Пример #1
0
class StreamlinesPanel(bpy.types.Panel):
    """
    Panel containing operators to position neuron morphology around
    DBS electrode.
    """

    # Panel parameters
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_label = 'Track Positioning'
    bl_category = 'NeuroMorphoVis'
    bl_options = {'DEFAULT_CLOSED'}

    # --------------------------------------------------------------------------
    # Properties for UI state

    # Streamlines file
    debug_tck_file = '/home/luye/Documents/mri_data/Waxholm_rat_brain_atlas/WHS_DTI_v1_ALS/S56280_track_filter-ROI-STN.tck'
    default_tck_file = debug_tck_file if DEBUG else 'Select File'

    bpy.types.Scene.StreamlinesFile = StringProperty(
        name="Streamlines File",
        description="Select streamlines file",
        default=default_tck_file,
        maxlen=2048,
        subtype='FILE_PATH')

    bpy.types.Scene.StreamlinesLabel = StringProperty(
        name="Label",
        description=
        "Enter label for streamlines in file (supported by pickle files)",
        default='')

    # ISSUE when loading numpy data saved using Python 2.x -> encoding must be 'latin1'
    bpy.types.Scene.StreamlinesEncoding = StringProperty(
        name="Encoding",
        description="Encoding of streamlines if using Python pickle file.",
        default='latin1')

    bpy.types.Scene.MaxLoadStreamlines = IntProperty(
        name="Max Streamlines",
        description="Maximum number of loaded streamlines",
        default=100,
        min=1,
        max=10000)

    bpy.types.Scene.MinStreamlineLength = FloatProperty(
        name="Min Length",
        description="Minimum streamline length (mm)",
        default=1.0,
        min=1.0,
        max=1e6)

    bpy.types.Scene.StreamlineUnitScale = FloatProperty(
        name="Scale",
        description="Streamline scale relative to microns (units/um)",
        default=1e3,
        min=1e-12,
        max=1e12)

    bpy.types.Scene.RoiName = StringProperty(
        name="ROI Name",
        description="Name for selected ROI volume",
        default='ROI-1')

    bpy.types.Scene.SampleSpacing = FloatProperty(
        name="Spacing",
        description="Spacing between streamline samples.",
        default=100.0)

    bpy.types.Scene.SubsampleFactor = IntProperty(
        name="Subsample factor", description="Subsample factor", default=1)

    # --------------------------------------------------------------------------
    # Panel overriden methods

    def draw(self, context):
        """
        Layout UI elements in the panel.

        :param context:
            Rendering context
        """
        layout = self.layout
        scene = context.scene

        # File Paths -----------------------------------------------------------
        layout.row().label(text='Import streamlines:',
                           icon='LIBRARY_DATA_DIRECT')

        # Select directory
        layout.row().prop(scene, 'StreamlinesFile')
        layout.row().prop(scene, 'StreamlinesLabel')
        layout.row().prop(scene, 'StreamlinesEncoding')

        # Import Options -------------------------------------------------------

        # labels for PRE and POST synaptic populations
        # row_pops_header = layout.row()
        # row_pops_header.column(align=True).label(text='Pre-syn.')
        # row_pops_header.column(align=True).label(text='Post-syn.')
        # row_pops_fields = layout.row()
        # row_pops_fields.column(align=True).prop(
        #     context.scene, 'ProjectionPrePopLabel', text='')
        # row_pops_fields.column(align=True).prop(
        #     context.scene, 'ProjectionPostPopLabel', text='')

        layout.row().prop(context.scene, 'MaxLoadStreamlines')

        layout.row().prop(context.scene, 'MinStreamlineLength')

        layout.row().prop(context.scene, 'StreamlineUnitScale')

        # Draw Streamlines
        layout.column(align=True).operator('import.streamlines', icon='IMPORT')

        # Edit -----------------------------------------------------------------
        layout.row().label(text='Edit streamlines:', icon='IPO')

        layout.column(align=True).operator(AttachAxonToNeuron.bl_idname,
                                           icon='SNAP_SURFACE')

        layout.row().prop(context.scene, 'SampleSpacing')
        layout.column(align=True).operator(SplineToPolyline.bl_idname,
                                           icon='ALIGN',
                                           text='Sample streamline')

        layout.row().prop(context.scene, 'SubsampleFactor')
        layout.column(align=True).operator(PolylineToSpline.bl_idname,
                                           icon='PARTICLE_POINT',
                                           text='Streamline to NURBS')

        # ROIs -----------------------------------------------------------------
        layout.row().label(text='ROIs:', icon='ALIASED')

        # ROI name
        layout.row().prop(context.scene, 'RoiName')

        layout.column(align=True).operator('add.roi', icon='IMPORT')
        layout.column(align=True).operator(ScaleROI.bl_idname,
                                           icon='MAN_SCALE')
        layout.column(align=True).operator('view3d.view_selected',
                                           icon='RESTRICT_VIEW_OFF')

        # Exporting ------------------------------------------------------------

        layout.row().label(text='Export Streamlines:',
                           icon='LIBRARY_DATA_DIRECT')

        layout.column(align=True).operator('axon.toggle_export', icon='EXPORT')
        layout.column(align=True).operator('export.streamlines',
                                           icon='SAVE_COPY')
Пример #2
0
class PREFERENCES_OT_keyconfig_import(Operator):
    """Import key configuration from a python script"""
    bl_idname = "preferences.keyconfig_import"
    bl_label = "Import Key Configuration..."

    filepath: StringProperty(
        subtype='FILE_PATH',
        default="keymap.py",
    )
    filter_folder: BoolProperty(
        name="Filter folders",
        default=True,
        options={'HIDDEN'},
    )
    filter_text: BoolProperty(
        name="Filter text",
        default=True,
        options={'HIDDEN'},
    )
    filter_python: BoolProperty(
        name="Filter python",
        default=True,
        options={'HIDDEN'},
    )
    keep_original: BoolProperty(
        name="Keep original",
        description="Keep original file after copying to configuration folder",
        default=True,
    )

    def execute(self, _context):
        import os
        from os.path import basename
        import shutil

        if not self.filepath:
            self.report({'ERROR'}, "Filepath not set")
            return {'CANCELLED'}

        config_name = basename(self.filepath)

        path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
        path = os.path.join(path, config_name)

        try:
            if self.keep_original:
                shutil.copy(self.filepath, path)
            else:
                shutil.move(self.filepath, path)
        except Exception as ex:
            self.report({'ERROR'}, "Installing keymap failed: %s" % ex)
            return {'CANCELLED'}

        # sneaky way to check we're actually running the code.
        if bpy.utils.keyconfig_set(path, report=self.report):
            return {'FINISHED'}
        else:
            return {'CANCELLED'}

    def invoke(self, context, _event):
        wm = context.window_manager
        wm.fileselect_add(self)
        return {'RUNNING_MODAL'}
Пример #3
0
class PREFERENCES_OT_app_template_install(Operator):
    """Install an application-template"""
    bl_idname = "preferences.app_template_install"
    bl_label = "Install Template from File..."

    overwrite: BoolProperty(
        name="Overwrite",
        description="Remove existing template with the same ID",
        default=True,
    )

    filepath: StringProperty(
        subtype='FILE_PATH',
    )
    filter_folder: BoolProperty(
        name="Filter folders",
        default=True,
        options={'HIDDEN'},
    )
    filter_glob: StringProperty(
        default="*.zip",
        options={'HIDDEN'},
    )

    def execute(self, _context):
        import traceback
        import zipfile
        import os

        filepath = self.filepath

        path_app_templates = bpy.utils.user_resource(
            'SCRIPTS', os.path.join("startup", "bl_app_templates_user"),
            create=True,
        )

        if not path_app_templates:
            self.report({'ERROR'}, "Failed to get add-ons path")
            return {'CANCELLED'}

        if not os.path.isdir(path_app_templates):
            try:
                os.makedirs(path_app_templates, exist_ok=True)
            except:
                traceback.print_exc()

        app_templates_old = set(os.listdir(path_app_templates))

        # check to see if the file is in compressed format (.zip)
        if zipfile.is_zipfile(filepath):
            try:
                file_to_extract = zipfile.ZipFile(filepath, 'r')
            except:
                traceback.print_exc()
                return {'CANCELLED'}

            if self.overwrite:
                for f in file_to_extract.namelist():
                    module_filesystem_remove(path_app_templates, f)
            else:
                for f in file_to_extract.namelist():
                    path_dest = os.path.join(path_app_templates, os.path.basename(f))
                    if os.path.exists(path_dest):
                        self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
                        return {'CANCELLED'}

            try:  # extract the file to "bl_app_templates_user"
                file_to_extract.extractall(path_app_templates)
            except:
                traceback.print_exc()
                return {'CANCELLED'}

        else:
            # Only support installing zipfiles
            self.report({'WARNING'}, "Expected a zip-file %r\n" % filepath)
            return {'CANCELLED'}

        app_templates_new = set(os.listdir(path_app_templates)) - app_templates_old

        # in case a new module path was created to install this addon.
        bpy.utils.refresh_script_paths()

        # print message
        msg = (
            tip_("Template Installed (%s) from %r into %r") %
            (", ".join(sorted(app_templates_new)), filepath, path_app_templates)
        )
        print(msg)
        self.report({'INFO'}, msg)

        return {'FINISHED'}

    def invoke(self, context, _event):
        wm = context.window_manager
        wm.fileselect_add(self)
        return {'RUNNING_MODAL'}
Пример #4
0
class SvPresetProps(bpy.types.Operator):
    """
    Edit preset properties
    """

    bl_idname = "node.sv_preset_props"
    bl_label = "Preset properties"
    bl_options = {'INTERNAL'}

    old_name: StringProperty(name="Old name", description="Preset name")
    new_name: StringProperty(name="Name", description="New preset name")

    description: StringProperty(name="Description",
                                description="Preset description")
    author: StringProperty(name="Author", description="Preset author name")
    license: StringProperty(name="License",
                            description="Preset license (short name)",
                            default="CC-BY-SA")

    def draw(self, context):
        layout = self.layout
        layout.prop(self, "new_name")
        layout.prop(self, "description")
        layout.prop(self, "author")
        layout.prop(self, "license")

    def execute(self, context):
        if not self.old_name:
            msg = "Old preset name is not specified"
            error(msg)
            self.report({'ERROR'}, msg)
            return {'CANCELLED'}

        if not self.new_name:
            msg = "New preset name is not specified"
            error(msg)
            self.report({'ERROR'}, msg)
            return {'CANCELLED'}

        preset = SvPreset(name=self.old_name)
        preset.meta['description'] = self.description
        preset.meta['author'] = self.author
        preset.meta['license'] = self.license
        preset.save()

        if self.new_name != self.old_name:
            old_path = get_preset_path(self.old_name)
            new_path = get_preset_path(self.new_name)

            if os.path.exists(new_path):
                msg = "Preset named `{}' already exists. Refusing to rewrite existing preset.".format(
                    self.new_name)
                error(msg)
                self.report({'ERROR'}, msg)
                return {'CANCELLED'}

            os.rename(old_path, new_path)
            preset.name = self.new_name
            info("Renamed `%s' to `%s'", old_path, new_path)
            self.report({'INFO'},
                        "Renamed `{}' to `{}'".format(self.old_name,
                                                      self.new_name))

        bpy.utils.unregister_class(preset_add_operators[self.old_name])
        del preset_add_operators[self.old_name]
        preset.make_add_operator()

        return {'FINISHED'}

    def invoke(self, context, event):
        wm = context.window_manager
        self.new_name = self.old_name
        preset = SvPreset(name=self.old_name)
        self.description = preset.meta.get('description', "")
        self.author = preset.meta.get('author', "")
        self.license = preset.meta.get('license', "CC-BY-SA")
        return wm.invoke_props_dialog(self)
Пример #5
0
class ImportOWMDL(bpy.types.Operator, ImportHelper):
    bl_idname = 'import_mesh.overtools_model'
    bl_label = 'Import Overtools Model (owmdl)'
    bl_options = {'UNDO'}

    filename_ext = '.owmdl'
    filter_glob: StringProperty(
        default='*.owmdl',
        options={'HIDDEN'},
    )

    uvDisplX: IntProperty(
        name='X',
        description='Displace UV X axis',
        default=0,
    )

    uvDisplY: IntProperty(
        name='Y',
        description='Displace UV Y axis',
        default=0,
    )

    autoIk: BoolProperty(
        name='AutoIK',
        description='Set AutoIK',
        default=True,
    )

    importNormals: BoolProperty(
        name='Import Normals',
        description='Import Custom Normals',
        default=True,
    )

    importColor: BoolProperty(
        name='Import Color',
        description='Import Custom Colors',
        default=True,
    )

    importEmpties: BoolProperty(
        name='Import Hardpoints',
        description='Import Hardpoints (attachment points)',
        default=False,
    )

    importMaterial: BoolProperty(
        name='Import Material',
        description='Import Referenced OWMAT',
        default=True,
    )

    importSkeleton: BoolProperty(
        name='Import Skeleton',
        description='Import Bones',
        default=True,
    )

    def menu_func(self, context):
        self.layout.operator_context = 'INVOKE_DEFAULT'
        self.layout.operator(ImportOWMDL.bl_idname,
                             text='Text Export Operator')

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        settings = owm_types.OWSettings(self.filepath, self.uvDisplX,
                                        self.uvDisplY, self.autoIk,
                                        self.importNormals, self.importEmpties,
                                        self.importMaterial,
                                        self.importSkeleton, self.importColor)
        owm_types.update_data()
        t = datetime.now()
        bpyhelper.LOCK_UPDATE = False
        try:
            import_owmdl.read(settings)
        except KeyboardInterrupt:
            bpyhelper.LOCK_UPDATE = False
        print('Done. SMPTE: %s' % (smpte_from_seconds(datetime.now() - t)))
        return {'FINISHED'}

    def draw(self, context):
        layout = self.layout

        col = layout.column(align=True)
        col.label(text='Mesh')
        col.prop(self, 'importNormals')
        col.prop(self, 'importEmpties')
        col.prop(self, 'importColor')
        col.prop(self, 'importMaterial')
        sub = col.row()
        sub.label(text='UV')
        sub.prop(self, 'uvDisplX')
        sub.prop(self, 'uvDisplY')

        col = layout.column(align=True)
        col.label(text='Armature')
        col.prop(self, 'importSkeleton')
        sub = col.row()
        sub.prop(self, 'autoIk')
        sub.enabled = self.importSkeleton
Пример #6
0
class ImportGLTF2(Operator, ImportHelper):
    """Load a glTF 2.0 file"""
    bl_idname = 'import_scene.gltf'
    bl_label = 'Import glTF 2.0'

    filter_glob: StringProperty(default="*.glb;*.gltf", options={'HIDDEN'})

    files: CollectionProperty(
        name="File Path",
        type=bpy.types.OperatorFileListElement,
    )

    loglevel: IntProperty(name='Log Level', description="Log Level")

    import_pack_images: BoolProperty(
        name='Pack images',
        description='Pack all images into .blend file',
        default=True)

    import_shading: EnumProperty(
        name="Shading",
        items=(("NORMALS", "Use Normal Data", ""),
               ("FLAT", "Flat Shading", ""), ("SMOOTH", "Smooth Shading", "")),
        description="How normals are computed during import",
        default="NORMALS")

    def draw(self, context):
        layout = self.layout

        layout.prop(self, 'import_pack_images')
        layout.prop(self, 'import_shading')

    def execute(self, context):
        return self.import_gltf2(context)

    def import_gltf2(self, context):
        import os

        self.set_debug_log()
        import_settings = self.as_keywords()

        if self.files:
            # Multiple file import
            ret = {'CANCELLED'}
            dirname = os.path.dirname(self.filepath)
            for file in self.files:
                path = os.path.join(dirname, file.name)
                if self.unit_import(path, import_settings) == {'FINISHED'}:
                    ret = {'FINISHED'}
            return ret
        else:
            # Single file import
            return self.unit_import(self.filepath, import_settings)

    def unit_import(self, filename, import_settings):
        import time
        from .io.imp.gltf2_io_gltf import glTFImporter
        from .blender.imp.gltf2_blender_gltf import BlenderGlTF

        self.gltf_importer = glTFImporter(filename, import_settings)
        success, txt = self.gltf_importer.read()
        if not success:
            self.report({'ERROR'}, txt)
            return {'CANCELLED'}
        success, txt = self.gltf_importer.checks()
        if not success:
            self.report({'ERROR'}, txt)
            return {'CANCELLED'}
        self.gltf_importer.log.critical(
            "Data are loaded, start creating Blender stuff")
        start_time = time.time()
        BlenderGlTF.create(self.gltf_importer)
        elapsed_s = "{:.2f}s".format(time.time() - start_time)
        self.gltf_importer.log.critical("glTF import finished in " + elapsed_s)
        self.gltf_importer.log.removeHandler(self.gltf_importer.log_handler)

        return {'FINISHED'}

    def set_debug_log(self):
        import logging
        if bpy.app.debug_value == 0:
            self.loglevel = logging.CRITICAL
        elif bpy.app.debug_value == 1:
            self.loglevel = logging.ERROR
        elif bpy.app.debug_value == 2:
            self.loglevel = logging.WARNING
        elif bpy.app.debug_value == 3:
            self.loglevel = logging.INFO
        else:
            self.loglevel = logging.NOTSET
Пример #7
0
class SunPosProperties(PropertyGroup):
    usage_mode: EnumProperty(
        name="Usage mode",
        description="Operate in normal mode or environment texture mode",
        items=(
            ('NORMAL', "Normal", ""),
            ('HDR', "Sun + HDR texture", ""),
        ),
        default='NORMAL',
        update=sun_update)

    use_daylight_savings: BoolProperty(
        name="Daylight savings",
        description="Daylight savings time adds 1 hour to standard time",
        default=False,
        update=sun_update)

    use_refraction: BoolProperty(
        name="Use refraction",
        description="Show apparent sun position due to refraction",
        default=True,
        update=sun_update)

    show_north: BoolProperty(name="Show North",
                             description="Draw line pointing north",
                             default=False,
                             update=north_update)

    north_offset: FloatProperty(
        name="North Offset",
        description="Rotate the scene to choose North direction",
        unit="ROTATION",
        soft_min=-pi,
        soft_max=pi,
        step=10.0,
        default=0.0,
        update=sun_update)

    latitude: FloatProperty(name="Latitude",
                            description="Latitude: (+) Northern (-) Southern",
                            soft_min=-90.0,
                            soft_max=90.0,
                            step=5,
                            precision=3,
                            default=0.0,
                            update=sun_update)

    longitude: FloatProperty(
        name="Longitude",
        description="Longitude: (-) West of Greenwich (+) East of Greenwich",
        soft_min=-180.0,
        soft_max=180.0,
        step=5,
        precision=3,
        default=0.0,
        update=sun_update)

    co_parser: StringProperty(
        name="Enter coordinates",
        description="Enter coordinates from an online map",
        update=parse_coordinates)

    month: IntProperty(name="Month",
                       min=1,
                       max=12,
                       default=TODAY.month,
                       update=sun_update)

    day: IntProperty(name="Day",
                     min=1,
                     max=31,
                     default=TODAY.day,
                     update=sun_update)

    year: IntProperty(name="Year",
                      min=1,
                      max=4000,
                      default=TODAY.year,
                      update=sun_update)

    use_day_of_year: BoolProperty(
        description="Use a single value for day of year",
        name="Use day of year",
        default=False,
        update=sun_update)

    day_of_year: IntProperty(name="Day of year",
                             min=1,
                             max=366,
                             default=1,
                             update=sun_update)

    UTC_zone: FloatProperty(
        name="UTC zone",
        description="Time zone: Difference from Greenwich, England in hours",
        precision=1,
        min=-14.0,
        max=13,
        step=50,
        default=0.0,
        update=sun_update)

    time: FloatProperty(name="Time",
                        description="Time of the day",
                        precision=4,
                        soft_min=0.0,
                        soft_max=23.9999,
                        step=1.0,
                        default=12.0,
                        update=sun_update)

    sun_distance: FloatProperty(name="Distance",
                                description="Distance to sun from origin",
                                unit="LENGTH",
                                min=0.0,
                                soft_max=3000.0,
                                step=10.0,
                                default=50.0,
                                update=sun_update)

    sun_object: PointerProperty(name="Sun Object",
                                type=bpy.types.Object,
                                description="Sun object to set in the scene",
                                poll=lambda self, obj: obj.type == 'LIGHT',
                                update=sun_update)

    object_collection: PointerProperty(
        name="Collection",
        type=bpy.types.Collection,
        description="Collection of objects used to visualize sun motion",
        update=sun_update)

    object_collection_type: EnumProperty(
        name="Display type",
        description="Show object group as sun motion",
        items=(
            ('ANALEMMA', "Analemma", ""),
            ('DIURNAL', "Diurnal", ""),
        ),
        default='ANALEMMA',
        update=sun_update)

    sky_texture: StringProperty(name="Sky Texture",
                                default="Sky Texture",
                                description="Name of sky texture to be used",
                                update=sun_update)

    hdr_texture: StringProperty(
        default="Environment Texture",
        name="Environment Texture",
        description="Name of texture to use. World nodes must be enabled "
        "and color set to Environment Texture",
        update=sun_update)

    hdr_azimuth: FloatProperty(
        name="Rotation",
        description="Rotation angle of sun and environment texture",
        unit="ROTATION",
        step=10.0,
        default=0.0,
        precision=3,
        update=sun_update)

    hdr_elevation: FloatProperty(name="Elevation",
                                 description="Elevation angle of sun",
                                 unit="ROTATION",
                                 step=10.0,
                                 default=0.0,
                                 precision=3,
                                 update=sun_update)

    bind_to_sun: BoolProperty(
        description="If true, Environment texture moves with sun",
        default=False,
        update=sun_update)

    time_spread: FloatProperty(
        name="Time Spread",
        description="Time period in which to spread object collection",
        precision=4,
        soft_min=1.0,
        soft_max=24.0,
        step=1.0,
        default=23.0,
        update=sun_update)
Пример #8
0
class OctaneThinLensCameraGroupPhysicalCameraParameters(
        OctaneGroupTitleSocket):
    bl_idname = "OctaneThinLensCameraGroupPhysicalCameraParameters"
    bl_label = "[OctaneGroupTitle]Physical Camera parameters"
    octane_group_sockets: StringProperty(
        name="Group Sockets", default="Sensor width;Focal length;F-stop;")
Пример #9
0
class OctaneThinLensCameraGroupClipping(OctaneGroupTitleSocket):
    bl_idname = "OctaneThinLensCameraGroupClipping"
    bl_label = "[OctaneGroupTitle]Clipping"
    octane_group_sockets: StringProperty(
        name="Group Sockets", default="Near clip depth;Far clip depth;")
Пример #10
0
class SvFormulaNodeMk3(bpy.types.Node, SverchCustomTreeNode):
    """
    Triggers: Formula
    Tooltip: Calculate by custom formula.
    """
    bl_idname = 'SvFormulaNodeMk3'
    bl_label = 'Formula'
    bl_icon = 'OUTLINER_OB_EMPTY'
    sv_icon = 'SV_FORMULA'

    @throttled
    def on_update(self, context):
        self.adjust_sockets()

    @throttled
    def on_update_dims(self, context):
        if self.dimensions < 4:
            self.formula4 = ""
        if self.dimensions < 3:
            self.formula3 = ""
        if self.dimensions < 2:
            self.formula2 = ""

        self.adjust_sockets()

    dimensions: IntProperty(name="Dimensions",
                            default=1,
                            min=1,
                            max=4,
                            update=on_update_dims)

    formula1: StringProperty(default="x+y", update=on_update)
    formula2: StringProperty(update=on_update)
    formula3: StringProperty(update=on_update)
    formula4: StringProperty(update=on_update)

    separate: BoolProperty(name="Separate", default=False, update=updateNode)
    wrap: BoolProperty(name="Wrap", default=False, update=updateNode)

    def formulas(self):
        return [self.formula1, self.formula2, self.formula3, self.formula4]

    def formula(self, k):
        return self.formulas()[k]

    def draw_buttons(self, context, layout):
        layout.prop(self, "formula1", text="")
        if self.dimensions > 1:
            layout.prop(self, "formula2", text="")
        if self.dimensions > 2:
            layout.prop(self, "formula3", text="")
        if self.dimensions > 3:
            layout.prop(self, "formula4", text="")
        row = layout.row()
        row.prop(self, "separate")
        row.prop(self, "wrap")

    def draw_buttons_ext(self, context, layout):
        layout.prop(self, "dimensions")
        self.draw_buttons(context, layout)

    def sv_init(self, context):
        self.inputs.new('SvStringsSocket', "x")

        self.outputs.new('SvStringsSocket', "Result")

    def get_variables(self):
        variables = set()

        for formula in self.formulas():
            vs = get_variables(formula)
            variables.update(vs)

        return list(sorted(list(variables)))

    def adjust_sockets(self):
        variables = self.get_variables()
        #self.debug("adjust_sockets:" + str(variables))
        #self.debug("inputs:" + str(self.inputs.keys()))
        for key in self.inputs.keys():
            if key not in variables:
                self.debug("Input {} not in variables {}, remove it".format(
                    key, str(variables)))
                self.inputs.remove(self.inputs[key])
        for v in variables:
            if v not in self.inputs:
                self.debug("Variable {} not in inputs {}, add it".format(
                    v, str(self.inputs.keys())))
                self.inputs.new('SvStringsSocket', v)

    def update(self):
        '''
        update analyzes the state of the node and returns if the criteria to start processing
        are not met.
        '''

        if not any(len(formula) for formula in self.formulas()):
            return

        self.adjust_sockets()

    def get_input(self):
        variables = self.get_variables()
        inputs = {}

        for var in variables:
            if var in self.inputs and self.inputs[var].is_linked:
                inputs[var] = self.inputs[var].sv_get()


#         n_max = max(len(inputs[var]) for var in inputs)
#         result = []
#         for i in range(n_max):
#             item = defaultdict(list)
#             for var in inputs:
#                 value = inputs[var]
#                 if i < len(value):
#                     item[var].append(value[i])
#                 else:
#                     item[var].append(value[-1])
#             result.append(item)

        return inputs

    def migrate_from(self, old_node):
        if old_node.bl_idname == 'Formula2Node':
            formula = old_node.formula
            # Older formula node allowed only fixed set of
            # variables, with names "x", "n[0]" .. "n[100]".
            # Other names could not be considered valid.
            k = -1
            for socket in old_node.inputs:
                name = socket.name
                if k == -1:  # First socket name was "x"
                    new_name = name
                else:  # Other names was "n[k]", which is syntactically not
                    # a valid python variable name.
                    # So we replace all occurences of "n[0]" in formula
                    # with "n0", and so on.
                    new_name = "n" + str(k)

                logging.info("Replacing %s with %s", name, new_name)
                formula = formula.replace(name, new_name)
                k += 1

            self.formula1 = formula
            self.wrap = True

    def process(self):

        if not self.outputs[0].is_linked:
            return

        var_names = self.get_variables()
        inputs = self.get_input()

        results = []

        if var_names:
            input_values = [inputs.get(name, [[0]]) for name in var_names]
            parameters = match_long_repeat(input_values)
        else:
            parameters = [[[]]]
        for objects in zip(*parameters):
            object_results = []
            for values in zip_long_repeat(*objects):
                variables = dict(zip(var_names, values))
                vector = []
                for formula in self.formulas():
                    if formula:
                        value = safe_eval(formula, variables)
                        vector.append(value)
                if self.separate:
                    object_results.append(vector)
                else:
                    object_results.extend(vector)
            results.append(object_results)

        if self.wrap:
            results = [results]

        self.outputs['Result'].sv_set(results)
Пример #11
0
class LuxCoreErrorLog(bpy.types.PropertyGroup):
    errors = StringProperty(name="")

    def set(self, error):
        self.errors = str(error)
Пример #12
0
class SplashExportNodeTree(Operator):
    """Exports Splash whole configuration, project (only geometry and image data), or 3D models"""
    bl_idname = "splash.export_node_tree"
    bl_label = "Exports the node tree"

    filepath = bpy.props.StringProperty(subtype='FILE_PATH')
    filter_glob = bpy.props.StringProperty(
        default="*.json",
        options={'HIDDEN'},
    )

    node_name = StringProperty(name='Node name',
                               description='Name of the calling node',
                               default='')
    export_project = BoolProperty(
        name='export_project',
        description=
        'If True, the tree will contain only meshes and images data',
        default=False)
    export_only_nodes = BoolProperty(
        name='export_only_nodes',
        description=
        'If True, the tree is not exported, but nodes are evaluated anyway',
        default=False)

    world_node = None
    scene_order = []
    scene_lists = {}
    node_links = {}
    project_accepted_types = [
        'SplashImageNodeType', 'SplashMeshNodeType', 'SplashObjectNodeType'
    ]

    def execute(self, context):
        objectIsEdited = bpy.context.edit_object is not None
        if objectIsEdited is True:
            bpy.ops.object.editmode_toggle()

        self.scene_order.clear()
        self.scene_lists.clear()
        self.node_links.clear()

        for nodeTree in bpy.data.node_groups:
            nodeIndex = nodeTree.nodes.find(self.node_name)
            if nodeIndex != -1:
                node = nodeTree.nodes[nodeIndex]
                break

        self.world_node = node

        connectedScenes = [
            socket.links[0].from_node for socket in node.inputs
            if socket.is_linked
        ]
        for scene in connectedScenes:
            scene_list = {}
            node_links = []
            tree_valid, tree_error = self.parseTree(scene, scene_list,
                                                    node_links,
                                                    self.export_project)
            if not tree_valid:
                message = "Splash tree exporting error: " + tree_error
                print(message)
                return {'CANCELLED'}
            print(tree_error)

            self.scene_order.append(scene.name)
            self.scene_lists[scene.name] = scene_list
            self.node_links[scene.name] = node_links

        # If we only wanted to export meshes, the previous loop did the job
        if self.export_only_nodes is True:
            for scene in self.scene_lists:
                for node in self.scene_lists[scene]:
                    self.scene_lists[scene][node].exportProperties(
                        self.filepath)

        # Merge scenes info if exporting a project
        if self.export_project and len(self.scene_order) > 0:
            masterSceneName = self.scene_order[0]
            for sceneId in range(1, len(self.scene_order)):
                sceneName = self.scene_order[sceneId]

                for node in self.scene_lists[sceneName]:
                    if node not in self.scene_lists[masterSceneName]:
                        self.scene_lists[masterSceneName][
                            node] = self.scene_lists[sceneName][node]
                for link in self.node_links[sceneName]:
                    self.node_links[masterSceneName].append(link)

            self.scene_order = [self.scene_order[0]]
            self.scene_lists = {
                masterSceneName: self.scene_lists[masterSceneName]
            }

        self.export(self.export_project)
        return {'FINISHED'}

    def parseTree(self, node, scene_list, node_links, export_project=False):
        node_valid, node_error = node.validate()
        if not node_valid:
            return node_valid, node_error

        if not export_project or node.bl_idname in self.project_accepted_types:
            scene_list[node.name] = node

        connectedNodes = [
            socket.links[0].from_node for socket in node.inputs
            if socket.is_linked
        ]
        for connectedNode in connectedNodes:
            newLink = [connectedNode.name, node.name]
            if newLink not in node_links:
                node_links.append([connectedNode.name, node.name])
            node_valid, node_error = self.parseTree(connectedNode, scene_list,
                                                    node_links, export_project)
            if not node_valid:
                return node_valid, node_error

        return True, "Splash tree parsing successful"

    def export(self, export_project=False):
        file = open(self.filepath, "w", encoding="utf8", newline="\n")
        fw = file.write

        worldArgs = self.world_node.exportProperties(self.filepath)
        fw("// Splash configuration file\n"
           "// Exported with Blender Splash add-on\n"
           "{\n")

        if export_project:
            fw("    \"description\" : \"splashProject\",\n")
        else:
            fw("    \"description\" : \"splashConfiguration\",\n")
            # World informations
            fw("    \"world\" : {\n"
               "        \"framerate\" : %i\n"
               "    },\n" % (worldArgs['framerate']))

            # Scenes list
            fw("    \"scenes\" : [\n")
            sceneIndex = 0
            for scene in self.scene_order:
                # Find the Scene nodes
                for node in self.scene_lists[scene]:
                    if self.scene_lists[scene][
                            node].bl_idname == "SplashSceneNodeType":
                        args = self.scene_lists[scene][node].exportProperties(
                            self.filepath)
                        fw("        {\n")
                        valueIndex = 0
                        for values in args:
                            fw("            \"%s\" : %s" %
                               (values, args[values]))

                            if valueIndex < len(args) - 1:
                                fw(",\n")
                            else:
                                fw("\n")
                            valueIndex = valueIndex + 1
                        fw("        }")

                        if sceneIndex < len(self.scene_lists) - 1:
                            fw(",\n")
                        else:
                            fw("\n")
                        sceneIndex = sceneIndex + 1
            fw("    ],\n")

        # Scenes information
        sceneIndex = 0
        for scene in self.scene_order:
            if not export_project:
                fw("    \"%s\" : {\n" % scene)

            for node in self.scene_lists[scene]:
                if self.scene_lists[scene][
                        node].bl_idname != "SplashSceneNodeType":
                    args = self.scene_lists[scene][node].exportProperties(
                        self.filepath)
                    fw("        \"%s\" : {\n" % node)
                    valueIndex = 0
                    for values in args:
                        fw("            \"%s\" : %s" % (values, args[values]))

                        if valueIndex < len(args) - 1:
                            fw(",\n")
                        else:
                            fw("\n")
                        valueIndex = valueIndex + 1
                    fw("        },\n")

            # Links
            fw("        \"links\" : [\n")
            linkIndex = 0
            for link in self.node_links[scene]:
                fw("            [\"%s\", \"%s\"]" % (link[0], link[1]))
                if linkIndex < len(self.node_links[scene]) - 1:
                    fw(",\n")
                else:
                    fw("\n")
                linkIndex = linkIndex + 1
            fw("        ]\n")

            if sceneIndex < len(self.scene_lists) - 1:
                fw("    },\n")
            else:
                fw("    }\n")
            sceneIndex = sceneIndex + 1

        if not export_project:
            fw("}")

    def invoke(self, context, event):
        self.filepath = os.path.splitext(bpy.data.filepath)[0] + ".json"
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}
Пример #13
0
class OPS_OT_EditAttribute(Operator):
    bl_idname = 'nextr_debug.edit_attribute'
    bl_label = 'Edit attribute'
    bl_description = 'Edit attribute' 

    path : StringProperty(name="Path", description="RNA path of the attribute")
    panel_name : StringProperty()
    panels : EnumProperty(name="Panel", items=[('outfits','Outfits','Outfits panel',0),('body','Body','Body Panel',1),('rig','Rig Layers','Rig Layers Panel',2)])
    name : StringProperty(default='Default Value', name="Attribute's Name")
    attribute : {}
    visibility_value: IntProperty(name="Visibility Value", description="On which value of the variable show the attribute in the UI")
    visibility_variable : StringProperty(name='Varibale Name')

    def execute(self, context):
        o = get_edited_object(context)
        a = get_attribute_by_path(context,self.panel_name, self.path)
        if a:
            if 'visibility' in a:
                a['visibility']['variable'] = self.visibility_variable
                a['visibility']['value'] = self.visibility_value
            else:
                a['visibility'] = {'variable': self.visibility_variable, 'value': self.visibility_value}
            a['name'] = self.name
            a['path'] = self.path
            
            new_attributes = []
            for attribute in o.data['nextrrig_attributes'][self.panel_name]:
                if attribute['path'] == self.path:
                    new_attributes.append(a)
                else:
                    new_attributes.append(attribute)
            o.data['nextrrig_attributes'][self.panel_name] = new_attributes
        return {'FINISHED'}

    def invoke(self, context, event):
        self.attribute = get_attribute_by_path(context, self.panel_name, self.path)        
        if not self.attribute:
            return {"CANCELED"}

        # might work on this some day, now you need to the name manually
        # items = [('none', 'Always Visible', 'Attribute is going to be always visible',0)]
        # # self.variables_enum : EnumProperty(name="Variables", items=items)
        # o = get_edited_object(context)
        # for key,prop in enumerate(o.data['nextrrig_properties']):
        #     name = prop
        #     try:
        #         name = getattr(bpy.types.Armature.nextrrig_properties[1]['type'],prop)[1]['name']
        #     except:
        #         continue
        #     items.append((prop, name, 'Variable used for visibility', key+1))
        if 'visibility' in self.attribute:
            self.visibility_variable = self.attribute['visibility']['variable']
            self.visibility_value = self.attribute['visibility']['value']
        else:
            self.visibility_value = 0
            self.visibility_variable = ""
        self.panels = self.panel_name
        self.name = self.attribute['name'] if self.attribute['name'] else "Default Value" 

        return context.window_manager.invoke_props_dialog(self, width=750)

    def draw(self, context):
        box = self.layout.box()
         
        box.label(text=self.name, icon="PREFERENCES")
        box.prop(self, "name", emboss=True)
        box.prop(self, "path", text="Path", icon="RNA")
        box.prop(self, 'panels')
        box_visibility = box.box()
        box_visibility.label(text="Visibility")
        box_visibility.prop(self, "visibility_variable")
        box_visibility.prop(self, 'visibility_value')
        if 'synced' in self.attribute:
            if self.attribute['synced']:
                box_synced = box.box()
                box_synced.label(text="Synced attributes")
                for synced in self.attribute['synced']:
                    row = box_synced.row(align=True)
                    row.label(text=synced)
                    op = row.operator(OPS_OT_RemoveSyncedAttribute.bl_idname, text="", icon="TRASH")
                    op.path = self.path
                    op.panel_name = self.panel_name
                    op.attribute_path = synced
Пример #14
0
    class SceneCoat3D(PropertyGroup):
        defaultfolder = StringProperty(
            name="FilePath",
            subtype="DIR_PATH",
        )
        cursor_loc = FloatVectorProperty(name="Cursor_loc",
                                         description="location")
        exchangedir = StringProperty(name="FilePath", subtype="DIR_PATH")
        exchangefolder = StringProperty(name="FilePath", subtype="DIR_PATH")
        wasactive = StringProperty(name="Pass active object", )
        import_box = BoolProperty(name="Import window",
                                  description="Allows to skip import dialog",
                                  default=True)
        exchange_found = BoolProperty(
            name="Exchange Found",
            description="Alert if Exchange folder is not found",
            default=True)
        export_box = BoolProperty(name="Export window",
                                  description="Allows to skip export dialog",
                                  default=True)
        export_color = BoolProperty(name="Export color",
                                    description="Export color texture",
                                    default=True)
        export_spec = BoolProperty(name="Export specular",
                                   description="Export specular texture",
                                   default=True)
        export_normal = BoolProperty(name="Export Normal",
                                     description="Export normal texture",
                                     default=True)
        export_disp = BoolProperty(name="Export Displacement",
                                   description="Export displacement texture",
                                   default=True)
        export_position = BoolProperty(name="Export Source Position",
                                       description="Export source position",
                                       default=True)
        export_zero_layer = BoolProperty(
            name="Export from Layer 0",
            description="Export mesh from Layer 0",
            default=True)
        export_coarse = BoolProperty(name="Export Coarse",
                                     description="Export Coarse",
                                     default=True)
        exportfile = BoolProperty(name="No Import File",
                                  description="Add Modifiers and export",
                                  default=False)
        importmod = BoolProperty(name="Remove Modifiers",
                                 description="Import and add modifiers",
                                 default=False)
        exportmod = BoolProperty(name="Modifiers",
                                 description="Export modifiers",
                                 default=False)
        export_pos = BoolProperty(name="Remember Position",
                                  description="Remember position",
                                  default=True)
        importtextures = BoolProperty(name="Bring Textures",
                                      description="Import Textures",
                                      default=True)
        importlevel = BoolProperty(name="Multires. Level",
                                   description="Bring Specific Multires Level",
                                   default=False)
        exportover = BoolProperty(name="Export Obj",
                                  description="Import Textures",
                                  default=False)
        importmesh = BoolProperty(name="Mesh",
                                  description="Import Mesh",
                                  default=True)

        # copy location
        cursor = FloatVectorProperty(name="Cursor",
                                     description="Location",
                                     subtype="XYZ",
                                     default=(0.0, 0.0, 0.0))
        loca = FloatVectorProperty(name="location",
                                   description="Location",
                                   subtype="XYZ",
                                   default=(0.0, 0.0, 0.0))
        rota = FloatVectorProperty(name="location",
                                   description="Location",
                                   subtype="EULER",
                                   default=(0.0, 0.0, 0.0))
        scal = FloatVectorProperty(name="location",
                                   description="Location",
                                   subtype="XYZ",
                                   default=(0.0, 0.0, 0.0))
        dime = FloatVectorProperty(name="dimension",
                                   description="Dimension",
                                   subtype="XYZ",
                                   default=(0.0, 0.0, 0.0))
        type = EnumProperty(name="Export Type",
                            description="Different Export Types",
                            items=(
                                ("ppp", "Per-Pixel Painting", ""),
                                ("mv", "Microvertex Painting", ""),
                                ("ptex", "Ptex Painting", ""),
                                ("uv", "UV-Mapping", ""),
                                ("ref", "Reference Mesh", ""),
                                ("retopo", "Retopo mesh as new layer", ""),
                                ("vox", "Mesh As Voxel Object", ""),
                                ("alpha", "Mesh As New Pen Alpha", ""),
                                ("prim", "Mesh As Voxel Primitive", ""),
                                ("curv", "Mesh As a Curve Profile", ""),
                                ("autopo", "Mesh For Auto-retopology", ""),
                            ),
                            default="ppp")
class NODETREE_SOURCE_lib_items(PropertyGroup):

    name: StringProperty()
Пример #16
0
class OctaneThinLensCameraGroupPosition(OctaneGroupTitleSocket):
    bl_idname = "OctaneThinLensCameraGroupPosition"
    bl_label = "[OctaneGroupTitle]Position"
    octane_group_sockets: StringProperty(name="Group Sockets",
                                         default="Position;Target;Up-vector;")
Пример #17
0
class ExportGLTF2_Base:
    # TODO: refactor to avoid boilerplate

    def __init__(self):
        from io_scene_gltf2.io.exp import gltf2_io_draco_compression_extension
        self.is_draco_available = gltf2_io_draco_compression_extension.dll_exists(
        )

    bl_options = {'UNDO', 'PRESET'}

    export_format: EnumProperty(
        name='Format',
        items=
        (('GLB', 'glTF Binary (.glb)',
          'Exports a single file, with all data packed in binary form. '
          'Most efficient and portable, but more difficult to edit later'),
         ('GLTF_EMBEDDED', 'glTF Embedded (.gltf)',
          'Exports a single file, with all data packed in JSON. '
          'Less efficient than binary, but easier to edit later'),
         ('GLTF_SEPARATE', 'glTF Separate (.gltf + .bin + textures)',
          'Exports multiple files, with separate JSON, binary and texture data. '
          'Easiest to edit later')),
        description=(
            'Output format and embedding options. Binary is most efficient, '
            'but JSON (embedded or separate) may be easier to edit later'),
        default='GLB')

    ui_tab: EnumProperty(
        items=(('GENERAL', "General", "General settings"),
               ('MESHES', "Meshes", "Mesh settings"), ('OBJECTS', "Objects",
                                                       "Object settings"),
               ('ANIMATION', "Animation", "Animation settings")),
        name="ui_tab",
        description="Export setting categories",
    )

    export_copyright: StringProperty(
        name='Copyright',
        description='Legal rights and conditions for the model',
        default='')

    export_image_format: EnumProperty(
        name='Images',
        items=(
            ('AUTO', 'Automatic', 'Save PNGs as PNGs and JPEGs as JPEGs.\n'
             'If neither one, use PNG'),
            ('JPEG', 'JPEG Format (.jpg)',
             'Save images as JPEGs. (Images that need alpha are saved as PNGs though.)\n'
             'Be aware of a possible loss in quality'),
        ),
        description=
        ('Output format for images. PNG is lossless and generally preferred, but JPEG might be preferable for web '
         'applications due to the smaller file size'),
        default='AUTO')

    export_texture_dir: StringProperty(
        name='Textures',
        description=
        'Folder to place texture files in. Relative to the .gltf file',
        default='',
    )

    export_texcoords: BoolProperty(
        name='UVs',
        description='Export UVs (texture coordinates) with meshes',
        default=True)

    export_normals: BoolProperty(
        name='Normals',
        description='Export vertex normals with meshes',
        default=True)

    export_draco_mesh_compression_enable: BoolProperty(
        name='Draco mesh compression',
        description='Compress mesh using Draco',
        default=False)

    export_draco_mesh_compression_level: IntProperty(
        name='Compression level',
        description=
        'Compression level (0 = most speed, 6 = most compression, higher values currently not supported)',
        default=6,
        min=0,
        max=6)

    export_draco_position_quantization: IntProperty(
        name='Position quantization bits',
        description=
        'Quantization bits for position values (0 = no quantization)',
        default=14,
        min=0,
        max=30)

    export_draco_normal_quantization: IntProperty(
        name='Normal quantization bits',
        description='Quantization bits for normal values (0 = no quantization)',
        default=10,
        min=0,
        max=30)

    export_draco_texcoord_quantization: IntProperty(
        name='Texcoord quantization bits',
        description=
        'Quantization bits for texture coordinate values (0 = no quantization)',
        default=12,
        min=0,
        max=30)

    export_draco_generic_quantization: IntProperty(
        name='Generic quantization bits',
        description=
        'Quantization bits for generic coordinate values like weights or joints (0 = no quantization)',
        default=12,
        min=0,
        max=30)

    export_tangents: BoolProperty(
        name='Tangents',
        description='Export vertex tangents with meshes',
        default=False)

    export_materials: BoolProperty(name='Materials',
                                   description='Export materials',
                                   default=True)

    export_colors: BoolProperty(name='Vertex Colors',
                                description='Export vertex colors with meshes',
                                default=True)

    export_cameras: BoolProperty(name='Cameras',
                                 description='Export cameras',
                                 default=False)

    export_selected: BoolProperty(name='Selected Objects',
                                  description='Export selected objects only',
                                  default=False)

    export_extras: BoolProperty(
        name='Custom Properties',
        description='Export custom properties as glTF extras',
        default=False)

    export_yup: BoolProperty(name='+Y Up',
                             description='Export using glTF convention, +Y up',
                             default=True)

    export_apply: BoolProperty(
        name='Apply Modifiers',
        description='Apply modifiers (excluding Armatures) to mesh objects -'
        'WARNING: prevents exporting shape keys',
        default=False)

    export_animations: BoolProperty(
        name='Animations',
        description='Exports active actions and NLA tracks as glTF animations',
        default=True)

    export_frame_range: BoolProperty(
        name='Limit to Playback Range',
        description='Clips animations to selected playback range',
        default=True)

    export_frame_step: IntProperty(
        name='Sampling Rate',
        description='How often to evaluate animated values (in frames)',
        default=1,
        min=1,
        max=120)

    export_force_sampling: BoolProperty(
        name='Always Sample Animations',
        description='Apply sampling to all animations',
        default=True)

    export_nla_strips: BoolProperty(name='NLA Strips',
                                    description='Export NLA Strip animations',
                                    default=True)

    export_def_bones: BoolProperty(
        name='Export Deformation bones only',
        description=
        'Export Deformation bones only (and needed bones for hierarchy)',
        default=False)

    export_current_frame: BoolProperty(
        name='Use Current Frame',
        description='Export the scene in the current animation frame',
        default=False)

    export_skins: BoolProperty(name='Skinning',
                               description='Export skinning (armature) data',
                               default=True)

    export_all_influences: BoolProperty(
        name='Include All Bone Influences',
        description=
        'Allow >4 joint vertex influences. Models may appear incorrectly in many viewers',
        default=False)

    export_morph: BoolProperty(name='Shape Keys',
                               description='Export shape keys (morph targets)',
                               default=True)

    export_morph_normal: BoolProperty(
        name='Shape Key Normals',
        description='Export vertex normals with shape keys (morph targets)',
        default=True)

    export_morph_tangent: BoolProperty(
        name='Shape Key Tangents',
        description='Export vertex tangents with shape keys (morph targets)',
        default=False)

    export_lights: BoolProperty(
        name='Punctual Lights',
        description='Export directional, point, and spot lights. '
        'Uses "KHR_lights_punctual" glTF extension',
        default=False)

    export_displacement: BoolProperty(
        name='Displacement Textures (EXPERIMENTAL)',
        description='EXPERIMENTAL: Export displacement textures. '
        'Uses incomplete "KHR_materials_displacement" glTF extension',
        default=False)

    will_save_settings: BoolProperty(
        name='Remember Export Settings',
        description='Store glTF export settings in the Blender project',
        default=False)

    # Custom scene property for saving settings
    scene_key = "glTF2ExportSettings"

    #

    def invoke(self, context, event):
        settings = context.scene.get(self.scene_key)
        self.will_save_settings = False
        self.has_active_extenions = False
        if settings:
            try:
                for (k, v) in settings.items():
                    setattr(self, k, v)
                self.will_save_settings = True

            except (AttributeError, TypeError):
                self.report({
                    "ERROR"
                }, "Loading export settings failed. Removed corrupted settings"
                            )
                del context.scene[self.scene_key]

        import sys
        preferences = bpy.context.preferences
        for addon_name in preferences.addons.keys():
            try:
                if hasattr(sys.modules[addon_name],
                           'glTF2ExportUserExtension') or hasattr(
                               sys.modules[addon_name],
                               'glTF2ExportUserExtensions'):
                    extension_panel_unregister_functors.append(
                        sys.modules[addon_name].register_panel())
                    self.has_active_extenions = True
            except Exception:
                pass

        return ExportHelper.invoke(self, context, event)

    def save_settings(self, context):
        # find all export_ props
        all_props = self.properties
        export_props = {
            x: getattr(self, x)
            for x in dir(all_props)
            if x.startswith("export_") and all_props.get(x) is not None
        }

        context.scene[self.scene_key] = export_props

    def execute(self, context):
        import os
        import datetime
        from .blender.exp import gltf2_blender_export

        if self.will_save_settings:
            self.save_settings(context)

        if self.export_format == 'GLB':
            self.filename_ext = '.glb'
        else:
            self.filename_ext = '.gltf'

        # All custom export settings are stored in this container.
        export_settings = {}

        export_settings['timestamp'] = datetime.datetime.now()

        export_settings['gltf_filepath'] = bpy.path.ensure_ext(
            self.filepath, self.filename_ext)
        export_settings['gltf_filedirectory'] = os.path.dirname(
            export_settings['gltf_filepath']) + '/'
        export_settings['gltf_texturedirectory'] = os.path.join(
            export_settings['gltf_filedirectory'],
            self.export_texture_dir,
        )

        export_settings['gltf_format'] = self.export_format
        export_settings['gltf_image_format'] = self.export_image_format
        export_settings['gltf_copyright'] = self.export_copyright
        export_settings['gltf_texcoords'] = self.export_texcoords
        export_settings['gltf_normals'] = self.export_normals
        export_settings[
            'gltf_tangents'] = self.export_tangents and self.export_normals

        if self.is_draco_available:
            export_settings[
                'gltf_draco_mesh_compression'] = self.export_draco_mesh_compression_enable
            export_settings[
                'gltf_draco_mesh_compression_level'] = self.export_draco_mesh_compression_level
            export_settings[
                'gltf_draco_position_quantization'] = self.export_draco_position_quantization
            export_settings[
                'gltf_draco_normal_quantization'] = self.export_draco_normal_quantization
            export_settings[
                'gltf_draco_texcoord_quantization'] = self.export_draco_texcoord_quantization
            export_settings[
                'gltf_draco_generic_quantization'] = self.export_draco_generic_quantization
        else:
            export_settings['gltf_draco_mesh_compression'] = False

        export_settings['gltf_materials'] = self.export_materials
        export_settings['gltf_colors'] = self.export_colors
        export_settings['gltf_cameras'] = self.export_cameras
        export_settings['gltf_selected'] = self.export_selected
        export_settings['gltf_layers'] = True  # self.export_layers
        export_settings['gltf_extras'] = self.export_extras
        export_settings['gltf_yup'] = self.export_yup
        export_settings['gltf_apply'] = self.export_apply
        export_settings['gltf_current_frame'] = self.export_current_frame
        export_settings['gltf_animations'] = self.export_animations
        if self.export_animations:
            export_settings['gltf_frame_range'] = self.export_frame_range
            export_settings['gltf_force_sampling'] = self.export_force_sampling
            if self.export_force_sampling:
                export_settings['gltf_def_bones'] = self.export_def_bones
            else:
                export_settings['gltf_def_bones'] = False
            export_settings['gltf_nla_strips'] = self.export_nla_strips
        else:
            export_settings['gltf_frame_range'] = False
            export_settings['gltf_move_keyframes'] = False
            export_settings['gltf_force_sampling'] = False
            export_settings['gltf_def_bones'] = False
        export_settings['gltf_skins'] = self.export_skins
        if self.export_skins:
            export_settings[
                'gltf_all_vertex_influences'] = self.export_all_influences
        else:
            export_settings['gltf_all_vertex_influences'] = False
        export_settings['gltf_frame_step'] = self.export_frame_step
        export_settings['gltf_morph'] = self.export_morph
        if self.export_morph:
            export_settings['gltf_morph_normal'] = self.export_morph_normal
        else:
            export_settings['gltf_morph_normal'] = False
        if self.export_morph and self.export_morph_normal:
            export_settings['gltf_morph_tangent'] = self.export_morph_tangent
        else:
            export_settings['gltf_morph_tangent'] = False

        export_settings['gltf_lights'] = self.export_lights
        export_settings['gltf_displacement'] = self.export_displacement

        export_settings['gltf_binary'] = bytearray()
        export_settings['gltf_binaryfilename'] = os.path.splitext(
            os.path.basename(
                bpy.path.ensure_ext(self.filepath,
                                    self.filename_ext)))[0] + '.bin'

        user_extensions = []

        import sys
        preferences = bpy.context.preferences
        for addon_name in preferences.addons.keys():
            try:
                module = sys.modules[addon_name]
            except Exception:
                continue
            if hasattr(module, 'glTF2ExportUserExtension'):
                extension_ctor = module.glTF2ExportUserExtension
                user_extensions.append(extension_ctor())
            if hasattr(module, 'glTF2ExportUserExtensions'):
                extension_ctors = module.glTF2ExportUserExtensions
                for extension_ctor in extension_ctors:
                    user_extensions.append(extension_ctor())
        export_settings['gltf_user_extensions'] = user_extensions

        return gltf2_blender_export.save(context, export_settings)

    def draw(self, context):
        pass  # Is needed to get panels available
Пример #18
0
class OctaneThinLensCamera(bpy.types.Node, OctaneBaseNode):
    bl_idname = "OctaneThinLensCamera"
    bl_label = "Thin lens camera"
    bl_width_default = 200
    octane_render_pass_id = -1
    octane_render_pass_name = ""
    octane_render_pass_short_name = ""
    octane_render_pass_description = ""
    octane_render_pass_sub_type_name = ""
    octane_min_version = 0
    octane_node_type: IntProperty(name="Octane Node Type", default=13)
    octane_socket_list: StringProperty(
        name="Socket List",
        default=
        "Orthographic;Sensor width;Focal length;F-stop;Field of view;Scale of view;Distortion;Lens shift;Perspective correction;Pixel aspect ratio;Near clip depth;Far clip depth;Auto-focus;Focal depth;Aperture;Aperture aspect ratio;Aperture edge;Bokeh side count;Bokeh rotation;Bokeh roundedness;Position;Target;Up-vector;Stereo output;Stereo mode;Eye distance;Swap eyes;Left stereo filter;Right stereo filter;Anaglyphic stereo;"
    )
    octane_attribute_list: StringProperty(
        name="Attribute List",
        default="a_load_initial_state;a_save_initial_state;")
    octane_attribute_config_list: StringProperty(name="Attribute Config List",
                                                 default="1;1;")
    octane_static_pin_count: IntProperty(name="Octane Static Pin Count",
                                         default=30)

    a_load_initial_state: BoolProperty(
        name="Load initial state",
        default=False,
        update=None,
        description=
        "If enabled and the node gets evaluated, the camera is reset to the previously saved position and orientation"
    )
    a_save_initial_state: BoolProperty(
        name="Save initial state",
        default=True,
        update=None,
        description=
        "If enabled and the node gets evaluated, the current camera position and orientation will be saved"
    )

    def init(self, context):
        self.inputs.new("OctaneThinLensCameraOrthographic",
                        OctaneThinLensCameraOrthographic.bl_label).init()
        self.inputs.new(
            "OctaneThinLensCameraGroupPhysicalCameraParameters",
            OctaneThinLensCameraGroupPhysicalCameraParameters.bl_label).init()
        self.inputs.new("OctaneThinLensCameraSensorWidth",
                        OctaneThinLensCameraSensorWidth.bl_label).init()
        self.inputs.new("OctaneThinLensCameraFocalLength",
                        OctaneThinLensCameraFocalLength.bl_label).init()
        self.inputs.new("OctaneThinLensCameraFstop",
                        OctaneThinLensCameraFstop.bl_label).init()
        self.inputs.new("OctaneThinLensCameraGroupViewingAngle",
                        OctaneThinLensCameraGroupViewingAngle.bl_label).init()
        self.inputs.new("OctaneThinLensCameraFov",
                        OctaneThinLensCameraFov.bl_label).init()
        self.inputs.new("OctaneThinLensCameraScale",
                        OctaneThinLensCameraScale.bl_label).init()
        self.inputs.new("OctaneThinLensCameraDistortion",
                        OctaneThinLensCameraDistortion.bl_label).init()
        self.inputs.new("OctaneThinLensCameraLensShift",
                        OctaneThinLensCameraLensShift.bl_label).init()
        self.inputs.new(
            "OctaneThinLensCameraPerspectiveCorrection",
            OctaneThinLensCameraPerspectiveCorrection.bl_label).init()
        self.inputs.new("OctaneThinLensCameraPixelAspectRatio",
                        OctaneThinLensCameraPixelAspectRatio.bl_label).init()
        self.inputs.new("OctaneThinLensCameraGroupClipping",
                        OctaneThinLensCameraGroupClipping.bl_label).init()
        self.inputs.new("OctaneThinLensCameraNearClipDepth",
                        OctaneThinLensCameraNearClipDepth.bl_label).init()
        self.inputs.new("OctaneThinLensCameraFarClipDepth",
                        OctaneThinLensCameraFarClipDepth.bl_label).init()
        self.inputs.new("OctaneThinLensCameraGroupDepthOfField",
                        OctaneThinLensCameraGroupDepthOfField.bl_label).init()
        self.inputs.new("OctaneThinLensCameraAutofocus",
                        OctaneThinLensCameraAutofocus.bl_label).init()
        self.inputs.new("OctaneThinLensCameraFocalDepth",
                        OctaneThinLensCameraFocalDepth.bl_label).init()
        self.inputs.new("OctaneThinLensCameraAperture",
                        OctaneThinLensCameraAperture.bl_label).init()
        self.inputs.new(
            "OctaneThinLensCameraApertureAspectRatio",
            OctaneThinLensCameraApertureAspectRatio.bl_label).init()
        self.inputs.new("OctaneThinLensCameraApertureEdge",
                        OctaneThinLensCameraApertureEdge.bl_label).init()
        self.inputs.new("OctaneThinLensCameraBokehSidecount",
                        OctaneThinLensCameraBokehSidecount.bl_label).init()
        self.inputs.new("OctaneThinLensCameraBokehRotation",
                        OctaneThinLensCameraBokehRotation.bl_label).init()
        self.inputs.new("OctaneThinLensCameraBokehRoundedness",
                        OctaneThinLensCameraBokehRoundedness.bl_label).init()
        self.inputs.new("OctaneThinLensCameraGroupPosition",
                        OctaneThinLensCameraGroupPosition.bl_label).init()
        self.inputs.new("OctaneThinLensCameraPos",
                        OctaneThinLensCameraPos.bl_label).init()
        self.inputs.new("OctaneThinLensCameraTarget",
                        OctaneThinLensCameraTarget.bl_label).init()
        self.inputs.new("OctaneThinLensCameraUp",
                        OctaneThinLensCameraUp.bl_label).init()
        self.inputs.new("OctaneThinLensCameraGroupStereo",
                        OctaneThinLensCameraGroupStereo.bl_label).init()
        self.inputs.new("OctaneThinLensCameraStereoOutput",
                        OctaneThinLensCameraStereoOutput.bl_label).init()
        self.inputs.new("OctaneThinLensCameraStereoMode",
                        OctaneThinLensCameraStereoMode.bl_label).init()
        self.inputs.new("OctaneThinLensCameraStereodist",
                        OctaneThinLensCameraStereodist.bl_label).init()
        self.inputs.new("OctaneThinLensCameraStereoSwitchEyes",
                        OctaneThinLensCameraStereoSwitchEyes.bl_label).init()
        self.inputs.new("OctaneThinLensCameraLeftFilter",
                        OctaneThinLensCameraLeftFilter.bl_label).init()
        self.inputs.new("OctaneThinLensCameraRightFilter",
                        OctaneThinLensCameraRightFilter.bl_label).init()
        self.inputs.new("OctaneThinLensCameraStereo",
                        OctaneThinLensCameraStereo.bl_label).init()
        self.outputs.new("OctaneCameraOutSocket", "Camera out").init()
Пример #19
0
class PIX_CSV_Operator(bpy.types.Operator):

    # Plugin definitions, such as ID, name, and file extension filters
    bl_idname = "object.pix_csv_importer"
    bl_label = "Import PIX CSV"
    filepath = StringProperty(subtype = "FILE_PATH")
    filter_glob = StringProperty(default = "*.csv", options = {'HIDDEN'})

    # Options for generation of vertices
    mirror_x = BoolProperty(
                            name = "Mirror X",
                            description = "Mirror all the vertices across X axis",
                            default = True,
                            )

    vertex_order = BoolProperty(
                                name = "Change vertex order",
                                description = "Reorder vertices in counter-clockwise order",
                                default = True,
                                )

    # Options for axis alignment
    axis_forward = EnumProperty(
                                name = "Forward",
                                items = (
                                         ('X', "X Forward", ""),
                                         ('Y', "Y Forward", ""),
                                         ('Z', "Z Forward", ""),
                                         ('-X', "-X Forward", ""),
                                         ('-Y', "-Y Forward", ""),
                                         ('-Z', "-Z Forward", ""),
                                         ),
                                default = 'Z',
                                )

    axis_up = EnumProperty(
                           name = "Up",
                           items = (
                                    ('X', "X Up", ""),
                                    ('Y', "Y Up", ""),
                                    ('Z', "Z Up", ""),
                                    ('-X', "-X Up", ""),
                                    ('-Y', "-Y Up", ""),
                                    ('-Z', "-Z Up", ""),
                                    ),
                           default = 'Y',
                           )


# ~~~~~~~~~~~~~~~~~~~~Operator Functions~~~~~~~~~~~~~~~~~~~~
    def execute(self, context):
        keywords = self.as_keywords(ignore = ("axis_forward", "axis_up", "filter_glob"))
        global_matrix = axis_conversion(from_forward = self.axis_forward, from_up = self.axis_up).to_4x4()

        keywords["global_matrix"] = global_matrix
        print(keywords)
        importCSV(**keywords)

        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

    def draw(self, context):
        layout = self.layout
        col = layout.column()
        col.label(text = "Import Options")

        row = col.row()
        row.prop(self, "mirror_x")
        row = col.row()
        row.prop(self, "vertex_order")
        layout.prop(self, "axis_forward")
        layout.prop(self, "axis_up")
Пример #20
0
class OctaneVolumetricSpotlight(bpy.types.Node, OctaneBaseNode):
    bl_idname = "OctaneVolumetricSpotlight"
    bl_label = "Volumetric spotlight"
    bl_width_default = 200
    octane_render_pass_id = -1
    octane_render_pass_name = ""
    octane_render_pass_short_name = ""
    octane_render_pass_description = ""
    octane_render_pass_sub_type_name = ""
    octane_min_version = 0
    octane_node_type: IntProperty(name="Octane Node Type", default=152)
    octane_socket_list: StringProperty(
        name="Socket List",
        default=
        "Throw distance;Cone width;Light medium;Emitter material;Barn doors material;Object layer;Light transform;Enable barn doors;Barn doors size;Barn door 1 angle;Barn door 2 angle;Barn door 3 angle;Barn door 4 angle;"
    )
    octane_attribute_list: StringProperty(name="Attribute List", default="")
    octane_attribute_config_list: StringProperty(name="Attribute Config List",
                                                 default="")
    octane_static_pin_count: IntProperty(name="Octane Static Pin Count",
                                         default=13)

    def init(self, context):
        self.inputs.new(
            "OctaneVolumetricSpotlightThrowDistance",
            OctaneVolumetricSpotlightThrowDistance.bl_label).init()
        self.inputs.new("OctaneVolumetricSpotlightConeWidth",
                        OctaneVolumetricSpotlightConeWidth.bl_label).init()
        self.inputs.new("OctaneVolumetricSpotlightMedium",
                        OctaneVolumetricSpotlightMedium.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightEmitterMaterial",
            OctaneVolumetricSpotlightEmitterMaterial.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightBarnDoorsMaterial",
            OctaneVolumetricSpotlightBarnDoorsMaterial.bl_label).init()
        self.inputs.new("OctaneVolumetricSpotlightObjectLayer",
                        OctaneVolumetricSpotlightObjectLayer.bl_label).init()
        self.inputs.new("OctaneVolumetricSpotlightTransform",
                        OctaneVolumetricSpotlightTransform.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightGroupBarnDoors",
            OctaneVolumetricSpotlightGroupBarnDoors.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightEnableBarnDoors",
            OctaneVolumetricSpotlightEnableBarnDoors.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightBarnDoorsSize",
            OctaneVolumetricSpotlightBarnDoorsSize.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightBarnDoor1Angle",
            OctaneVolumetricSpotlightBarnDoor1Angle.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightBarnDoor2Angle",
            OctaneVolumetricSpotlightBarnDoor2Angle.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightBarnDoor3Angle",
            OctaneVolumetricSpotlightBarnDoor3Angle.bl_label).init()
        self.inputs.new(
            "OctaneVolumetricSpotlightBarnDoor4Angle",
            OctaneVolumetricSpotlightBarnDoor4Angle.bl_label).init()
        self.outputs.new("OctaneGeometryOutSocket", "Geometry out").init()
Пример #21
0
class SvGenFloatRange(bpy.types.Node, SverchCustomTreeNode):
    ''' Generator range list of floats'''
    bl_idname = 'SvGenFloatRange'
    bl_label = 'Range Float'
    bl_icon = 'IPO_LINEAR'

    start_: FloatProperty(name='start',
                          description='start',
                          default=0,
                          update=updateNode)

    stop_: FloatProperty(name='stop',
                         description='stop',
                         default=10,
                         update=updateNode)

    count_: IntProperty(name='count',
                        description='num items',
                        default=10,
                        min=1,
                        update=updateNode)

    step_: FloatProperty(name='step',
                         description='step',
                         default=1.0,
                         update=updateNode)

    current_mode: StringProperty(default="FRANGE")

    modes = [
        ("FRANGE", "Range", "Series based frange like function", 1),
        ("FRANGE_COUNT", "Count", "Create series based on count", 2),
        ("FRANGE_STEP", "Step", "Create range based step and count", 3),
    ]

    def mode_change(self, context):

        # just because click doesn't mean we need to change mode
        mode = self.mode
        if mode == self.current_mode:
            return

        if mode == 'FRANGE':
            self.inputs[1].prop_name = 'stop_'
            self.inputs[2].prop_name = 'step_'
        elif mode == 'FRANGE_COUNT':
            self.inputs[1].prop_name = 'stop_'
            self.inputs[2].prop_name = 'count_'
        else:
            self.inputs[1].prop_name = 'step_'
            self.inputs[2].prop_name = 'count_'

        self.current_mode = mode
        updateNode(self, context)

    mode: EnumProperty(items=modes, default='FRANGE', update=mode_change)

    def sv_init(self, context):
        self.inputs.new('SvStringsSocket', "Start").prop_name = 'start_'
        self.inputs.new('SvStringsSocket', "Step").prop_name = 'stop_'
        self.inputs.new('SvStringsSocket', "Stop").prop_name = 'step_'

        self.outputs.new('SvStringsSocket', "Range")

    def draw_buttons(self, context, layout):
        layout.prop(self, "mode", expand=True)

    func_dict = {
        'FRANGE': frange,
        'FRANGE_COUNT': frange_count,
        'FRANGE_STEP': frange_step
    }

    def process(self):
        inputs = self.inputs
        outputs = self.outputs
        if not outputs[0].is_linked:
            return
        param = [inputs[i].sv_get()[0] for i in range(3)]
        f = self.func_dict[self.mode]
        out = [list(f(*args)) for args in zip(*match_long_repeat(param))]
        outputs['Range'].sv_set(out)
Пример #22
0
class WebAuth(Operator):
    bl_idname = 'bis.web_auth'
    bl_label = 'Authorization'

    userLogin: StringProperty(name='Login',
                              description='User Login',
                              default='')
    userPassword: StringProperty(subtype='PASSWORD',
                                 name='Password',
                                 description='User Password',
                                 default='')
    userStayLogged: BoolProperty(name='Stay logged (insecure)',
                                 description='Stay logged',
                                 default=False)

    def execute(self, context):
        if WebAuthVars.logged:
            __class__.log_off(context=context)
        else:
            self.log_in(context=context)
        for area in context.screen.areas:
            area.tag_redraw()
        return {'FINISHED'}

    def invoke(self, context, event):
        if WebAuthVars.logged:
            return self.execute(context)
        else:
            if WebAuthVars.userLogin:
                self.userLogin = WebAuthVars.userLogin
            return context.window_manager.invoke_props_dialog(self)

    @classmethod
    def get_init_data(cls, context):
        WebAuthVars.logged = False
        WebAuthVars.userStayLogged = False
        with open(
                os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             'config.json')) as currentFile:
            json_data = json.load(currentFile)
            WebAuthVars.host = json_data['host']
            WebAuthVars.requestBase = json_data['requestbase']
            if 'userLogin' in json_data:
                WebAuthVars.userLogin = json_data['userLogin']
            else:
                WebAuthVars.userLogin = ''
            if 'token' in json_data:
                WebAuthVars.token = json_data['token']
            else:
                WebAuthVars.token = ''
            currentFile.close()
        if WebAuthVars.token:
            cls.log_in(cls, context=context)

    def log_in(self, context):
        if WebAuthVars.token:
            if __class__.check_token_valid(context=context,
                                           user_login=WebAuthVars.userLogin,
                                           token=WebAuthVars.token):
                WebAuthVars.logged = True
            else:
                __class__.log_off(context=context)
        else:
            request = WebRequest.send_request(context=context,
                                              data={
                                                  'userlogin': self.userLogin,
                                                  'userpassword':
                                                  self.userPassword
                                              },
                                              host_target='blender_auth')
            self.userPassword = ''
            if request:
                request_rez = json.loads(request.text)
                if request_rez['stat'] == 'OK':
                    WebAuthVars.logged = True
                    WebAuthVars.token = request_rez['data']['token']
                    WebAuthVars.userLogin = self.userLogin
                    WebAuthVars.userProStatus = request_rez['data'][
                        'prostatus']
                    __class__.save_config(
                        user_login=WebAuthVars.userLogin,
                        token=WebAuthVars.token if self.userStayLogged else '')
                else:
                    bpy.ops.bis.messagebox('INVOKE_DEFAULT',
                                           message=request_rez['data']['text'])
                    __class__.log_off(context=context)

    @staticmethod
    def log_off(context):
        WebAuthVars.token = ''
        WebAuthVars.logged = False
        WebRequestsVars.close_session()
        __class__.save_config(user_login=WebAuthVars.userLogin)

    @staticmethod
    def check_token_valid(context, user_login='', token=''):
        request = WebRequest.send_request(context=context,
                                          data={
                                              'userlogin': user_login,
                                              'token': token
                                          },
                                          host_target='blender_auth')
        if request:
            request_rez = json.loads(request.text)
            if request_rez['stat'] == 'OK':
                WebAuthVars.userProStatus = request_rez['data']['prostatus']
                return True
        return False

    @staticmethod
    def save_config(user_login='', token=''):
        with open(
                os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             'config.json'), 'r+') as configFile:
            json_data = json.load(configFile)
            json_data['token'] = token
            json_data['userLogin'] = user_login
            configFile.seek(0)
            configFile.truncate()
            json.dump(json_data, configFile, indent=4)
            configFile.close()
Пример #23
0
def register():
    bpy.utils.register_module(__name__)

    bpy.types.Scene.iskeyfree_data = StringProperty(
        name="Key", maxlen=32, description="Shortcut to verify")
    bpy.types.Scene.iskeyfree_use_crtl = BoolProperty(
        name="Ctrl", description="Ctrl key used in shortcut", default=False)
    bpy.types.Scene.iskeyfree_use_alt = BoolProperty(
        name="Alt", description="Alt key used in shortcut", default=False)
    bpy.types.Scene.iskeyfree_use_shift = BoolProperty(
        name="Shift", description="Shift key used in shortcut", default=False)
    bpy.types.Scene.iskeyfree_use_oskey = BoolProperty(
        name="OsKey",
        description="Operating system key used in shortcut",
        default=False)
    bpy.types.Scene.iskeyfree_numpad = EnumProperty(
        items=(('NONE', "Select key", ""), ("LEFTMOUSE", "LEFTMOUSE", ""),
               ("MIDDLEMOUSE", "MIDDLEMOUSE",
                ""), ("RIGHTMOUSE", "RIGHTMOUSE",
                      ""), ("BUTTON4MOUSE", "BUTTON4MOUSE",
                            ""), ("BUTTON5MOUSE", "BUTTON5MOUSE",
                                  ""), ("BUTTON6MOUSE", "BUTTON6MOUSE", ""),
               ("BUTTON7MOUSE", "BUTTON7MOUSE",
                ""), ("ACTIONMOUSE", "ACTIONMOUSE",
                      ""), ("SELECTMOUSE", "SELECTMOUSE",
                            ""), ("MOUSEMOVE", "MOUSEMOVE", ""),
               ("INBETWEEN_MOUSEMOVE", "INBETWEEN_MOUSEMOVE",
                ""), ("TRACKPADPAN", "TRACKPADPAN",
                      ""), ("TRACKPADZOOM", "TRACKPADZOOM",
                            ""), ("MOUSEROTATE", "MOUSEROTATE",
                                  ""), ("WHEELUPMOUSE", "WHEELUPMOUSE", ""),
               ("WHEELDOWNMOUSE", "WHEELDOWNMOUSE",
                ""), ("WHEELINMOUSE", "WHEELINMOUSE",
                      ""), ("WHEELOUTMOUSE", "WHEELOUTMOUSE",
                            ""), ("EVT_TWEAK_L", "EVT_TWEAK_L",
                                  ""), ("EVT_TWEAK_M", "EVT_TWEAK_M", ""),
               ("EVT_TWEAK_R", "EVT_TWEAK_R",
                ""), ("EVT_TWEAK_A", "EVT_TWEAK_A",
                      ""), ("EVT_TWEAK_S", "EVT_TWEAK_S", ""), ("A", "A", ""),
               ("B", "B", ""), ("C", "C", ""), ("D", "D", ""), ("E", "E", ""),
               ("F", "F", ""), ("G", "G", ""), ("H", "H", ""), ("I", "I", ""),
               ("J", "J", ""), ("K", "K", ""), ("L", "L", ""), ("M", "M", ""),
               ("N", "N", ""), ("O", "O", ""), ("P", "P", ""), ("Q", "Q", ""),
               ("R", "R", ""), ("S", "S", ""), ("T", "T", ""), ("U", "U", ""),
               ("V", "V", ""), ("W", "W", ""), ("X", "X", ""), ("Y", "Y", ""),
               ("Z", "Z", ""), ("ZERO", "ZERO", ""), ("ONE", "ONE",
                                                      ""), ("TWO", "TWO", ""),
               ("THREE", "THREE",
                ""), ("FOUR", "FOUR",
                      ""), ("FIVE", "FIVE",
                            ""), ("SIX", "SIX", ""), ("SEVEN", "SEVEN",
                                                      ""), ("EIGHT", "EIGHT",
                                                            ""), ("NINE",
                                                                  "NINE", ""),
               ("LEFT_CTRL", "LEFT_CTRL",
                ""), ("LEFT_ALT", "LEFT_ALT",
                      ""), ("LEFT_SHIFT", "LEFT_SHIFT",
                            ""), ("RIGHT_ALT", "RIGHT_ALT",
                                  ""), ("RIGHT_CTRL", "RIGHT_CTRL",
                                        ""), ("RIGHT_SHIFT", "RIGHT_SHIFT",
                                              ""), ("OSKEY", "OSKEY", ""),
               ("GRLESS", "GRLESS",
                ""), ("ESC", "ESC",
                      ""), ("TAB", "TAB",
                            ""), ("RET", "RET",
                                  ""), ("SPACE", "SPACE",
                                        ""), ("LINE_FEED", "LINE_FEED",
                                              ""), ("BACK_SPACE", "BACK_SPACE",
                                                    ""), ("DEL", "DEL", ""),
               ("SEMI_COLON", "SEMI_COLON",
                ""), ("PERIOD", "PERIOD",
                      ""), ("COMMA", "COMMA",
                            ""), ("QUOTE", "QUOTE",
                                  ""), ("ACCENT_GRAVE", "ACCENT_GRAVE",
                                        ""), ("MINUS", "MINUS",
                                              ""), ("SLASH", "SLASH",
                                                    ""), ("BACK_SLASH",
                                                          "BACK_SLASH", ""),
               ("EQUAL", "EQUAL",
                ""), ("LEFT_BRACKET", "LEFT_BRACKET",
                      ""), ("RIGHT_BRACKET", "RIGHT_BRACKET",
                            ""), ("LEFT_ARROW", "LEFT_ARROW",
                                  ""), ("DOWN_ARROW", "DOWN_ARROW",
                                        ""), ("RIGHT_ARROW", "RIGHT_ARROW",
                                              ""), ("UP_ARROW", "UP_ARROW",
                                                    ""), ("NUMPAD_1",
                                                          "NUMPAD_1", ""),
               ("NUMPAD_2", "NUMPAD_2",
                ""), ("NUMPAD_3", "NUMPAD_3",
                      ""), ("NUMPAD_4", "NUMPAD_4",
                            ""), ("NUMPAD_5", "NUMPAD_5",
                                  ""), ("NUMPAD_6", "NUMPAD_6",
                                        ""), ("NUMPAD_7", "NUMPAD_7",
                                              ""), ("NUMPAD_8", "NUMPAD_8",
                                                    ""), ("NUMPAD_9",
                                                          "NUMPAD_9", ""),
               ("NUMPAD_0", "NUMPAD_0",
                ""), ("NUMPAD_PERIOD", "NUMPAD_PERIOD",
                      ""), ("NUMPAD_SLASH", "NUMPAD_SLASH",
                            ""), ("NUMPAD_ASTERIX", "NUMPAD_ASTERIX",
                                  ""), ("NUMPAD_MINUS", "NUMPAD_MINUS",
                                        ""), ("NUMPAD_ENTER", "NUMPAD_ENTER",
                                              ""), ("NUMPAD_PLUS",
                                                    "NUMPAD_PLUS",
                                                    ""), ("F1", "F1", ""),
               ("F2", "F2",
                ""), ("F3", "F3",
                      ""), ("F4", "F4",
                            ""), ("F5", "F5",
                                  ""), ("F6", "F6",
                                        ""), ("F7", "F7",
                                              ""), ("F8", "F8",
                                                    ""), ("F9", "F9", ""),
               ("F10", "F10",
                ""), ("F11", "F11",
                      ""), ("F12", "F12",
                            ""), ("F13", "F13",
                                  ""), ("F14", "F14",
                                        ""), ("F15", "F15",
                                              ""), ("F16", "F16",
                                                    ""), ("F17", "F17", ""),
               ("F18", "F18",
                ""), ("F19", "F19",
                      ""), ("PAUSE", "PAUSE",
                            ""), ("INSERT", "INSERT",
                                  ""), ("HOME", "HOME",
                                        ""), ("PAGE_UP", "PAGE_UP",
                                              ""), ("PAGE_DOWN", "PAGE_DOWN",
                                                    ""), ("END", "END", ""),
               ("MEDIA_PLAY", "MEDIA_PLAY",
                ""), ("MEDIA_STOP", "MEDIA_STOP",
                      ""), ("MEDIA_FIRST", "MEDIA_FIRST",
                            ""), ("MEDIA_LAST", "MEDIA_LAST",
                                  ""), ("TEXTINPUT", "TEXTINPUT",
                                        ""), ("WINDOW_DEACTIVATE",
                                              "WINDOW_DEACTIVATE",
                                              ""), ("TIMER", "TIMER",
                                                    ""), ("TIMER0", "TIMER0",
                                                          ""), ("TIMER1",
                                                                "TIMER1", ""),
               ("TIMER2", "TIMER2",
                ""), ("TIMER_JOBS", "TIMER_JOBS",
                      ""), ("TIMER_AUTOSAVE", "TIMER_AUTOSAVE",
                            ""), ("TIMER_REPORT", "TIMER_REPORT",
                                  ""), ("TIMERREGION", "TIMERREGION",
                                        ""), ("NDOF_MOTION", "NDOF_MOTION",
                                              ""), ("NDOF_BUTTON_MENU",
                                                    "NDOF_BUTTON_MENU", ""),
               ("NDOF_BUTTON_FIT", "NDOF_BUTTON_FIT",
                ""), ("NDOF_BUTTON_TOP", "NDOF_BUTTON_TOP",
                      ""), ("NDOF_BUTTON_BOTTOM", "NDOF_BUTTON_BOTTOM",
                            ""), ("NDOF_BUTTON_LEFT", "NDOF_BUTTON_LEFT", ""),
               ("NDOF_BUTTON_RIGHT", "NDOF_BUTTON_RIGHT",
                ""), ("NDOF_BUTTON_FRONT", "NDOF_BUTTON_FRONT",
                      ""), ("NDOF_BUTTON_BACK", "NDOF_BUTTON_BACK",
                            ""), ("NDOF_BUTTON_ISO1", "NDOF_BUTTON_ISO1",
                                  ""), ("NDOF_BUTTON_ISO2", "NDOF_BUTTON_ISO2",
                                        ""), ("NDOF_BUTTON_ROLL_CW",
                                              "NDOF_BUTTON_ROLL_CW", ""),
               ("NDOF_BUTTON_ROLL_CCW", "NDOF_BUTTON_ROLL_CCW",
                ""), ("NDOF_BUTTON_SPIN_CW", "NDOF_BUTTON_SPIN_CW",
                      ""), ("NDOF_BUTTON_SPIN_CCW", "NDOF_BUTTON_SPIN_CCW",
                            ""), ("NDOF_BUTTON_TILT_CW", "NDOF_BUTTON_TILT_CW",
                                  ""), ("NDOF_BUTTON_TILT_CCW",
                                        "NDOF_BUTTON_TILT_CCW",
                                        ""), ("NDOF_BUTTON_ROTATE",
                                              "NDOF_BUTTON_ROTATE", ""),
               ("NDOF_BUTTON_PANZOOM", "NDOF_BUTTON_PANZOOM",
                ""), ("NDOF_BUTTON_DOMINANT", "NDOF_BUTTON_DOMINANT",
                      ""), ("NDOF_BUTTON_PLUS", "NDOF_BUTTON_PLUS",
                            ""), ("NDOF_BUTTON_MINUS", "NDOF_BUTTON_MINUS",
                                  ""), ("NDOF_BUTTON_ESC", "NDOF_BUTTON_ESC",
                                        ""), ("NDOF_BUTTON_ALT",
                                              "NDOF_BUTTON_ALT", ""),
               ("NDOF_BUTTON_SHIFT", "NDOF_BUTTON_SHIFT",
                ""), ("NDOF_BUTTON_CTRL", "NDOF_BUTTON_CTRL",
                      ""), ("NDOF_BUTTON_1", "NDOF_BUTTON_1",
                            ""), ("NDOF_BUTTON_2", "NDOF_BUTTON_2",
                                  ""), ("NDOF_BUTTON_3", "NDOF_BUTTON_3",
                                        ""), ("NDOF_BUTTON_4", "NDOF_BUTTON_4",
                                              ""), ("NDOF_BUTTON_5",
                                                    "NDOF_BUTTON_5",
                                                    ""), ("NDOF_BUTTON_6",
                                                          "NDOF_BUTTON_6", ""),
               ("NDOF_BUTTON_7", "NDOF_BUTTON_7",
                ""), ("NDOF_BUTTON_8", "NDOF_BUTTON_8",
                      ""), ("NDOF_BUTTON_9", "NDOF_BUTTON_9",
                            ""), ("NDOF_BUTTON_10", "NDOF_BUTTON_10",
                                  ""), ("NDOF_BUTTON_A", "NDOF_BUTTON_A",
                                        ""), ("NDOF_BUTTON_B", "NDOF_BUTTON_B",
                                              ""), ("NDOF_BUTTON_C",
                                                    "NDOF_BUTTON_C", "")),
        name="Quick Type",
        description="Enter key code in find text",
        update=update_data)
Пример #24
0
def register():
    Scene = bpy.types.Scene
    Mat = bpy.types.Material
    Tex = bpy.types.Texture
    Obj = bpy.types.Object
    Cam = bpy.types.Camera
    Text = bpy.types.Text
    ###########################SCENE##################################

    # File Options
    Scene.pov_tempfiles_enable = BoolProperty(
        name="Enable Tempfiles",
        description=
        "Enable the OS-Tempfiles. Otherwise set the path where to save the files",
        default=True)
    Scene.pov_deletefiles_enable = BoolProperty(
        name="Delete files",
        description="Delete files after rendering. Doesn't work with the image",
        default=True)
    Scene.pov_scene_name = StringProperty(
        name="Scene Name",
        description=
        "Name of POV-Ray scene to create. Empty name will use the name of the blend file",
        default="",
        maxlen=1024)
    Scene.pov_scene_path = StringProperty(
        name="Export scene path",
        # description="Path to directory where the exported scene (POV and INI) is created",  # Bug in POV-Ray RC3
        description="Path to directory where the files are created",
        default="",
        maxlen=1024,
        subtype="DIR_PATH")
    Scene.pov_renderimage_path = StringProperty(
        name="Rendered image path",
        description="Full path to directory where the rendered image is saved",
        default="",
        maxlen=1024,
        subtype="DIR_PATH")
    Scene.pov_list_lf_enable = BoolProperty(
        name="LF in lists",
        description=
        "Enable line breaks in lists (vectors and indices). Disabled: lists are exported in one line",
        default=True)

    # Not a real pov option, just to know if we should write
    Scene.pov_radio_enable = BoolProperty(
        name="Enable Radiosity",
        description="Enable POV-Rays radiosity calculation",
        default=False)
    Scene.pov_radio_display_advanced = BoolProperty(
        name="Advanced Options",
        description="Show advanced options",
        default=False)
    Scene.pov_media_enable = BoolProperty(
        name="Enable Media",
        description="Enable POV-Rays atmospheric media",
        default=False)
    Scene.pov_media_samples = IntProperty(
        name="Samples",
        description=
        "Number of samples taken from camera to first object encountered along ray path for media calculation",
        min=1,
        max=100,
        default=35)

    Scene.pov_media_color = FloatVectorProperty(
        name="Media Color",
        description="The atmospheric media color",
        subtype='COLOR',
        precision=4,
        step=0.01,
        min=0,
        soft_max=1,
        default=(0.001, 0.001, 0.001),
        options={'ANIMATABLE'})

    Scene.pov_baking_enable = BoolProperty(
        name="Enable Baking",
        description="Enable POV-Rays texture baking",
        default=False)
    Scene.pov_indentation_character = EnumProperty(
        name="Indentation",
        description="Select the indentation type",
        items=(("0", "None", "No indentation"), ("1", "Tabs",
                                                 "Indentation with tabs"),
               ("2", "Spaces", "Indentation with spaces")),
        default="2")
    Scene.pov_indentation_spaces = IntProperty(
        name="Quantity of spaces",
        description="The number of spaces for indentation",
        min=1,
        max=10,
        default=4)

    Scene.pov_comments_enable = BoolProperty(
        name="Enable Comments",
        description="Add comments to pov file",
        default=True)

    # Real pov options
    Scene.pov_command_line_switches = StringProperty(
        name="Command Line Switches",
        description=
        "Command line switches consist of a + (plus) or - (minus) sign, followed by one or more alphabetic characters and possibly a numeric value",
        default="",
        maxlen=500)

    Scene.pov_antialias_enable = BoolProperty(
        name="Anti-Alias", description="Enable Anti-Aliasing", default=True)

    Scene.pov_antialias_method = EnumProperty(
        name="Method",
        description=
        "AA-sampling method. Type 1 is an adaptive, non-recursive, super-sampling method. Type 2 is an adaptive and recursive super-sampling method",
        items=(("0", "non-recursive AA", "Type 1 Sampling in POV-Ray"),
               ("1", "recursive AA", "Type 2 Sampling in POV-Ray")),
        default="1")

    Scene.pov_antialias_depth = IntProperty(
        name="Antialias Depth",
        description="Depth of pixel for sampling",
        min=1,
        max=9,
        default=3)

    Scene.pov_antialias_threshold = FloatProperty(
        name="Antialias Threshold",
        description="Tolerance for sub-pixels",
        min=0.0,
        max=1.0,
        soft_min=0.05,
        soft_max=0.5,
        default=0.1)

    Scene.pov_jitter_enable = BoolProperty(
        name="Jitter",
        description=
        "Enable Jittering. Adds noise into the sampling process (it should be avoided to use jitter in animation)",
        default=True)

    Scene.pov_jitter_amount = FloatProperty(name="Jitter Amount",
                                            description="Amount of jittering",
                                            min=0.0,
                                            max=1.0,
                                            soft_min=0.01,
                                            soft_max=1.0,
                                            default=1.0)

    Scene.pov_antialias_gamma = FloatProperty(
        name="Antialias Gamma",
        description=
        "POV-Ray compares gamma-adjusted values for super sampling. Antialias Gamma sets the Gamma before comparison",
        min=0.0,
        max=5.0,
        soft_min=0.01,
        soft_max=2.5,
        default=2.5)

    Scene.pov_max_trace_level = IntProperty(
        name="Max Trace Level",
        description="Number of reflections/refractions allowed on ray path",
        min=1,
        max=256,
        default=5)

    Scene.pov_photon_spacing = FloatProperty(
        name="Spacing",
        description=
        "Average distance between photons on surfaces. half this get four times as many surface photons",
        min=0.001,
        max=1.000,
        soft_min=0.001,
        soft_max=1.000,
        default=0.005,
        precision=3)

    Scene.pov_photon_max_trace_level = IntProperty(
        name="Max Trace Level",
        description="Number of reflections/refractions allowed on ray path",
        min=1,
        max=256,
        default=5)

    Scene.pov_photon_adc_bailout = FloatProperty(
        name="ADC Bailout",
        description=
        "The adc_bailout for photons. Use adc_bailout = 0.01 / brightest_ambient_object for good results",
        min=0.0,
        max=1000.0,
        soft_min=0.0,
        soft_max=1.0,
        default=0.1,
        precision=3)

    Scene.pov_photon_gather_min = IntProperty(
        name="Gather Min",
        description="Minimum number of photons gathered for each point",
        min=1,
        max=256,
        default=20)

    Scene.pov_photon_gather_max = IntProperty(
        name="Gather Max",
        description="Maximum number of photons gathered for each point",
        min=1,
        max=256,
        default=100)

    Scene.pov_radio_adc_bailout = FloatProperty(
        name="ADC Bailout",
        description=
        "The adc_bailout for radiosity rays. Use adc_bailout = 0.01 / brightest_ambient_object for good results",
        min=0.0,
        max=1000.0,
        soft_min=0.0,
        soft_max=1.0,
        default=0.01,
        precision=3)

    Scene.pov_radio_always_sample = BoolProperty(
        name="Always Sample",
        description=
        "Only use the data from the pretrace step and not gather any new samples during the final radiosity pass",
        default=True)

    Scene.pov_radio_brightness = FloatProperty(
        name="Brightness",
        description=
        "Amount objects are brightened before being returned upwards to the rest of the system",
        min=0.0,
        max=1000.0,
        soft_min=0.0,
        soft_max=10.0,
        default=1.0)

    Scene.pov_radio_count = IntProperty(
        name="Ray Count",
        description=
        "Number of rays for each new radiosity value to be calculated (halton sequence over 1600)",
        min=1,
        max=10000,
        soft_max=1600,
        default=35)

    Scene.pov_radio_error_bound = FloatProperty(
        name="Error Bound",
        description=
        "One of the two main speed/quality tuning values, lower values are more accurate",
        min=0.0,
        max=1000.0,
        soft_min=0.1,
        soft_max=10.0,
        default=1.8)

    Scene.pov_radio_gray_threshold = FloatProperty(
        name="Gray Threshold",
        description=
        "One of the two main speed/quality tuning values, lower values are more accurate",
        min=0.0,
        max=1.0,
        soft_min=0,
        soft_max=1,
        default=0.0)

    Scene.pov_radio_low_error_factor = FloatProperty(
        name="Low Error Factor",
        description=
        "Just enough samples is slightly blotchy. Low error changes error tolerance for less critical last refining pass",
        min=0.0,
        max=1.0,
        soft_min=0.0,
        soft_max=1.0,
        default=0.5)

    # max_sample - not available yet
    Scene.pov_radio_media = BoolProperty(
        name="Media",
        description="Radiosity estimation can be affected by media",
        default=False)

    Scene.pov_radio_minimum_reuse = FloatProperty(
        name="Minimum Reuse",
        description=
        "Fraction of the screen width which sets the minimum radius of reuse for each sample point (At values higher than 2% expect errors)",
        min=0.0,
        max=1.0,
        soft_min=0.1,
        soft_max=0.1,
        default=0.015,
        precision=3)

    Scene.pov_radio_nearest_count = IntProperty(
        name="Nearest Count",
        description=
        "Number of old ambient values blended together to create a new interpolated value",
        min=1,
        max=20,
        default=5)

    Scene.pov_radio_normal = BoolProperty(
        name="Normals",
        description="Radiosity estimation can be affected by normals",
        default=False)

    Scene.pov_radio_recursion_limit = IntProperty(
        name="Recursion Limit",
        description=
        "how many recursion levels are used to calculate the diffuse inter-reflection",
        min=1,
        max=20,
        default=3)

    Scene.pov_radio_pretrace_start = FloatProperty(
        name="Pretrace Start",
        description=
        "Fraction of the screen width which sets the size of the blocks in the mosaic preview first pass",
        min=0.01,
        max=1.00,
        soft_min=0.02,
        soft_max=1.0,
        default=0.08)

    Scene.pov_radio_pretrace_end = FloatProperty(
        name="Pretrace End",
        description=
        "Fraction of the screen width which sets the size of the blocks in the mosaic preview last pass",
        min=0.001,
        max=1.00,
        soft_min=0.01,
        soft_max=1.00,
        default=0.04,
        precision=3)

    #############################MATERIAL######################################

    Mat.pov_irid_enable = BoolProperty(
        name="Enable Iridescence",
        description=
        "Newton's thin film interference (like an oil slick on a puddle of water or the rainbow hues of a soap bubble.)",
        default=False)

    Mat.pov_mirror_use_IOR = BoolProperty(
        name="Correct Reflection",
        description=
        "Use same IOR as raytrace transparency to calculate mirror reflections. More physically correct",
        default=False)

    Mat.pov_mirror_metallic = BoolProperty(
        name="Metallic Reflection",
        description=
        "mirror reflections get colored as diffuse (for metallic materials)",
        default=False)

    Mat.pov_conserve_energy = BoolProperty(
        name="Conserve Energy",
        description=
        "Light transmitted is more correctly reduced by mirror reflections, also the sum of diffuse and translucency gets reduced below one ",
        default=True)

    Mat.pov_irid_amount = FloatProperty(
        name="amount",
        description=
        "Contribution of the iridescence effect to the overall surface color. As a rule of thumb keep to around 0.25 (25% contribution) or less, but experiment. If the surface is coming out too white, try lowering the diffuse and possibly the ambient values of the surface",
        min=0.0,
        max=1.0,
        soft_min=0.01,
        soft_max=1.0,
        default=0.25)

    Mat.pov_irid_thickness = FloatProperty(
        name="thickness",
        description=
        "A very thin film will have a high frequency of color changes while a thick film will have large areas of color",
        min=0.0,
        max=1000.0,
        soft_min=0.1,
        soft_max=10.0,
        default=1)

    Mat.pov_irid_turbulence = FloatProperty(
        name="turbulence",
        description="This parameter varies the thickness",
        min=0.0,
        max=10.0,
        soft_min=0.000,
        soft_max=1.0,
        default=0)

    Mat.pov_interior_fade_color = FloatVectorProperty(
        name="Fade Color",
        description="Color of filtered attenuation for transparent materials",
        subtype='COLOR',
        precision=4,
        step=0.01,
        min=0.0,
        soft_max=1.0,
        default=(0, 0, 0),
        options={'ANIMATABLE'})

    Mat.pov_caustics_enable = BoolProperty(
        name="Caustics",
        description=
        "use only fake refractive caustics (default) or photon based reflective/refractive caustics",
        default=True)

    Mat.pov_fake_caustics = BoolProperty(
        name="Fake Caustics",
        description="use only (Fast) fake refractive caustics",
        default=True)

    Mat.pov_fake_caustics_power = FloatProperty(
        name="Fake caustics power",
        description=
        "Values typically range from 0.0 to 1.0 or higher. Zero is no caustics. Low, non-zero values give broad hot-spots while higher values give tighter, smaller simulated focal points",
        min=0.00,
        max=10.0,
        soft_min=0.00,
        soft_max=1.10,
        default=0.1)

    Mat.pov_photons_refraction = BoolProperty(
        name="Refractive Photon Caustics",
        description="more physically correct",
        default=False)

    Mat.pov_photons_dispersion = FloatProperty(
        name="chromatic dispersion",
        description=
        "Light passing through will be separated according to wavelength. This ratio of refractive indices for violet to red controls how much the colors are spread out 1 = no dispersion, good values are 1.01 to 1.1",
        min=1.0000,
        max=10.000,
        soft_min=1.0000,
        soft_max=1.1000,
        precision=4,
        default=1.0000)

    Mat.pov_photons_reflection = BoolProperty(
        name="Reflective Photon Caustics",
        description="Use this to make your Sauron's ring ;-P",
        default=False)

    Mat.pov_refraction_type = EnumProperty(
        items=[
            ("0", "None", "use only reflective caustics"),
            ("1", "Fake Caustics", "use fake caustics"),
            ("2", "Photons Caustics", "use photons for refractive caustics"),
        ],
        name="Refractive",
        description=
        "use fake caustics (fast) or true photons for refractive Caustics",
        default="1")
    ##################################CustomPOV Code############################
    Mat.pov_replacement_text = StringProperty(
        name="Declared name:",
        description=
        "Type the declared name in custom POV code or an external .inc it points at. texture {} expected",
        default="")

    #Only DUMMIES below for now:
    Tex.pov_replacement_text = StringProperty(
        name="Declared name:",
        description=
        "Type the declared name in custom POV code or an external .inc it points at. pigment {} expected",
        default="")

    Obj.pov_replacement_text = StringProperty(
        name="Declared name:",
        description=
        "Type the declared name in custom POV code or an external .inc it points at. Any POV shape expected e.g: isosurface {}",
        default="")

    Cam.pov_replacement_text = StringProperty(
        name="Texts in blend file",
        description=
        "Type the declared name in custom POV code or an external .inc it points at. camera {} expected",
        default="")
    ##############################TEXTURE######################################

    #Custom texture gamma
    Tex.pov_tex_gamma_enable = BoolProperty(
        name="Enable custom texture gamma",
        description=
        "Notify some custom gamma for which texture has been precorrected without the file format carrying it and only if it differs from your OS expected standard (see pov doc)",
        default=False)

    Tex.pov_tex_gamma_value = FloatProperty(
        name="Custom texture gamma",
        description=
        "value for which the file was issued e.g. a Raw photo is gamma 1.0",
        min=0.45,
        max=5.00,
        soft_min=1.00,
        soft_max=2.50,
        default=1.00)

    #################################OBJECT####################################

    #Importance sampling
    Obj.pov_importance_value = FloatProperty(
        name="Radiosity Importance",
        description=
        "Priority value relative to other objects for sampling radiosity rays. Increase to get more radiosity rays at comparatively small yet bright objects",
        min=0.01,
        max=1.00,
        default=1.00)

    #Collect photons
    Obj.pov_collect_photons = BoolProperty(
        name="Receive Photon Caustics",
        description=
        "Enable object to collect photons from other objects caustics. Turn off for objects that don't really need to receive caustics (e.g. objects that generate caustics often don't need to show any on themselves) ",
        default=True)

    ##################################CAMERA###################################

    #DOF Toggle
    Cam.pov_dof_enable = BoolProperty(
        name="Depth Of Field",
        description="Enable POV-Ray Depth Of Field ",
        default=True)

    #Aperture (Intensity of the Blur)
    Cam.pov_dof_aperture = FloatProperty(
        name="Aperture",
        description=
        "Similar to a real camera's aperture effect over focal blur (though not in physical units and independant of focal length).Increase to get more blur",
        min=0.01,
        max=1.00,
        default=0.25)

    #Aperture adaptive sampling
    Cam.pov_dof_samples_min = IntProperty(
        name="Samples Min",
        description="Minimum number of rays to use for each pixel",
        min=1,
        max=128,
        default=96)

    Cam.pov_dof_samples_max = IntProperty(
        name="Samples Max",
        description="Maximum number of rays to use for each pixel",
        min=1,
        max=128,
        default=128)

    Cam.pov_dof_variance = IntProperty(
        name="Variance",
        description=
        "Minimum threshold (fractional value) for adaptive DOF sampling (up increases quality and render time). The value for the variance should be in the range of the smallest displayable color difference",
        min=1,
        max=100000,
        soft_max=10000,
        default=256)

    Cam.pov_dof_confidence = FloatProperty(
        name="Confidence",
        description=
        "Probability to reach the real color value. Larger confidence values will lead to more samples, slower traces and better images",
        min=0.01,
        max=0.99,
        default=0.90)

    ###################################TEXT####################################

    Text.pov_custom_code = BoolProperty(
        name="Custom Code",
        description="Add this text at the top of the exported POV-Ray file",
        default=False)
Пример #25
0
class PhobosPrefs(AddonPreferences):
    """The general Phobos addon settings are stored in this class.
    They can be edited in the User Preferences of Blender under the Addon tab.

    Args:

    Returns:

    """
    bl_idname = __package__

    logfile = StringProperty(
        name="logfile",
        subtype="FILE_PATH",
        default="."
    )

    loglevel = EnumProperty(
        name="loglevel",
        items=tuple(((l,) * 3 for l in LOGLEVELS)),
        default="ERROR"
    )

    logtofile = BoolProperty(
        name="logtofile",
        default=False
    )

    logtoterminal = BoolProperty(
        name="logtoterminal",
        default=True
    )

    modelsfolder = StringProperty(
        name="modelsfolder",
        subtype="DIR_PATH",
        default=''
    )

    configfolder = StringProperty(
        name="configfolder",
        subtype="DIR_PATH",
        description="Path to the system-dependent config folder of Phobos.",
        default=''
    )

    exportpluginsfolder = StringProperty(
        name='exportpluginsfolder',
        subtype='DIR_PATH',
        default='.'
    )

    models_poses = CollectionProperty(type=ModelPoseProp)

    def draw(self, context):
        layout = self.layout
        layout.label(text="Log Settings")
        layout.prop(self, "logfile", text="log file path")
        layout.prop(self, "logtofile", text="write to logfile")
        layout.prop(self, "logtoterminal", text="write to terminal")
        layout.prop(self, "loglevel", text="log level")
        layout.separator()
        layout.label(text="Folders")
        layout.prop(self, "modelsfolder", text="models folder")
        layout.prop(self, "configfolder", text="config folder")
Пример #26
0
class SvVectorMathNodeMK3(bpy.types.Node, SverchCustomTreeNode):
    '''Vector: Add, Dot P..'''
    bl_idname = 'SvVectorMathNodeMK3'
    bl_label = 'Vector Math'
    bl_icon = 'THREE_DOTS'
    sv_icon = 'SV_VECTOR_MATH'

    @throttled
    def mode_change(self, context):
        self.update_sockets()

    current_op: EnumProperty(items=vector_math_ops,
                             name="Function",
                             description="Function choice",
                             default="COMPONENT-WISE",
                             update=mode_change)

    amount: FloatProperty(default=1.0, name='amount', update=updateNode)
    v3_input_0: FloatVectorProperty(size=3,
                                    default=(0, 0, 0),
                                    name='input a',
                                    update=updateNode)
    v3_input_1: FloatVectorProperty(size=3,
                                    default=(0, 0, 0),
                                    name='input b',
                                    update=updateNode)

    implementation_modes = [("NumPy", "NumPy", "NumPy", 0),
                            ("MathUtils", "MathUtils", "MathUtils", 1)]

    implementation: EnumProperty(name='Implementation',
                                 items=implementation_modes,
                                 description='Choose calculation method',
                                 default="NumPy",
                                 update=updateNode)

    implementation_func_dict = {
        "NumPy": (numpy_vector_func_dict, recurse_fx_numpy, recurse_fxy_numpy),
        "MathUtils": (mathutils_vector_func_dict, recurse_fx, recurse_fxy)
    }

    output_numpy: BoolProperty(name='Output NumPy',
                               description='Output NumPy arrays',
                               default=False,
                               update=updateNode)

    def draw_label(self):
        text = self.current_op.replace("_", " ")
        if text in {'SCALAR', '1/SCALAR'}:
            text = f'A * {text}'
        return text

    def draw_buttons(self, ctx, layout):
        layout.prop(self,
                    "current_op",
                    text="",
                    icon_value=custom_icon("SV_FUNCTION"))

    def draw_buttons_ext(self, ctx, layout):
        layout.prop(self,
                    "current_op",
                    text="",
                    icon_value=custom_icon("SV_FUNCTION"))
        layout.label(text="Implementation:")
        layout.prop(self, "implementation", expand=True)
        if self.implementation == "NumPy":
            layout.prop(self, "output_numpy", toggle=False)

    def rclick_menu(self, context, layout):
        layout.prop_menu_enum(self, "current_op", text="Function")
        layout.prop_menu_enum(self, "implementation", text="Implementation")
        if self.implementation == "NumPy":
            layout.prop(self, "output_numpy", toggle=True)

    def sv_init(self, context):
        self.inputs.new('SvVerticesSocket', "A").prop_name = 'v3_input_0'
        self.inputs.new('SvVerticesSocket', "B").prop_name = 'v3_input_1'
        self.outputs.new('SvVerticesSocket', "Out")

    socket_info: StringProperty(default="vv v")

    def update_sockets(self):
        socket_info = numpy_vector_func_dict.get(self.current_op)[2]
        if socket_info != self.socket_info:
            self.socket_info = socket_info
            t_inputs, t_outputs = socket_info.split(' ')

            self.outputs[0].replace_socket(socket_type.get(t_outputs))

            if len(t_inputs) > len(self.inputs):
                self.inputs.new('SvVerticesSocket', "dummy")
            elif len(t_inputs) < len(self.inputs):
                self.inputs.remove(self.inputs[-1])

            renames = 'AB'
            for idx, t_in in enumerate(t_inputs):
                s = self.inputs[idx].replace_socket(socket_type.get(t_in),
                                                    renames[idx])
                s.prop_name = f'v3_input_{idx}' if t_in == 'v' else 'amount'

    def process(self):

        self.ensure_enums_have_no_space(enums=["current_op"])

        inputs, outputs = self.inputs, self.outputs

        if not outputs[0].is_linked:
            return

        func = self.implementation_func_dict[self.implementation][0].get(
            self.current_op)[1]
        num_inputs = len(inputs)

        # get either input data, or socket default
        input_one = inputs[0].sv_get(deepcopy=False)

        level = levels_of_list_or_np(input_one) - 1
        if num_inputs == 1:
            recurse_func = self.implementation_func_dict[
                self.implementation][1]
            params = [input_one, func, level]
            # result = recurse_func(input_one, func, level, self.output_numpy)
        else:
            input_two = inputs[1].sv_get(deepcopy=False)
            level = max(level, levels_of_list_or_np(input_two) - 1)
            min_l2_level = 3 if inputs[1].bl_idname == "SvVerticesSocket" else 2
            params = [input_one, input_two, func, level, min_l2_level]
            recurse_func = self.implementation_func_dict[
                self.implementation][2]

        if self.implementation == 'NumPy':
            params.append(self.output_numpy)
        result = recurse_func(*params)
        outputs[0].sv_set(result)
Пример #27
0
class PREFERENCES_OT_addon_install(Operator):
    """Install an add-on"""
    bl_idname = "preferences.addon_install"
    bl_label = "Install Add-on"

    overwrite: BoolProperty(
        name="Overwrite",
        description="Remove existing add-ons with the same ID",
        default=True,
    )
    target: EnumProperty(
        name="Target Path",
        items=(
            ('DEFAULT', "Default", ""),
            ('PREFS', "User Prefs", ""),
        ),
    )

    filepath: StringProperty(
        subtype='FILE_PATH',
    )
    filter_folder: BoolProperty(
        name="Filter folders",
        default=True,
        options={'HIDDEN'},
    )
    filter_python: BoolProperty(
        name="Filter python",
        default=True,
        options={'HIDDEN'},
    )
    filter_glob: StringProperty(
        default="*.py;*.zip",
        options={'HIDDEN'},
    )

    def execute(self, context):
        import addon_utils
        import traceback
        import zipfile
        import shutil
        import os

        pyfile = self.filepath

        if self.target == 'DEFAULT':
            # don't use bpy.utils.script_paths("addons") because we may not be able to write to it.
            path_addons = bpy.utils.user_resource('SCRIPTS', "addons", create=True)
        else:
            path_addons = context.preferences.filepaths.script_directory
            if path_addons:
                path_addons = os.path.join(path_addons, "addons")

        if not path_addons:
            self.report({'ERROR'}, "Failed to get add-ons path")
            return {'CANCELLED'}

        if not os.path.isdir(path_addons):
            try:
                os.makedirs(path_addons, exist_ok=True)
            except:
                traceback.print_exc()

        # Check if we are installing from a target path,
        # doing so causes 2+ addons of same name or when the same from/to
        # location is used, removal of the file!
        addon_path = ""
        pyfile_dir = os.path.dirname(pyfile)
        for addon_path in addon_utils.paths():
            if os.path.samefile(pyfile_dir, addon_path):
                self.report({'ERROR'}, "Source file is in the add-on search path: %r" % addon_path)
                return {'CANCELLED'}
        del addon_path
        del pyfile_dir
        # done checking for exceptional case

        addons_old = {mod.__name__ for mod in addon_utils.modules()}

        # check to see if the file is in compressed format (.zip)
        if zipfile.is_zipfile(pyfile):
            try:
                file_to_extract = zipfile.ZipFile(pyfile, 'r')
            except:
                traceback.print_exc()
                return {'CANCELLED'}

            if self.overwrite:
                for f in file_to_extract.namelist():
                    module_filesystem_remove(path_addons, f)
            else:
                for f in file_to_extract.namelist():
                    path_dest = os.path.join(path_addons, os.path.basename(f))
                    if os.path.exists(path_dest):
                        self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
                        return {'CANCELLED'}

            try:  # extract the file to "addons"
                file_to_extract.extractall(path_addons)
            except:
                traceback.print_exc()
                return {'CANCELLED'}

        else:
            path_dest = os.path.join(path_addons, os.path.basename(pyfile))

            if self.overwrite:
                module_filesystem_remove(path_addons, os.path.basename(pyfile))
            elif os.path.exists(path_dest):
                self.report({'WARNING'}, "File already installed to %r\n" % path_dest)
                return {'CANCELLED'}

            # if not compressed file just copy into the addon path
            try:
                shutil.copyfile(pyfile, path_dest)
            except:
                traceback.print_exc()
                return {'CANCELLED'}

        addons_new = {mod.__name__ for mod in addon_utils.modules()} - addons_old
        addons_new.discard("modules")

        # disable any addons we may have enabled previously and removed.
        # this is unlikely but do just in case. bug [#23978]
        for new_addon in addons_new:
            addon_utils.disable(new_addon, default_set=True)

        # possible the zip contains multiple addons, we could disallow this
        # but for now just use the first
        for mod in addon_utils.modules(refresh=False):
            if mod.__name__ in addons_new:
                info = addon_utils.module_bl_info(mod)

                # show the newly installed addon.
                context.preferences.view.show_addons_enabled_only = False
                context.window_manager.addon_filter = 'All'
                context.window_manager.addon_search = info["name"]
                break

        # in case a new module path was created to install this addon.
        bpy.utils.refresh_script_paths()

        # print message
        msg = (
            tip_("Modules Installed (%s) from %r into %r") %
            (", ".join(sorted(addons_new)), pyfile, path_addons)
        )
        print(msg)
        self.report({'INFO'}, msg)

        return {'FINISHED'}

    def invoke(self, context, _event):
        wm = context.window_manager
        wm.fileselect_add(self)
        return {'RUNNING_MODAL'}
Пример #28
0
class SvScriptNodeLite(bpy.types.Node, SverchCustomTreeNode, SvAnimatableNode):
    ''' snl SN Lite /// a lite version of SN '''

    bl_idname = 'SvScriptNodeLite'
    bl_label = 'Scripted Node Lite'
    bl_icon = 'SCRIPTPLUGINS'

    def custom_enum_func(self, context):
        ND = self.node_dict.get(hash(self))
        if ND:
            enum_list = ND['sockets']['custom_enum']
            if enum_list:
                return [(ce, ce, '', idx) for idx, ce in enumerate(enum_list)]

        return [("A", "A", '', 0), ("B", "B", '', 1)]

    def custom_enum_func_2(self, context):
        ND = self.node_dict.get(hash(self))
        if ND:
            enum_list = ND['sockets']['custom_enum_2']
            if enum_list:
                return [(ce, ce, '', idx) for idx, ce in enumerate(enum_list)]

        return [("A", "A", '', 0), ("B", "B", '', 1)]

    def custom_callback(self, context, operator):
        ND = self.node_dict.get(hash(self))
        if ND:
            ND['sockets']['callbacks'][operator.cb_name](self, context)

    def make_operator(self, new_func_name, force=False):
        ND = self.node_dict.get(hash(self))
        if ND:
            callbacks = ND['sockets']['callbacks']
            if not (new_func_name in callbacks) or force:
                # here node refers to an ast node (a syntax tree node), not a node tree node
                ast_node = self.get_node_from_function_name(new_func_name)
                slice_begin, slice_end = ast_node.body[
                    0].lineno - 1, ast_node.body[-1].lineno
                code = '\n'.join(
                    self.script_str.split('\n')[slice_begin - 1:slice_end + 1])

                exec(code, locals(), locals())
                callbacks[new_func_name] = locals()[new_func_name]

    script_name: StringProperty()
    script_str: StringProperty()
    node_dict = {}

    halt_updates: BoolProperty(name="snlite halting token")

    def updateNode2(self, context):
        if not self.halt_updates:
            updateNode(self, context)

    int_list: IntVectorProperty(name='int_list',
                                description="Integer list",
                                default=defaults,
                                size=32,
                                update=updateNode2)

    float_list: FloatVectorProperty(name='float_list',
                                    description="Float list",
                                    default=defaults,
                                    size=32,
                                    update=updateNode2)

    mode_options = [
        ("To_TextBlok", "To TextBlok", "", 0),
        ("To_Node", "To Node", "", 1),
    ]

    selected_mode: bpy.props.EnumProperty(
        items=mode_options,
        description=
        "load the template directly to the node or add to textblocks",
        default="To_Node",
        update=updateNode)

    inject_params: BoolProperty()
    injected_state: BoolProperty(default=False)
    user_filename: StringProperty(update=updateNode)
    n_id: StringProperty(default='')

    custom_enum: bpy.props.EnumProperty(items=custom_enum_func,
                                        description="custom enum",
                                        update=updateNode)
    custom_enum_2: bpy.props.EnumProperty(items=custom_enum_func_2,
                                          description="custom enum 2",
                                          update=updateNode)

    snlite_raise_exception: BoolProperty(name="raise exception")

    def draw_label(self):
        if self.script_name:
            return 'SN: ' + self.script_name
        else:
            return self.bl_label

    def add_or_update_sockets(self, k, v):
        '''
        'sockets' are either 'self.inputs' or 'self.outputs'
        '''
        sockets = getattr(self, k)

        for idx, (socket_description) in enumerate(v):
            if socket_description is UNPARSABLE:
                print(socket_description, idx, 'was unparsable')
                return

            if len(sockets) > 0 and idx in set(range(len(sockets))):
                if not are_matched(sockets[idx], socket_description):
                    sockets[idx].replace_socket(*socket_description[:2])
            else:
                sockets.new(*socket_description[:2])

        return True

    def add_props_to_sockets(self, socket_info):

        self.id_data.freeze(hard=True)
        try:
            self.halt_updates = True

            for idx, (socket_description) in enumerate(socket_info['inputs']):
                dval = socket_description[2]
                print(idx, socket_description)

                s = self.inputs[idx]

                if isinstance(dval, float):
                    s.prop_type = "float_list"
                    s.prop_index = idx
                    self.float_list[idx] = self.float_list[
                        idx] or dval  # pick up current if not zero

                elif isinstance(dval, int):
                    s.prop_type = "int_list"
                    s.prop_index = idx
                    self.int_list[idx] = self.int_list[idx] or dval
        except:
            print('some failure in the add_props_to_sockets function. ouch.')

        self.halt_updates = False
        self.id_data.unfreeze(hard=True)

    def flush_excess_sockets(self, k, v):
        sockets = getattr(self, k)
        if len(sockets) > len(v):
            num_to_remove = (len(sockets) - len(v))
            for _ in range(num_to_remove):
                sockets.remove(sockets[-1])

    def update_sockets(self):
        socket_info = parse_sockets(self)
        if not socket_info['inputs']:
            return

        for k, v in socket_info.items():
            if not (k in {'inputs', 'outputs'}):
                continue

            if not self.add_or_update_sockets(k, v):
                print('failed to load sockets for ', k)
                return

            self.flush_excess_sockets(k, v)

        self.add_props_to_sockets(socket_info)

        self.node_dict[hash(self)] = {}
        self.node_dict[hash(self)]['sockets'] = socket_info

        return True

    def sv_init(self, context):
        self.use_custom_color = False

    def load(self):
        if not self.script_name:
            return

        text = self.get_bpy_data_from_name(self.script_name, bpy.data.texts)
        if text:
            self.script_str = text.as_string()
        else:
            print(
                f'bpy.data.texts not read yet, self.script_name="{self.script_name}"'
            )
            if self.script_str:
                print('but script loaded locally anyway.')

        if self.update_sockets():
            self.injected_state = False
            self.process()

    def nuke_me(self):
        self.script_str = ''
        self.script_name = ''
        self.node_dict[hash(self)] = {}
        for socket_set in [self.inputs, self.outputs]:
            socket_set.clear()

    def sv_copy(self, node):
        self.node_dict[hash(self)] = {}
        self.load()
        self.n_id = ""

    def process(self):
        if not all([self.script_name, self.script_str]):
            return
        self.process_script()

    def make_new_locals(self):

        # make .blend reload event work, without this the self.node_dict is empty.
        if not self.node_dict:
            # self.load()
            self.injected_state = False
            self.update_sockets()

        # make inputs local, do function with inputs, return outputs if present
        ND = self.node_dict.get(hash(self))
        if not ND:
            print('hash invalidated')
            self.injected_state = False
            self.update_sockets()
            ND = self.node_dict.get(hash(self))
            self.load()

        socket_info = ND['sockets']
        local_dict = {}
        for idx, s in enumerate(self.inputs):
            sock_desc = socket_info['inputs'][idx]

            if s.is_linked:
                val = s.sv_get(default=[[]])
                if sock_desc[3]:
                    val = {0: val, 1: val[0], 2: val[0][0]}.get(sock_desc[3])
            else:
                val = sock_desc[2]
                if isinstance(val, (int, float)):
                    # extra pussyfooting for the load sequence.
                    t = s.sv_get()
                    if t and t[0] and len(t[0]) > 0:
                        val = t[0][0]

            local_dict[s.name] = val

        return local_dict

    def get_node_from_function_name(self, func_name):
        """
        this seems to get enough info for a snlite stateful setup function.

        """
        tree = ast.parse(self.script_str)
        for node in tree.body:
            if isinstance(node, ast.FunctionDef) and node.name == func_name:
                return node

    def get_setup_code(self):
        ast_node = self.get_node_from_function_name('setup')
        if ast_node:
            begin_setup = ast_node.body[0].lineno - 1
            end_setup = ast_node.body[-1].lineno
            code = '\n'.join(
                self.script_str.split('\n')[begin_setup:end_setup])
            return 'def setup():\n\n' + code + '\n    return locals()\n'

    def get_ui_code(self):
        ast_node = self.get_node_from_function_name('ui')
        if ast_node:
            begin_setup = ast_node.body[0].lineno - 1
            end_setup = ast_node.body[-1].lineno
            code = '\n'.join(
                self.script_str.split('\n')[begin_setup:end_setup])
            return 'def ui(self, context, layout):\n\n' + code + '\n\n'

    def inject_state(self, local_variables):
        setup_result = self.get_setup_code()
        if setup_result:
            exec(setup_result, local_variables, local_variables)
            setup_locals = local_variables.get('setup')()
            local_variables.update(setup_locals)
            local_variables['socket_info']['setup_state'] = setup_locals
            self.injected_state = True

    def inject_draw_buttons(self, local_variables):
        draw_ui_result = self.get_ui_code()
        if draw_ui_result:
            exec(draw_ui_result, local_variables, local_variables)
            ui_func = local_variables.get('ui')
            local_variables['socket_info']['drawfunc'] = ui_func

    def process_script(self):
        __local__dict__ = self.make_new_locals()
        locals().update(__local__dict__)
        locals().update({
            'vectorize': vectorize,
            'bpy': bpy,
            'np': np,
            'ddir': ddir,
            'bmesh_from_pydata': bmesh_from_pydata,
            'pydata_from_bmesh': pydata_from_bmesh
        })

        for output in self.outputs:
            locals().update({output.name: []})

        try:
            socket_info = self.node_dict[hash(self)]['sockets']

            # inject once!
            if not self.injected_state:
                self.inject_state(locals())
                self.inject_draw_buttons(locals())
            else:
                locals().update(socket_info['setup_state'])

            if self.inject_params:
                locals().update({
                    'parameters':
                    [__local__dict__.get(s.name) for s in self.inputs]
                })

            exec(self.script_str, locals(), locals())

            for idx, _socket in enumerate(self.outputs):
                vals = locals()[_socket.name]
                self.outputs[idx].sv_set(vals)

            set_autocolor(self, True, READY_COLOR)

        except Exception as err:

            print("Unexpected error:", sys.exc_info()[0])
            exc_type, exc_value, exc_traceback = sys.exc_info()
            lineno = traceback.extract_tb(exc_traceback)[-1][1]
            print('on line: ', lineno)
            show = traceback.print_exception
            show(exc_type, exc_value, exc_traceback, limit=6, file=sys.stdout)
            if hasattr(
                    self,
                    "snlite_raise_exception") and self.snlite_raise_exception:
                raise  #   SNLITE_EXCEPTION(sys.exc_info()[2]) from err

    def custom_draw(self, context, layout):
        tk = self.node_dict.get(hash(self))
        if not tk or not tk.get('sockets'):
            return

        snlite_info = tk['sockets']
        if snlite_info:

            # snlite supplied custom file handler solution
            fh = snlite_info.get('display_file_handler')
            if fh:
                layout.prop_search(self,
                                   'user_filename',
                                   bpy.data,
                                   'texts',
                                   text='filename')

            # user supplied custom draw function
            f = snlite_info.get('drawfunc')
            if f:
                f(self, context, layout)

    def draw_buttons(self, context, layout):
        sn_callback = 'node.scriptlite_ui_callback'

        if not self.script_str:
            col = layout.column(align=True)
            row = col.row()
            row.prop_search(self,
                            'script_name',
                            bpy.data,
                            'texts',
                            text='',
                            icon='TEXT')
            row.operator(sn_callback, text='', icon='PLUGIN').fn_name = 'load'
        else:
            self.draw_animatable_buttons(layout, icon_only=True)
            col = layout.column(align=True)
            row = col.row()
            row.operator(sn_callback, text='Reload').fn_name = 'load'
            row.operator(sn_callback, text='Clear').fn_name = 'nuke_me'

        self.custom_draw(context, layout)

    def draw_buttons_ext(self, _, layout):
        row = layout.row()
        row.prop(self, 'selected_mode', expand=True)
        col = layout.column()
        col.menu(SV_MT_ScriptNodeLitePyMenu.bl_idname)

        box = layout.box()
        r = box.row()
        r.label(text="extra snlite features")
        if hasattr(self, "snlite_raise_exception"):
            r = box.row()
            r.prop(self,
                   "snlite_raise_exception",
                   toggle=True,
                   text="raise errors to tree level")

    # ---- IO Json storage is handled in this node locally ----

    def storage_set_data(self, node_ref):

        texts = bpy.data.texts

        data_list = node_ref.get('snlite_ui')
        if data_list:
            # self.node_dict[hash(self)]['sockets']['snlite_ui'] = ui_elements
            for data_json_str in data_list:
                data_dict = json.loads(data_json_str)
                if data_dict['bl_idname'] == 'ShaderNodeRGBCurve':
                    set_rgb_curve(data_dict)

        includes = node_ref.get('includes')
        if includes:
            for include_name, include_content in includes.items():
                new_text = texts.new(include_name)
                new_text.from_string(include_content)

                if include_name == new_text.name:
                    continue

                print('| in', node_ref.name, 'the importer encountered')
                print('| an include called', include_name, '. While trying')
                print('| to write this file to bpy.data.texts another file')
                print('| with the same name was encountered. The importer')
                print('| automatically made a datablock called', new_text.name)

    def storage_get_data(self, node_dict):

        # this check and function call is needed to allow loading node trees directly
        # from a .blend in order to export them via create_dict_of_tree
        if not self.node_dict or not self.node_dict.get(hash(self)):
            self.make_new_locals()

        storage = self.node_dict[hash(self)]['sockets']

        ui_info = storage['snlite_ui']
        node_dict['snlite_ui'] = []
        print(ui_info)
        for _, info in enumerate(ui_info):
            mat_name = info['mat_name']
            node_name = info['node_name']
            bl_idname = info['bl_idname']
            if bl_idname == 'ShaderNodeRGBCurve':
                data = get_rgb_curve(mat_name, node_name)
                print(data)
                data_json_str = json.dumps(data)
                node_dict['snlite_ui'].append(data_json_str)

        includes = storage['includes']
        if includes:
            node_dict['includes'] = {}
            for k, v in includes.items():
                node_dict['includes'][k] = v
Пример #29
0
class PREFERENCES_OT_studiolight_install(Operator):
    """Install a user defined studio light"""
    bl_idname = "preferences.studiolight_install"
    bl_label = "Install Custom Studio Light"

    files: CollectionProperty(
        name="File Path",
        type=OperatorFileListElement,
    )
    directory: StringProperty(
        subtype='DIR_PATH',
    )
    filter_folder: BoolProperty(
        name="Filter folders",
        default=True,
        options={'HIDDEN'},
    )
    filter_glob: StringProperty(
        default="*.png;*.jpg;*.hdr;*.exr",
        options={'HIDDEN'},
    )
    type: EnumProperty(
        items=(
            ('MATCAP', "MatCap", ""),
            ('WORLD', "World", ""),
            ('STUDIO', "Studio", ""),
        )
    )

    def execute(self, context):
        import os
        import shutil
        prefs = context.preferences

        path_studiolights = os.path.join("studiolights", self.type.lower())
        path_studiolights = bpy.utils.user_resource('DATAFILES', path_studiolights, create=True)
        if not path_studiolights:
            self.report({'ERROR'}, "Failed to create Studio Light path")
            return {'CANCELLED'}

        for e in self.files:
            shutil.copy(os.path.join(self.directory, e.name), path_studiolights)
            prefs.studio_lights.load(os.path.join(path_studiolights, e.name), self.type)

        # print message
        msg = (
            tip_("StudioLight Installed %r into %r") %
            (", ".join(e.name for e in self.files), path_studiolights)
        )
        print(msg)
        self.report({'INFO'}, msg)
        return {'FINISHED'}

    def invoke(self, context, _event):
        wm = context.window_manager

        if self.type == 'STUDIO':
            self.filter_glob = "*.sl"

        wm.fileselect_add(self)
        return {'RUNNING_MODAL'}
Пример #30
0
class AddTextToStorageVars(PropertyGroup):
    tags: StringProperty(name='Tags (comma separated)',
                         description='Add some tags to describe this text',
                         default='')