Esempio n. 1
0
class SelectPattern(Operator):
    '''Select object matching a naming pattern'''
    bl_idname = "object.select_pattern"
    bl_label = "Select Pattern"
    bl_options = {'REGISTER', 'UNDO'}

    pattern = StringProperty(
            name="Pattern",
            description="Name filter using '*' and '?' wildcard chars",
            maxlen=32,
            default="*",
            )
    case_sensitive = BoolProperty(
            name="Case Sensitive",
            description="Do a case sensitive compare",
            default=False,
            )
    extend = BoolProperty(
            name="Extend",
            description="Extend the existing selection",
            default=True,
            )

    def execute(self, context):

        import fnmatch

        if self.case_sensitive:
            pattern_match = fnmatch.fnmatchcase
        else:
            pattern_match = (lambda a, b:
                             fnmatch.fnmatchcase(a.upper(), b.upper()))
        is_ebone = False
        obj = context.object
        if obj and obj.mode == 'POSE':
            items = obj.data.bones
            if not self.extend:
                bpy.ops.pose.select_all(action='DESELECT')
        elif obj and obj.type == 'ARMATURE' and obj.mode == 'EDIT':
            items = obj.data.edit_bones
            if not self.extend:
                bpy.ops.armature.select_all(action='DESELECT')
            is_ebone = True
        else:
            items = context.visible_objects
            if not self.extend:
                bpy.ops.object.select_all(action='DESELECT')

        # Can be pose bones or objects
        for item in items:
            if pattern_match(item.name, self.pattern):
                item.select = True

                # hrmf, perhaps there should be a utility function for this.
                if is_ebone:
                    item.select_head = True
                    item.select_tail = True
                    if item.use_connect:
                        item_parent = item.parent
                        if item_parent is not None:
                            item_parent.select_tail = True

        return {'FINISHED'}

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_popup(self, event)

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

        layout.prop(self, "pattern")
        row = layout.row()
        row.prop(self, "case_sensitive")
        row.prop(self, "extend")
Esempio n. 2
0
def register():
    bpy.utils.register_module(__name__)
    wm = bpy.types.WindowManager

    # Project
    wm.flamenco_project = EnumProperty(items=project_list,
                                       name="Projects",
                                       description="Flamenco Projects")
    wm.flamenco_projectCache = StringProperty(name="Project list cache",
                                              default="",
                                              options={'HIDDEN', 'SKIP_SAVE'})
    # Job Name
    wm.flamenco_jobName = StringProperty(name="Job Name",
                                         default="",
                                         options={'HIDDEN', 'SKIP_SAVE'})
    # Job Type
    wm.flamenco_jobType = EnumProperty(items=jobType_list,
                                       name="Job type",
                                       description="Type of job available")
    # File Format
    wm.flamenco_file_format = EnumProperty(
        items=[('EXR', 'EXR', ''), ('JPEG', 'JPEG', ''), ('PNG', 'PNG', ''),
               ('JPEG2000', 'JPEG2000', '')],
        name="File Format",
        description="Output file format for the job")
    # Chunk Size
    wm.flamenco_chunkSize = IntProperty(
        name="Chunk Size",
        description="Number of chunks in which the render will be divided.",
        default=5,
        soft_min=1,
        options={'HIDDEN', 'SKIP_SAVE'})
    # Managers
    wm.flamenco_managers = CollectionProperty(type=flamencoManagers,
                                              name="Managers",
                                              description="Flamenco Managers")
    wm.flamenco_managersIndex = IntProperty(
        name="Manager Index",
        description="Currently selected Flamenco Manager")
    # Command (Blender Version)
    wm.flamenco_command = EnumProperty(items=command_names,
                                       name="Command",
                                       description="Flamenco Command")
    # Priority
    wm.flamenco_priority = IntProperty(
        name="Priority",
        description=
        "A value between 0 and 100. The closer to 100, the higher the priority.",
        default=50,
        soft_min=0,
        soft_max=100,
        options={'HIDDEN', 'SKIP_SAVE'})
    # Start Job
    wm.flamenco_startJob = BoolProperty(
        name="Start Job",
        description=
        "As soon the file is sent to the server, the job will be started.",
        options={'HIDDEN', 'SKIP_SAVE'})
    # Send Packed file
    wm.flamenco_submit_archive = BoolProperty(
        name="Send Packed File",
        description=
        "If unchecked, the file will be BAM packed, but not sent to the server. \
This will have to be done by hand.",
        options={'HIDDEN', 'SKIP_SAVE'},
        default=True)
    # Pack Alembic Caches
    wm.flamenco_pack_alembic_caches = BoolProperty(
        name="Pack Alembic Caches",
        description="If checked, .abc caches will be added to the bam archive. \
This can generate very large files.",
        options={'HIDDEN', 'SKIP_SAVE'},
        default=False)
    # Pack EXR files
    wm.flamenco_pack_exr_sequences = BoolProperty(
        name="Pack EXR sequences",
        description=
        "If checked, .exr image sequences will be included in the bam archive. \
This can generate very large files.",
        options={'HIDDEN', 'SKIP_SAVE'},
        default=False)
    # Pack movie files
    wm.flamenco_pack_movie_files = BoolProperty(
        name="Pack movie files",
        description=
        "If checked, .mov and .avi files will be included in the bam archive. \
This can generate very large files.",
        options={'HIDDEN', 'SKIP_SAVE'},
        default=False)
    # Pack movie files
    wm.flamenco_pack_audio_files = BoolProperty(
        name="Pack audio files",
        description=
        "If checked, .wav and .mp3 files will be included in the bam archive. \
    This can generate very large files.",
        options={'HIDDEN', 'SKIP_SAVE'},
        default=False)

    wm.flamenco_settingsServer = CollectionProperty(
        type=flamencoSettingsServer,
        name="Server Settings",
        description="Server Settings")
    wm.flamenco_settingsServerIndex = IntProperty(
        name="Server Setting Index",
        description="Currently selected Flamenco Server Setting")
    wm.flamenco_settingsManagers = CollectionProperty(
        type=flamencoSettingsManagers,
        name="Managers Settings",
        description="Managers Settings")
    wm.flamenco_settingsManagerIndex = IntProperty(
        name="Manager Setting Index",
        description="Currently selected Flamenco Manager Setting")
Esempio n. 3
0
class SvPointInside(bpy.types.Node, SverchCustomTreeNode):
    """
    Triggers: Mask verts with geom
    Tooltip:  Mask points inside geometry in 2D or 3D
    """
    bl_idname = 'SvPointInside'
    bl_label = 'Points Inside Mesh'
    sv_icon = 'SV_POINTS_INSIDE_MESH'

    mode_options = [
        (k[0], k[1], '', i)
        for i, k in enumerate([("algo_1", "Regular"), ("algo_2",
                                                       "Multisample")])
    ]
    dimension_options = [(k, k, '', i) for i, k in enumerate(["2D", "3D"])]

    def update_sockets(self, context):
        if self.dimensions_mode == '2D' and len(self.inputs) < 4:
            self.inputs.new('SvVerticesSocket',
                            'Plane Normal').prop_name = 'normal'
        elif self.dimensions_mode == '3D' and len(self.inputs) > 3:
            self.inputs.remove(self.inputs['Plane Normal'])
        if self.dimensions_mode == '2D' and self.limit_max_dist and len(
                self.inputs) < 5:
            self.inputs.new('SvStringsSocket',
                            'Max Dist').prop_name = 'max_dist'
        elif self.dimensions_mode == '3D' or not self.limit_max_dist:
            if 'Max Dist' in self.inputs:
                self.inputs.remove(self.inputs['Max Dist'])
        updateNode(self, context)

    dimensions_mode: EnumProperty(
        items=dimension_options,
        description="offers different approaches to finding internal points",
        default="3D",
        update=update_sockets)

    normal: FloatVectorProperty(name='Normal',
                                description='Plane Normal',
                                size=3,
                                default=(0, 0, 1),
                                update=updateNode)

    max_dist: FloatProperty(name='Max Distance',
                            description='Maximum valid distance',
                            default=10.0,
                            update=updateNode)

    limit_max_dist: BoolProperty(name='Limit Projection',
                                 description='Limit projection distance',
                                 default=False,
                                 update=update_sockets)

    selected_algo: EnumProperty(
        items=mode_options,
        description="offers different approaches to finding internal points",
        default="algo_1",
        update=updateNode)

    epsilon_bvh: FloatProperty(name='Tolerance',
                               description='fudge value',
                               default=0.0,
                               min=0.0,
                               max=1.0,
                               update=updateNode)

    num_samples: IntProperty(name='Samples Num',
                             description='Number of rays to cast',
                             min=1,
                             max=6,
                             default=3,
                             update=updateNode)

    list_match_global: EnumProperty(
        name="Match Global",
        description=
        "Behavior on different list lengths, multiple objects level",
        items=list_match_modes,
        default="REPEAT",
        update=updateNode)

    list_match_local: EnumProperty(
        name="Match Local",
        description=
        "Behavior on different list lengths, between Normal and Max Distance",
        items=list_match_modes,
        default="REPEAT",
        update=updateNode)

    def sv_init(self, context):
        self.width = 160
        self.inputs.new('SvVerticesSocket', 'verts')
        self.inputs.new('SvStringsSocket', 'faces')
        self.inputs.new('SvVerticesSocket', 'points')
        self.outputs.new('SvStringsSocket', 'mask')
        # self.outputs.new('SvVerticesSocket', 'Inside Vertices') # to be used in MK2
        s = self.outputs.new('SvVerticesSocket',
                             'verts')  # to be removed in MK2
        s.label = "Inside Vertices"  # to be removed in MK2
        self.outputs.new('SvVerticesSocket', 'Outside Vertices')
        self.update_sockets(context)

    def draw_buttons(self, context, layout):
        layout.prop(self, 'dimensions_mode', expand=True)
        if self.dimensions_mode == '2D':
            layout.prop(self, 'limit_max_dist', expand=True)
        else:
            layout.prop(self, 'selected_algo', expand=True)
            if self.selected_algo == 'algo 2':
                layout.prop(self, 'epsilon_bvh', text='Epsilon')
                layout.prop(self, 'num_samples', text='Samples')

    def draw_buttons_ext(self, context, layout):
        self.draw_buttons(context, layout)
        layout.prop(self, 'list_match_global', text='Global Match')
        if self.dimensions_mode == '2D' and self.limit_max_dist:
            layout.prop(self, 'list_match_local', text='Local Match')

    def rclick_menu(self, context, layout):
        '''right click sv_menu items'''
        layout.prop_menu_enum(self,
                              "list_match_global",
                              text="List Match Global")
        if self.dimensions_mode == '2D' and self.limit_max_dist:
            layout.prop_menu_enum(self,
                                  "list_match_local",
                                  text="List Match Local")

    def get_data(self):
        # general parameters
        params = [s.sv_get() for s in self.inputs[:3]]
        # special parameters
        if self.dimensions_mode == '2D':
            params.append(self.inputs['Plane Normal'].sv_get(default=[[]]))
            if self.limit_max_dist:
                params.append(self.inputs['Max Dist'].sv_get(default=[[]]))

        match_func = list_match_func[self.list_match_global]
        params = match_func(params)
        # general options
        params.append(cycle([self.epsilon_bvh]))
        # special options and main_func

        if self.dimensions_mode == '3D':
            if self.selected_algo == 'algo_1':
                main_func = are_inside
            elif self.selected_algo == 'algo_2':
                params.append(cycle([self.num_samples]))
                main_func = get_points_in_mesh
        else:
            if self.limit_max_dist:
                params.append(cycle([self.list_match_local]))
                main_func = get_points_in_mesh_2D_clip
            else:
                main_func = get_points_in_mesh_2D

        return main_func, params

    def process(self):

        if not all(socket.is_linked for socket in self.inputs[:3]):
            return

        main_func, params = self.get_data()

        mask = []
        for par in zip(*params):
            mask.append(main_func(*par))

        self.outputs['mask'].sv_set(mask)

        if self.outputs['verts'].is_linked:
            # if self.outputs['Inside Vertices'].is_linked: # to be used in MK2
            verts = []
            for masked, pts_in in zip(mask, params[2]):
                verts.append([p for m, p in zip(masked, pts_in) if m])
            self.outputs['verts'].sv_set(verts)  # to be removed in MK2
            # self.outputs['Inside Vertices'].sv_set(verts) # to be used in MK2

        if 'Outside Vertices' in self.outputs:  # to be removed in MK2
            if self.outputs['Outside Vertices'].is_linked:
                verts = []
                for masked, pts_in in zip(mask, params[2]):
                    verts.append([p for m, p in zip(masked, pts_in) if not m])
                self.outputs['Outside Vertices'].sv_set(verts)
Esempio n. 4
0
class SvLogicNode(bpy.types.Node, SverchCustomTreeNode):
    '''And, Or, If, <, >..'''
    bl_idname = 'SvLogicNode'
    bl_label = 'Logic functions'
    bl_icon = 'NONE'  #'LOGIC'
    sv_icon = 'SV_LOGIC'

    def change_type(self, context):
        signature = func_dict[self.items_][2]
        self.set_inputs(len(signature))
        props_names = ['x', 'y']
        for socket, t, n, i in zip(self.inputs, signature, props_names,
                                   [0, 1]):
            if t == 'f':
                socket.prop_name = 'i_' + n
                self.prop_types[i] = True
            else:
                socket.prop_name = n
                self.prop_types[i] = False
        updateNode(self, context)

    def set_inputs(self, num_inputs):
        if num_inputs == len(self.inputs):
            return
        if num_inputs < len(self.inputs):
            while num_inputs < len(self.inputs):
                self.inputs.remove(self.inputs[-1])
        if num_inputs > len(self.inputs):
            if 'X' not in self.inputs:
                self.inputs.new('SvStringsSocket', "X")
            if 'Y' not in self.inputs and num_inputs == 2:
                self.inputs.new('SvStringsSocket', "Y")
            self.change_prop_type(None)

    constant = {
        'FALSE': False,
        'TRUE': True,
    }

    x: IntProperty(default=1, name='x', update=updateNode)
    y: IntProperty(default=1, name='y', update=updateNode)

    i_x: FloatProperty(default=1, name='x', update=updateNode)
    i_y: FloatProperty(default=1, name='y', update=updateNode)

    items_: EnumProperty(name="Logic Gate",
                         description="Logic Gate choice",
                         default="AND",
                         items=mode_items,
                         update=change_type)

    # boolvector to control prop type
    def change_prop_type(self, context):
        inputs = self.inputs
        if inputs:
            inputs[0].prop_name = 'i_x' if self.prop_types[0] else 'x'
        if len(inputs) > 1:
            inputs[1].prop_name = 'i_y' if self.prop_types[1] else 'y'

    prop_types: BoolVectorProperty(size=2,
                                   default=(False, False),
                                   update=change_prop_type)

    list_match: EnumProperty(name="List Match",
                             description="Behavior on different list lengths",
                             items=numpy_list_match_modes,
                             default="REPEAT",
                             update=updateNode)

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

    def draw_buttons(self, context, layout):
        layout.prop(self, "items_", text="Functions:")

    def draw_buttons_ext(self, context, layout):
        layout.prop(self, "items_", text="Functions:")
        layout.label(text="Change property type")
        for i, socket in enumerate(self.inputs):
            row = layout.row()
            row.label(text=socket.name)
            txt = "To int" if self.prop_types[i] else "To float"
            row.prop(self, "prop_types", index=i, text=txt, toggle=True)
        layout.row().prop(self, 'list_match', expand=False)
        layout.prop(self, "output_numpy", text="Output NumPy")

    def rclick_menu(self, context, layout):
        layout.prop_menu_enum(self, "items_", text="Function:")
        layout.prop_menu_enum(self, "list_match", text="List Match")
        layout.prop(self, "output_numpy", expand=False)

    def sv_init(self, context):
        self.inputs.new('SvStringsSocket', "X").prop_name = 'x'
        self.inputs.new('SvStringsSocket', "Y").prop_name = 'y'
        self.outputs.new('SvStringsSocket', "Gate")

    def draw_label(self):

        num_inputs = len(self.inputs)
        label = [self.items_]

        if num_inputs:
            x_val = self.i_x if self.prop_types[0] else self.x
            x_label = 'X' if self.inputs[0].links else str(round(x_val, 3))
            label.append(x_label)

        if num_inputs == 2:
            y_val = self.i_y if self.prop_types[1] else self.y
            y_label = 'Y' if self.inputs[1].links else str(round(y_val, 3))
            label.extend((", ", y_label))
        return " ".join(label)

    def process(self):

        if not self.outputs['Gate'].is_linked:
            return

        if self.items_ in self.constant:
            result = [[self.constant[self.items_]]]
        else:
            current_func = func_from_mode(self.items_)
            params = [
                si.sv_get(default=[[]], deepcopy=False) for si in self.inputs
            ]
            matching_f = list_match_func[self.list_match]
            desired_levels = [2 for p in params]
            ops = [current_func, self.list_match, self.output_numpy]
            result = recurse_f_level_control(params, ops, logic_numpy,
                                             matching_f, desired_levels)

        self.outputs[0].sv_set(result)
Esempio n. 5
0
class SvListStatisticsNode(bpy.types.Node, SverchCustomTreeNode):
    '''
    Triggers: Sum, Avg, Min, Max
    Tooltip: Statistical quantities: sum, average, standard deviation, min, max, product...
    '''
    bl_idname = 'SvListStatisticsNode'
    bl_label = 'List Statistics'
    bl_icon = 'OUTLINER_OB_EMPTY'
    sv_icon = 'SV_LIST_STADISTICS'

    def update_function(self, context):
        if self.function == "ALL STATISTICS":
            self.inputs["Percentage"].hide_safe = False
            self.inputs["Bins"].hide_safe = False
            self.inputs["Size"].hide_safe = not self.normalize
            self.outputs[0].name = "Names"
            self.outputs[1].name = "Values"
        else:
            for name in ["Percentage", "Bins", "Size"]:
                self.inputs[name].hide_safe = True
            if self.function == "PERCENTILE":
                self.inputs["Percentage"].hide_safe = False
            elif self.function == "HISTOGRAM":
                self.inputs["Bins"].hide_safe = False
                self.inputs["Size"].hide_safe = not self.normalize

            self.outputs[0].name = "Name"
            self.outputs[1].name = "Value"

        updateNode(self, context)

    def update_normalize(self, context):
        socket = self.inputs["Size"]
        socket.hide_safe = not self.normalize

        updateNode(self, context)

    mode: EnumProperty(name="Mode",
                       items=modeItems,
                       default="FLOAT",
                       update=updateNode)

    function: EnumProperty(name="Function",
                           items=functionItems,
                           update=update_function)

    percentage: FloatProperty(name="Percentage",
                              default=0.75,
                              min=0.0,
                              max=1.0,
                              update=updateNode)

    bins: IntProperty(name="Bins", default=10, min=1, update=updateNode)

    normalize: BoolProperty(
        name="Normalize",
        description="Normalize the bins to a normalize size",
        default=False,
        update=update_normalize)

    normalized_size: FloatProperty(
        name="Size",
        description="The normalized size of the bins",
        default=10.0,
        update=updateNode)

    def draw_buttons(self, context, layout):
        layout.prop(self, "mode", expand=True)
        layout.prop(self, "function", text="")
        if self.function in ["HISTOGRAM", "ALL STATISTICS"]:
            layout.prop(self, "normalize", toggle=True)

    def sv_init(self, context):
        self.width = 150
        self.inputs.new('SvStringsSocket', "Data")
        self.inputs.new('SvStringsSocket',
                        "Percentage").prop_name = "percentage"
        self.inputs.new('SvStringsSocket', "Bins").prop_name = "bins"
        self.inputs.new('SvStringsSocket',
                        "Size").prop_name = "normalized_size"
        self.outputs.new('SvStringsSocket', "Names")
        self.outputs.new('SvStringsSocket', "Values")
        self.function = "AVERAGE"

    def get_statistics_function(self):
        return functions[self.function][1]

    def process(self):
        outputs = self.outputs
        # return if no outputs are connected
        if not any(s.is_linked for s in outputs):
            return

        inputs = self.inputs
        input_D = inputs["Data"].sv_get()
        input_P = inputs["Percentage"].sv_get()[0]
        input_B = inputs["Bins"].sv_get()[0]
        input_S = inputs["Size"].sv_get()[0]

        # sanitize the inputs
        input_P = list(map(lambda x: max(0, min(1, x)), input_P))
        input_B = list(map(lambda x: max(1, x), input_B))

        if self.mode == "INT":
            input_P = list(map(lambda x: int(x), input_P))

        if self.function == "ALL STATISTICS":
            functionNames = [fn[0] for fn in functionItems[1:]]
        else:
            functionNames = [self.function]

        params = match_long_repeat([input_D, input_P, input_B, input_S])

        allNames = []
        allValues = []
        for functionName in functionNames:
            statistics_function = functions[functionName][1]
            quantityList = []
            for d, p, b, s in zip(*params):
                if functionName == "PERCENTILE":
                    quantity = statistics_function(d, p)
                elif functionName == "HISTOGRAM":
                    quantity = statistics_function(d, b, self.normalize, s)
                else:
                    quantity = statistics_function(d)

                if functionName != "HISTOGRAM":
                    if self.mode == "INT":
                        quantity = int(quantity)

                quantityList.append(quantity)

            allNames.append(functionName)
            allValues.append(quantityList)

        outputs[0].sv_set(allNames)
        outputs[1].sv_set(allValues)
Esempio n. 6
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)
Esempio n. 7
0
class ExportAppleseedScene(bpy.types.Operator, ExportHelper):
    """
    Export the scene to an appleseed project on disk.
    """

    bl_idname = "appleseed.export_scene"
    bl_label = "Export appleseed Scene"
    bl_options = {'PRESET'}

    filename_ext = ".appleseed"
    filter_glob = StringProperty(default="*.appleseed", options={'HIDDEN'})

    # Properties.

    animation = BoolProperty(
        name="Animation",
        description="Write out an appleseed project for each frame",
        default=False)

    # selected_only = BoolProperty(name="Selection Only", description="Export selected objects only", default=False)
    # packed = BoolProperty(name="Pack Project", description="Export packed projects", default=False)

    @classmethod
    def poll(cls, context):
        renderer = context.scene.render
        return renderer.engine == 'APPLESEED_RENDER'

    def execute(self, context):
        export_path = util.realpath(self.filepath)

        scene = context.scene

        if self.animation:

            if not '#' in export_path:
                self.report({
                    'ERROR'
                }, 'Exporting animation but project filename has no # frame placeholders.'
                            )
                return {'CANCELLED'}

            replacements = [('######', "%06d"), ('#####', "%05d"),
                            ('####', "%04d"), ('###', "%03d"), ('##', "%02d"),
                            ('#', "%d")]

            for i in replacements:
                if i[0] in export_path:
                    export_path = export_path.replace(i[0], i[1])
                    break

            frame_start = scene.frame_start
            frame_end = scene.frame_end

            for frame in range(frame_start, frame_end + 1):
                scene.frame_set(frame)
                proj_filename = export_path % frame
                self.__export_project(context, proj_filename)

        else:
            self.__export_project(context, export_path)

        return {'FINISHED'}

    def __export_project(self, context, export_path):
        scene_translator = SceneTranslator.create_project_export_translator(
            context.scene, export_path)
        scene_translator.translate_scene()
        scene_translator.write_project(export_path)
class PointImportProperties():
    """ This class encapsulates Blender UI properties that are required to visualize the reconstructed points correctly. """
    import_points: BoolProperty(
        name="Import Points",
        description = "Import Points", 
        default=True)
    draw_points_with_gpu : BoolProperty(
       name="Draw Points in the 3D View with OpenGL.",
        description="Draw Points in the 3D View. Allows to visualize point clouds with many elements. These are not visible in eevee/cycles renderings.",
        default=False)
    add_points_as_particle_system: BoolProperty(
        name="Add Points as Particle System",
        description="Use a particle system to represent vertex positions with objects. Can be rendered with eevee/cycles.",
        default=True)
    mesh_items = [
        ("CUBE", "Cube", "", 1),
        ("SPHERE", "Sphere", "", 2),
        ("PLANE", "Plane", "", 3)
        ]
    mesh_type: EnumProperty(
        name="Mesh Type",
        description = "Select the vertex representation mesh type.", 
        items=mesh_items)
    point_extent: FloatProperty(
        name="Initial Point Extent (in Blender Units)", 
        description = "Initial Point Extent for meshes at vertex positions",
        default=0.01)
    add_particle_color_emission: BoolProperty(
        name="Add Particle Color Emission",
        description = "Add particle color emission to increase the visibility of the individual objects of the particle system.", 
        default=True)
    set_particle_color_flag: BoolProperty(
        name="Set Fixed Particle Color",
        description="Overwrite the colors in the file with a single color.", 
        default=False
    )
    particle_overwrite_color: FloatVectorProperty(
        name="Particle Color",
        description="Single fixed particle color.", 
        default=(0.0, 1.0, 0.0),
        min=0.0,
        max=1.0
    )

    def draw_point_options(self, layout):
        point_box = layout.box()
        point_box.prop(self, "import_points")
        if self.import_points:
            particle_box = point_box.box()
            particle_box.prop(self, "draw_points_with_gpu")
            particle_box.prop(self, "add_points_as_particle_system")
            if self.add_points_as_particle_system:
                particle_box.prop(self, "mesh_type")
                particle_box.prop(self, "add_particle_color_emission")
                particle_box.prop(self, "point_extent")
                particle_box.prop(self, "set_particle_color_flag")
                if self.set_particle_color_flag:
                    particle_box.prop(self, "particle_overwrite_color")
                    

    def import_photogrammetry_points(self, points, reconstruction_collection, transformations_sorted=None):
        if self.import_points:

            if self.draw_points_with_gpu:
                from photogrammetry_importer.utils.visualization_utils import draw_points
                draw_points(self, points)

            point_cloud_obj_name = add_points_as_mesh(
                self, 
                points, 
                self.add_points_as_particle_system, 
                self.mesh_type, 
                self.point_extent,
                self.add_particle_color_emission,
                reconstruction_collection,
                self.set_particle_color_flag,
                self.particle_overwrite_color) 

            if transformations_sorted is not None:
                add_transformation_animation(
                    self,
                    point_cloud_obj_name,
                    transformations_sorted, 
                    number_interpolation_frames=1, 
                    interpolation_type=None,
                    remove_rotation_discontinuities=False)
Esempio n. 9
0
class WScrewData(bpy.types.PropertyGroup):
    rounds = IntProperty(
        name="Rounds",
        description="Iterations of the screw",
        default=5,
        min=1,
        soft_min=1,
        set = setRounds,
        get = getRounds
    )

    segments = IntProperty(
        name="Segments",
        description="Perimetr segments",
        default=12,
        min=3,
        soft_min=3,
        set = setSegments,
        get = getSegments
    )

    height = FloatProperty(
        name="Height",
        description="Height of the screw",
        default=2.0,
        min=0.0,
        soft_min=0.0,
        step=1,
        precision=2,
        unit='LENGTH',
        set = setHeight,
        get = getHeigh
    )

    radius_1 = FloatProperty(
        name="Major",
        description="Major radius",
        default=0.5,
        min=0.0,
        soft_min=0.0,
        step=1,
        unit='LENGTH',
        set = setRadius_1,
        get = getRadius_1
    )

    radius_2 = FloatProperty(
        name="Minor",
        description="Minor radius",
        default=0.6,
        min=0.0,
        soft_min=0.0,
        step=1,
        unit='LENGTH',
        set = setRadius_2,
        get = getRadius_2
    )

    smoothed = BoolProperty(
        name="Smooth",
        description="Smooth shading",
        default=True,
        set = setSmoothed,
        get = getSmoothed
    )
Esempio n. 10
0
class PDTSceneProperties(PropertyGroup):
    """Contains all PDT related properties."""

    pdt_library_path: StringProperty(
        name="Library",
        default="",
        description="Parts Library File",
        maxlen=1024,
        subtype="FILE_PATH",
    )

    object_search_string: StringProperty(name="Search",
                                         default="",
                                         description=PDT_DES_LIBSER)
    collection_search_string: StringProperty(name="Search",
                                             default="",
                                             description=PDT_DES_LIBSER)
    material_search_string: StringProperty(name="Search",
                                           default="",
                                           description=PDT_DES_LIBSER)

    cartesian_coords: FloatVectorProperty(name="Coords",
                                          default=(0.0, 0.0, 0.0),
                                          subtype="XYZ",
                                          description=PDT_DES_COORDS)
    distance: FloatProperty(name="Distance",
                            default=0.0,
                            precision=5,
                            description=PDT_DES_OFFDIS,
                            unit="LENGTH")
    angle: FloatProperty(name="Angle",
                         min=-180,
                         max=180,
                         default=0.0,
                         precision=5,
                         description=PDT_DES_OFFANG)
    percent: FloatProperty(name="Percent",
                           default=0.0,
                           precision=5,
                           description=PDT_DES_OFFPER)
    plane: EnumProperty(
        items=(
            ("XZ", "Front(X-Z)", "Use X-Z Plane"),
            ("XY", "Top(X-Y)", "Use X-Y Plane"),
            ("YZ", "Right(Y-Z)", "Use Y-Z Plane"),
            ("LO", "View", "Use View Plane"),
        ),
        name="Working Plane",
        default="XZ",
        description=PDT_DES_WORPLANE,
    )
    select: EnumProperty(
        items=(
            ("REL", "Current Pos.", "Move Relative to Current Position"),
            (
                "SEL",
                "Selected Entities",
                "Move Relative to Selected Object or Vertex (Cursor & Pivot Only)",
            ),
        ),
        name="Move Mode",
        default="SEL",
        description=PDT_DES_MOVESEL,
    )
    operation: EnumProperty(
        items=(
            ("CU", "Move Cursor", "This function will Move the Cursor"),
            ("PP", "Move Pivot Point",
             "This function will Move the Pivot Point"),
            ("MV", "Move Entities",
             "This function will Move selected Vertices or Objects"),
            ("NV", "Add New Vertex", "This function will Add a New Vertex"),
            (
                "EV",
                "Extrude Vertex/Vertices",
                "This function will Extrude Vertex/Vertices Only in EDIT Mode",
            ),
            ("SE", "Split Edges",
             "This function will Split Edges Only in EDIT Mode"),
            (
                "DG",
                "Duplicate Geometry",
                "This function will Duplicate Geometry in EDIT Mode (Delta & Direction Only)",
            ),
            (
                "EG",
                "Extrude Geometry",
                "This function will Extrude Geometry in EDIT Mode (Delta & Direction Only)",
            ),
        ),
        name="Operation",
        default="CU",
        description=PDT_DES_OPMODE,
    )
    taper: EnumProperty(
        items=(
            ("RX-MY", "RotX-MovY", "Rotate X - Move Y"),
            ("RX-MZ", "RotX-MovZ", "Rotate X - Move Z"),
            ("RY-MX", "RotY-MovX", "Rotate Y - Move X"),
            ("RY-MZ", "RotY-MovZ", "Rotate Y - Move Z"),
            ("RZ-MX", "RotZ-MovX", "Rotate Z - Move X"),
            ("RZ-MY", "RotZ-MovY", "Rotate Z - Move Y"),
        ),
        name="Axes",
        default="RX-MY",
        description=PDT_DES_ROTMOVAX,
    )

    flip_angle: BoolProperty(name="Flip Angle",
                             default=False,
                             description=PDT_DES_FLIPANG)
    flip_percent: BoolProperty(name="Flip %",
                               default=False,
                               description=PDT_DES_FLIPPER)

    extend: BoolProperty(name="Trim/Extend All",
                         default=False,
                         description=PDT_DES_TRIM)

    lib_objects: EnumProperty(items=enumlist_objects,
                              name="Objects",
                              description=PDT_DES_LIBOBS)
    lib_collections: EnumProperty(items=enumlist_collections,
                                  name="Collections",
                                  description=PDT_DES_LIBCOLS)
    lib_materials: EnumProperty(items=enumlist_materials,
                                name="Materials",
                                description=PDT_DES_LIBMATS)
    lib_mode: EnumProperty(
        items=(
            ("OBJECTS", "Objects", "Use Objects"),
            ("COLLECTIONS", "Collections", "Use Collections"),
            ("MATERIALS", "Materials", "Use Materials"),
        ),
        name="Mode",
        default="OBJECTS",
        description=PDT_DES_LIBMODE,
    )

    rotation_coords: FloatVectorProperty(name="Rotation",
                                         default=(0.0, 0.0, 0.0),
                                         subtype="XYZ",
                                         description="Rotation Coordinates")

    object_order: EnumProperty(
        items=(
            ("1,2,3,4", "1,2,3,4", "Objects 1 & 2 are First Line"),
            ("1,3,2,4", "1,3,2,4", "Objects 1 & 3 are First Line"),
            ("1,4,2,3", "1,4,2,3", "Objects 1 & 4 are First Line"),
        ),
        name="Order",
        default="1,2,3,4",
        description=PDT_DES_OBORDER,
    )
    vrotangle: FloatProperty(name="View Rotate Angle",
                             default=10,
                             max=180,
                             min=-180)
    command: StringProperty(
        name="Command",
        default="CA0,0,0",
        update=command_run,
        description=PDT_DES_VALIDLET,
    )
    maths_output: FloatProperty(
        name="Maths output",
        default=0,
        description=PDT_DES_OUTPUT,
    )
    error: StringProperty(name="Error", default="")

    # Was pivot* -- is now pivot_*
    pivot_loc: FloatVectorProperty(
        name="Pivot Location",
        default=(0.0, 0.0, 0.0),
        subtype="XYZ",
        description=PDT_DES_PPLOC,
    )
    pivot_scale: FloatVectorProperty(name="Pivot Scale",
                                     default=(1.0, 1.0, 1.0),
                                     subtype="XYZ",
                                     description=PDT_DES_PPSCALEFAC)
    pivot_size: FloatProperty(name="Pivot Factor",
                              min=0.4,
                              max=10,
                              default=2,
                              precision=1,
                              description=PDT_DES_PPSIZE)
    pivot_width: IntProperty(name="Width",
                             min=1,
                             max=5,
                             default=2,
                             description=PDT_DES_PPWIDTH)

    pivot_ang: FloatProperty(name="Pivot Angle",
                             min=-180,
                             max=180,
                             default=0.0)

    pivot_dis: FloatProperty(
        name="Pivot Dist",
        default=0.0,
        min=0,
        update=scale_set,
        description=PDT_DES_PIVOTDIS,
    )
    pivot_alpha: FloatProperty(
        name="Alpha",
        min=0.2,
        max=1,
        default=0.6,
        precision=1,
        description=PDT_DES_PPTRANS,
    )
    pivot_show: BoolProperty()

    # Was filletrad
    fillet_radius: FloatProperty(name="Fillet Radius",
                                 min=0.0,
                                 default=1.0,
                                 unit="LENGTH",
                                 description=PDT_DES_FILLETRAD)
    # Was filletnum
    fillet_segments: IntProperty(name="Fillet Segments",
                                 min=1,
                                 default=4,
                                 description=PDT_DES_FILLETSEG)
    # Was filletpro
    fillet_profile: FloatProperty(name="Fillet Profile",
                                  min=0.0,
                                  max=1.0,
                                  default=0.5,
                                  description=PDT_DES_FILLETPROF)
    # Was filletbool
    fillet_vertices_only: BoolProperty(
        name="Fillet Vertices Only",
        default=True,
        description=PDT_DES_FILLETVERTS,
    )
    fillet_intersect: BoolProperty(
        name="Intersect",
        default=False,
        description=PDT_DES_FILLINT,
    )
    tangent_point0: FloatVectorProperty(name="Coordst1",
                                        default=(0.0, 0.0, 0.0),
                                        subtype="XYZ",
                                        description=PDT_DES_TANCEN1)
    tangent_point1: FloatVectorProperty(name="Coordst2",
                                        default=(0.0, 0.0, 0.0),
                                        subtype="XYZ",
                                        description=PDT_DES_TANCEN2)
    tangent_radius0: FloatProperty(name="Arc Radius 1",
                                   min=0.00001,
                                   default=1,
                                   unit="LENGTH",
                                   description=PDT_DES_RADIUS1)
    tangent_radius1: FloatProperty(name="Arc Radius 2",
                                   min=0.00001,
                                   default=1,
                                   unit="LENGTH",
                                   description=PDT_DES_RADIUS2)
    tangent_point2: FloatVectorProperty(name="Coordst3",
                                        default=(0.0, 0.0, 0.0),
                                        subtype="XYZ",
                                        description=PDT_DES_TANCEN3)
    menu_expand: BoolProperty(
        name="Expand",
        default=False,
        description=PDT_DES_EXPCOLL,
    )
    tangent_mode: EnumProperty(
        items=(
            ("inner", "Inner", "Inner Tangents"),
            ("outer", "Outer", "Outer Tangents"),
            ("both", "Inner & Outer", "Inner & Outer Tangents"),
            ("point", "From Point", "Tangents from Point"),
        ),
        name="Working Plane",
        default="both",
        description=PDT_DES_TANMODE,
    )

    # For Trig Waves
    trig_type: EnumProperty(
        items=(
            ("sin", "Sine", "Sine Wave"),
            ("cos", "Cosine", "Cosine Wave"),
            ("tan", "Tangent", "Tangent Wave"),
        ),
        name="Wave Form",
        default="sin",
        description="Trig. Wave Form",
    )
    trig_cycles: IntProperty(name="Cycles #",
                             default=1,
                             min=1,
                             description="1 Cycle = 180 Degrees")
    trig_amp: FloatProperty(
        name="Amplitude",
        default=1,
        min=0.01,
        description="Maximum Height of 1 Cycle (forms Basis for Tangents)")
    trig_len: FloatProperty(name="Cycle Length",
                            default=2,
                            min=0.02,
                            description="Length in Blender Units of 1 Cycle")
    trig_obj: PointerProperty(name="Object", type=Object)
    trig_del: BoolProperty(name="Empty Object",
                           default=False,
                           description="Delete ALL Vertices in Object First")
    trig_res: IntProperty(
        name="Resolution",
        default=18,
        min=4,
        max=72,
        description="Number of Vertices per Cycle (180 Degrees)")
    trig_tanmax: FloatProperty(name="Tangent Max",
                               default=10,
                               min=0.1,
                               description="Maximum Permitted Tangent Value")
    trig_off: FloatVectorProperty(
        name="Start Location",
        default=(0, 0, 0),
        description="Location in World Space for Origin of Wave")
    trig_abs: BoolProperty(name="Absolute",
                           default=False,
                           description="Use Absolute Values Only")
Esempio n. 11
0
class KinorawToolsAddon(AddonPreferences):
    # this must match the addon name, use '__package__'
    # when defining this in a submodule of a python package.
    bl_idname = __package__
    bl_option = {'REGISTER'}

    # extra_actions
    kr_show_tools: BoolProperty(
            name="Show tools",
            description="Show extra tools in the panel",
            default=False
            )
    kr_mini_ui: BoolProperty(
            name="Mini UI",
            description="Enable mini UI",
            default=True
            )
    kr_show_info: BoolProperty(
            name="Show info",
            description="Show basic info from selected strip",
            default=False
            )
    kr_show_trim: BoolProperty(
            name="Show trim",
            default=False
            )
    kr_show_modifiers: BoolProperty(
            name="Show modifiers",
            description="Show modifiers from selected strip",
            default=False
            )
    kr_extra_info: BoolProperty(
            name="Show extra info",
            description="Show extra info and settings from selected strip",
            default=False
            )
    # exif
    use_exif_panel: BoolProperty(
            name="Exif info Panel | depends on external programs, see Documentation",
            default=False
            )
    # glitch
    use_glitch_panel: BoolProperty(
            name="Glitch panel | depends on external programs, see Documentation",
            default=False
            )
    all_keyframes: BoolProperty(
            name="Remove all keyframes",
            default=True
            )
    load_glitch: BoolProperty(
            name="Load glitch after conversion > UNSTABLE!!!",
            default=True
            )
    # jump to cut
    use_jumptocut: BoolProperty(
            name="Jump to Cut Panel",
            default=True
            )
    use_io_tools: BoolProperty(
            name="Enable in and out tools in Jump to Cut Panel",
            default=False
            )
    # Proxy Tools
    use_proxy_tools: BoolProperty(
            name="Proxy tools Panel | depends on external programs, see Documentation",
            default=False
            )
    proxy_dir: StringProperty(
            name="Proxy Custom Directory",
            default="//proxies/"
            )
    proxy_scripts_path: StringProperty(
            name="Directory to store proxy scripts",
            default="//proxy_scripts/"
            )
    proxy_scripts: BoolProperty(
            name="Generate ffmpeg scripts",
            default=False
            )
    ffmpeg_command: StringProperty(
            name="Command to generate proxy",
            default='''ffmpeg -i {} -vcodec mjpeg -q:v 10 -s {}x{} -an -y {}'''
            )
    use_internal_proxy = BoolProperty(
            name="Use internal Blender's proxy system",
            default=True
            )
    use_bi_custom_directory = BoolProperty(
            name="Proxy Custom Directory",
            default=True
            )
    quality = IntProperty(
            name="Quality",
            default=90,
            min=0, max=32767
            )
    tc_list = [
            ("NONE", "No TC in use", ""), ("RECORD_RUN", "Record Run", ""),
            ("FREE_RUN", "Free Run", ""), ("FREE_RUN_REC_DATE", "Free Run (rec date)", ""),
            ("RECORD_RUN_NO_GAPS", "Record Run No Gaps", "")
            ]
    timecode = EnumProperty(
            name="Settings Type",
            items=tc_list,
            default="NONE",
            description="Timecode"
            )
    # Audio Tools
    use_audio_tools = BoolProperty(
            name="Audio tools Panel | depends on external programs, see Documentation",
            default=False
            )
    audio_dir = StringProperty(
            name="Path to store extracted audio",
            default="//audio/"
            )
    audio_scripts_path = StringProperty(
            name="Path to store audio scripts",
            default="//audio_scripts/"
            )
    audio_scripts = BoolProperty(
            name="Generate ffmpeg scripts",
            default=False
            )
    #  Audio Tools - external links
    audio_use_external_links = BoolProperty(
            name="Use external audio linked to movie strips",
            default=False
            )
    audio_external_filename = StringProperty(
            name="File to store info about linked audio",
            default="//external_audio_sync_info.txt"
            )
    # audio tools vu-meter
    meterbridge = [
            ("VU", "Classic moving needle VU meter", ""), ("PPM", "PPM meter", ""),
            ("DPM", "Digital peak meter", ""), ("JF", "'Jellyfish' phase meter", ""),
            ("SCO", "Oscilloscope meter", "")
            ]
    metertype = EnumProperty(
            name="Meter type",
            items=meterbridge,
            default="DPM",
            description="Meterbridge meter type"
            )
    # eco
    use_eco_tools = BoolProperty(
            name="Eco tools Panel",
            default=True
            )
    eco_value = IntProperty(
            name="Number of echoes",
            default=5,
            min=1, max=25
            )
    eco_offset = IntProperty(
            name="Echo Offset",
            default=1,
            min=-25000, max=25000
            )
    eco_use_add_blend_mode = BoolProperty(
            name='use_add_blend_mode',
            default=False
            )
    # random editor
    use_random_editor = BoolProperty(
            name="Random editor Panel | Experimental",
            default=False
            )
    random_frames = IntProperty(
            name="Frames",
            default=1,
            min=1, max=1000
            )
    random_selected_scene = StringProperty(
            name="Selected Scene",
            default=""
            )
    random_use_marker_subsets = BoolProperty(
            name="Use_Marker subsets",
            default=True
            )
    random_number_of_subsets = IntProperty(
            name="Number of subsets",
            default=3,
            min=1, max=5
            )
    show_shortcuts = BoolProperty(
            name="Hot Keys",
            default=False,
            description="List of the shortcuts used for the included various tools",
            )
    show_experimental = BoolProperty(
            name="Tools with External Dependencies / Experimental",
            default=False,
            description="List of various tools that need an External Library "
                        "or are Experimental\nPlease read the Documentation "
                        "before enabling them",
            )

    def draw(self, context):
        layout = self.layout
        icon_1 = "TRIA_RIGHT" if not self.show_shortcuts else "TRIA_DOWN"
        icon_2 = "TRIA_RIGHT" if not self.show_experimental else "TRIA_DOWN"

        box = layout.box()
        box.prop(self, "use_jumptocut")
        box = layout.box()
        box.prop(self, "use_eco_tools")

        box_exp = layout.box()
        box_exp.prop(self, "show_experimental", emboss=False, icon=icon_2)

        if self.show_experimental:
            box = box_exp.box()
            box.prop(self, "use_audio_tools")
            box = box_exp.box()
            box.prop(self, "use_proxy_tools")
            box = box_exp.box()
            box.prop(self, "use_exif_panel")
            box = box_exp.box()
            box.prop(self, "use_glitch_panel")
            box = box_exp.box()
            box.prop(self, "use_random_editor")

        box = layout.box()
        box.prop(self, "show_shortcuts", emboss=False, icon=icon_1)

        if self.show_shortcuts:
            box.label(text="Skip One Second Forward: Ctrl + Shift + Right Arrow", icon="LAYER_USED")
            box.label(text="Skip One Second Backwards: Ctrl + Shift + Left Arrow", icon="LAYER_USED")
            box.label(text="Jump to Previous Strip: Q", icon="LAYER_USED")
            box.label(text="Jump to Next Strip: W", icon="LAYER_USED")
            box.label(text="Source IN: Ctrl + Shift + I", icon="LAYER_USED")
            box.label(text="Source OUT: Ctrl + Shift + O", icon="LAYER_USED")
            box.label(text="Jump to Previous Marker: Shift + Q", icon="LAYER_USED")
            box.label(text="Jump to Next Marker: Shift + W", icon="LAYER_USED")
Esempio n. 12
0
class ImportData3d(bpy.types.Operator, ImportHelper):
    """ Load a Archilogic Data3d File """

    bl_idname = 'import_scene.data3d'
    bl_label = 'Import Data3d'
    bl_options = {'PRESET', 'UNDO'}

    filter_glob: StringProperty(default='*.data3d.buffer;*.data3d.json', options={'HIDDEN'})

    import_materials: BoolProperty(
        name='Import Materials',
        description='Import Materials and Textures.',
        default=True
        )

    import_hierarchy: BoolProperty(
        name='Import Hierarchy',
        description='Import objects with parent-child relations.',
        default=True
        )

    convert_tris_to_quads: BoolProperty(
        name='Triangles to Quads',
        description='Converts triangles to quads for better editing.',
        default=True
        )

    # Hidden context
    import_al_metadata: EnumProperty(
        name='DATA3D Metadata',
        description='Import Archilogic Metadata',
        default='NONE',
        items=[
            ('NONE', 'none', '', 0),
            ('BASIC', 'basic material metadata', '', 1),
            ('ADVANCED', 'advanced material metadata', '', 2)
            ]
    )

    # Fixme: Change to enum property (custom-split-normals: {none, raw, Autosmooth}
    smooth_split_normals: BoolProperty(
        name='Autodetect smooth vertices from custom split normals.',
        description='Autosmooth vertex normals.',
        default=True
    )

    import_place_holder_images: BoolProperty(
        name='Placeholder Images',
        description='Import a placeholder image if the source image is unavailable',
        default=True
    )

    config_logger: BoolProperty(
        name='Configure logger',
        description='Configure and format log output',
        default=True
    )

    def draw(self, context):
        layout = self.layout
        layout.prop(self, 'import_materials')
        if self.import_materials is True:
            box = layout.box()
            row = box.row()
            row.label(text='Material Import Options')
            # Fixme: Add Material import options
            #row = box.row()
            #row.prop(self, "create cycles material")
            row = box.row()
            row.prop(self, "import_place_holder_images")

        layout.prop(self, 'import_hierarchy')
        layout.prop(self, 'convert_tris_to_quads')

        layout.prop(self, "axis_forward")
        layout.prop(self, "axis_up")

    def execute(self, context):
        from . import import_data3d
        keywords = self.as_keywords(ignore=('axis_forward',
                                            'axis_up',
                                            'filter_glob'))
        keywords['global_matrix'] = axis_conversion(from_forward=self.axis_forward, from_up=self.axis_up).to_4x4()
        return import_data3d.load(**keywords)
Esempio n. 13
0
class ExportData3d(bpy.types.Operator, ExportHelper):
    """ Export the scene as an Archilogic Data3d File """

    # export_materials
    # export_textures
    # apply modifiers

    bl_idname = 'export_scene.data3d'
    bl_label = 'Export Data3d'
    bl_options = {'PRESET'}

    filename_ext = '.data3d.json'
    filter_glob: StringProperty(default='*.data3d.buffer;*.data3d.json', options={'HIDDEN'})

    # Context
    export_format: EnumProperty(
        name='Format',
        description='Export geometry interleaved(buffer) or non-interleaved (json).',
        default='NON_INTERLEAVED',
        items=[
            ('INTERLEAVED', 'data3d.buffer', '', 0),
            ('NON_INTERLEAVED', 'data3d.json', '', 1)
            ]
    )

    use_selection: BoolProperty(
        name='Selection Only',
        description='Export selected objects only.',
        default=False
    )

    export_images: BoolProperty(
        name='Export Images',
        description='Export associated texture files.',
        default=False
    )

    # Hidden context
    export_al_metadata: BoolProperty(
        name='Export Archilogic Metadata',
        description='Export Archilogic Metadata, if it exists.',
        default=False
    )

    config_logger: BoolProperty(
        name='Configure logger',
        description='Configure and format log output',
        default=True
    )

    def draw(self, context):
        layout = self.layout
        layout.prop(self, 'export_format')
        layout.prop(self, 'use_selection')
        layout.prop(self, 'export_images')

    def execute(self, context):
        from . import export_data3d

        keywords = self.as_keywords(ignore=('axis_forward',
                                            'axis_up',
                                            'filter_glob',
                                            'filename_ext',
                                            'check_existing'))
        global_matrix = axis_conversion(to_forward=self.axis_forward,
                                        to_up=self.axis_up,
                                        ).to_4x4()
        keywords["global_matrix"] = global_matrix
        return export_data3d.save(context, **keywords)
Esempio n. 14
0
class SvGroupNodeExp:
    """
    Base class for all monad instances
    """
    bl_icon = 'OUTLINER_OB_EMPTY'

    vectorize: BoolProperty(
        name="Vectorize", description="Vectorize using monad",
        default=False, update=updateNode)

    split: BoolProperty(
        name="Split", description="Split inputs into lenght 1",
        default=False, update=updateNode)

    loop_me: BoolProperty(default=False, update=updateNode)
    loops_max: IntProperty(default=5, description='maximum')
    loops: IntProperty(
        name='loop n times', default=0,
        description='change max value in sidebar with variable named loops_max',
        get=lambda s: uget(s, 'loops'),
        set=lambda s, val: uset(s, val, 'loops'),
        update=updateNode)

    def draw_label(self):
        return self.monad.name

    @property
    def monad(self):
        for tree in bpy.data.node_groups:
            if tree.bl_idname == 'SverchGroupTreeType' and self.bl_idname == tree.cls_bl_idname:
               return tree
        return None # or raise LookupError or something, anyway big FAIL

    def sv_init(self, context):
        self['loops'] = 0
        self.use_custom_color = True
        self.color = MONAD_COLOR

        for socket_name, socket_bl_idname, prop_data in self.input_template:
            s = self.inputs.new(socket_bl_idname, socket_name)
            for name, value in prop_data.items():
                setattr(s, name, value)

        for socket_name, socket_bl_idname in self.output_template:
            self.outputs.new(socket_bl_idname, socket_name)


    def update(self):
        ''' Override inherited '''
        pass

    def draw_buttons_ext(self, context, layout):
        self.draw_buttons(context, layout)
        layout.prop(self, 'loops_max')

    def draw_buttons(self, context, layout):

        split = layout.column().split()
        cA = split.column()
        cB = split.column()
        cA.active = not self.loop_me
        cA.prop(self, "vectorize", toggle=True)
        cB.active = self.vectorize
        cB.prop(self, "split", toggle=True)
        
        c2 = layout.column()
        row = c2.row(align=True)
        row.prop(self, "loop_me", text='Loop', toggle=True)
        row.prop(self, "loops", text='N')

        monad = self.monad
        if monad:
            c3 = layout.column()
            c3.prop(monad, "name", text='name')

            d = layout.column()
            d.active = bool(monad)
            if context:
                f = d.operator('node.sv_group_edit', text='edit!')
                f.group_name = monad.name
            else:
                layout.prop(self, 'loops_max')

    def get_nodes_to_process(self, out_node_name):
        """
        nodes not indirectly / directly contributing to the data we eventually pass to "monad.output_node" 
        are discarded if only `self.monad.outputs_node.name` is passed in endpoints_nodes.

        The exceptions are nodes that we use for debugging inside the monad. At present SvDebugPrint instances
        are added as endpoints (this allows them to be processed and they can write to the bpy.data.texta
        """
        endpoint_nodes = [out_node_name]
        nodes = self.monad.nodes
        for n in nodes:
            if n.bl_idname == 'SvDebugPrintNode' and n.print_data:
                endpoint_nodes.append(n.name)
        return endpoint_nodes

    def process(self):
        if not any(s.is_linked for s in self.outputs):
            return
        if not self.monad:
            return
        if self.vectorize:
            self.process_vectorize()
            return
        elif self.loop_me:
            self.process_looped(self.loops)
            return

        monad = self.monad
        in_node = monad.input_node
        out_node = monad.output_node
        monad['current_index'] = 0
        monad['current_total'] = 0

        for index, socket in enumerate(self.inputs):
            data = socket.sv_get(deepcopy=False)
            in_node.outputs[index].sv_set(data)

        node_names = self.get_nodes_to_process(out_node.name)
        ul = make_tree_from_nodes(node_names, monad, down=False)

        do_update(ul, monad.nodes)
        # set output sockets correctly
        for index, socket in enumerate(self.outputs):
            if socket.is_linked:
                data = out_node.inputs[index].sv_get(deepcopy=False)
                socket.sv_set(data)

    def process_vectorize(self):
        monad = self.monad
        in_node = monad.input_node
        out_node = monad.output_node

        node_names = self.get_nodes_to_process(out_node.name)
        ul = make_tree_from_nodes(node_names, monad, down=False)

        data_out = [[] for s in self.outputs]

        data_in = match_long_repeat([s.sv_get(deepcopy=False) for s in self.inputs])
        if self.split:
            for idx, data in enumerate(data_in):
                new_data = unwrap(split_list(d) for d in data)
                data_in[idx] = new_data
            data_in = match_long_repeat(data_in)

        monad["current_total"] = len(data_in[0])


        for master_idx, data in enumerate(zip(*data_in)):
            for idx, d in enumerate(data):
                socket = in_node.outputs[idx]
                if socket.is_linked:
                    socket.sv_set([d])
            monad["current_index"] = master_idx
            do_update(ul, monad.nodes)
            for idx, s in enumerate(out_node.inputs[:-1]):
                data_out[idx].extend(s.sv_get(deepcopy=False))

        for idx, socket in enumerate(self.outputs):
            if socket.is_linked:
                socket.sv_set(data_out[idx])


    # ----------- loop (iterate 2)

    def do_process(self, sockets_data_in):

        monad = self.monad
        in_node = monad.input_node
        out_node = monad.output_node

        for index, data in enumerate(sockets_data_in):
            in_node.outputs[index].sv_set(data)        

        node_names = self.get_nodes_to_process(out_node.name)
        ul = make_tree_from_nodes(node_names, monad, down=False)
        do_update(ul, monad.nodes)

        # set output sockets correctly
        socket_data_out = []
        for index, socket in enumerate(self.outputs):
            if socket.is_linked:
                data = out_node.inputs[index].sv_get(deepcopy=False)
                socket_data_out.append(data)

        return socket_data_out


    def apply_output(self, socket_data):
        for idx, data in enumerate(socket_data):
            self.outputs[idx].sv_set(data)


    def process_looped(self, iterations_remaining):
        sockets_in = [i.sv_get() for i in self.inputs]

        monad = self.monad
        monad['current_total'] = iterations_remaining
        monad['current_index'] = 0

        in_node = monad.input_node
        out_node = monad.output_node

        for iteration in range(iterations_remaining):
            # if 'Monad Info' in monad.nodes:
            #     info_node = monad.nodes['Monad Info']
            #     info_node.outputs[0].sv_set([[iteration]])
            monad["current_index"] = iteration
            sockets_in = self.do_process(sockets_in)
        self.apply_output(sockets_in)


    def load(self):
        pass
Esempio n. 15
0
class UI_OT_i18n_updatetranslation_svn_branches(Operator):
    """Update i18n svn's branches (po files)"""
    bl_idname = "ui.i18n_updatetranslation_svn_branches"
    bl_label = "Update I18n Branches"

    use_skip_pot_gen: BoolProperty(
        name="Skip POT",
        description="Skip POT file generation",
        default=False,
    )

    def execute(self, context):
        if not hasattr(self, "settings"):
            self.settings = settings.settings
        i18n_sett = context.window_manager.i18n_update_svn_settings
        self.settings.FILE_NAME_POT = i18n_sett.pot_path

        context.window_manager.progress_begin(0, len(i18n_sett.langs) + 1)
        context.window_manager.progress_update(0)
        if not self.use_skip_pot_gen:
            env = os.environ.copy()
            env["ASAN_OPTIONS"] = "exitcode=0:" + os.environ.get(
                "ASAN_OPTIONS", "")
            # Generate base pot from RNA messages (we use another blender instance here, to be able to perfectly
            # control our environment (factory startup, specific addons enabled/disabled...)).
            # However, we need to export current user settings about this addon!
            cmmd = (
                bpy.app.binary_path,
                "--background",
                "--factory-startup",
                "--python",
                os.path.join(os.path.dirname(utils_i18n.__file__),
                             "bl_extract_messages.py"),
                "--",
                "--settings",
                self.settings.to_json(),
            )
            # Not working (UI is not refreshed...).
            #self.report({'INFO'}, "Extracting messages, this will take some time...")
            context.window_manager.progress_update(1)
            ret = subprocess.run(cmmd, env=env)
            if ret.returncode != 0:
                self.report({'ERROR'}, "Message extraction process failed!")
                context.window_manager.progress_end()
                return {'CANCELLED'}

        # Now we should have a valid POT file, we have to merge it in all languages po's...
        with concurrent.futures.ProcessPoolExecutor() as exctr:
            pot = utils_i18n.I18nMessages(kind='PO',
                                          src=self.settings.FILE_NAME_POT,
                                          settings=self.settings)
            num_langs = len(i18n_sett.langs)
            for progress, _ in enumerate(
                    exctr.map(i18n_updatetranslation_svn_branches_callback,
                              (pot, ) * num_langs,
                              [dict(lng.items()) for lng in i18n_sett.langs],
                              (self.settings, ) * num_langs,
                              chunksize=4)):
                context.window_manager.progress_update(progress + 2)
        context.window_manager.progress_end()
        return {'FINISHED'}

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_dialog(self)
Esempio n. 16
0
class Make_WScrew(bpy.types.Operator):
    """Create primitive WScrew"""
    bl_idname = "mesh.make_wscrew"
    bl_label = "WScrew"
    bl_options = {'UNDO', 'REGISTER'}

    rounds = IntProperty(
        name="Rounds",
        description="Iterations of the screw",
        default=5,
        min=1,
        soft_min=1
    )

    segments = IntProperty(
        name="Segments",
        description="Perimetr segments",
        default=12,
        min=3,
        soft_min=3
    )

    height = FloatProperty(
        name="Height",
        description="Height of the screw",
        default=2.0,
        min=0.0,
        soft_min=0.0,
        step=1,
        precision=2,
        unit='LENGTH'
    )

    radius_1 = FloatProperty(
        name="Major",
        description="Major radius",
        default=0.5,
        min=0.0,
        soft_min=0.0,
        step=1,
        unit='LENGTH'
    )

    radius_2 = FloatProperty(
        name="Minor",
        description="Minor radius",
        default=0.6,
        min=0.0,
        soft_min=0.0,
        step=1,
        unit='LENGTH'
    )

    smoothed = BoolProperty(
        name="Smooth",
        description="Smooth shading",
        default=True
    )

    def execute(self, context):

        """
        WScrew_Defaults = {
        "rounds": 5,
        "segments": 12,
        "height": 2.0,
        "radius_1": 0.5,
        "radius_2": 0.6,
        "smoothed": True
        """

        WScrew_Defaults["rounds"] = self.rounds
        WScrew_Defaults["segments"] = self.segments
        WScrew_Defaults["height"] = self.height
        WScrew_Defaults["radius_1"] = self.radius_1
        WScrew_Defaults["radius_2"] = self.radius_2
        WScrew_Defaults["smoothed"] = self.smoothed

        verts, edges, faces = primitive_Screw(**WScrew_Defaults)
        create_mesh_object(context, verts, edges, faces, "WScrew")

        context.object.data.WType = 'WSCREW'
        context.object.data.WScrew["animArgs"] = WScrew_Defaults
        bpy.ops.object.shade_smooth()
        context.object.data.use_auto_smooth = True
        context.object.data.auto_smooth_angle = pi / 3
        return {'FINISHED'}
Esempio n. 17
0
class SvGetObjectsData(Show3DProperties, bpy.types.Node, SverchCustomTreeNode):
    """
    Triggers: Object Info
    Tooltip: Get Scene Objects into Sverchok Tree
    """

    bl_idname = 'SvGetObjectsData'
    bl_label = 'Get Objects Data'
    bl_icon = 'OUTLINER_OB_EMPTY'
    sv_icon = 'SV_OBJECTS_IN'

    @property
    def is_scene_dependent(self):
        return (not self.inputs['Objects'].is_linked) and (self.inputs['Objects'].object_ref_pointer
                                                           or self.object_names)

    @property
    def is_animation_dependent(self):
        return (not self.inputs['Objects'].is_linked) and (self.inputs['Objects'].object_ref_pointer
                                                           or self.object_names)

    def hide_show_versgroups(self, context):
        outs = self.outputs
        showing_vg = 'Vers_grouped' in outs

        if self.vergroups and not showing_vg:
            outs.new('SvStringsSocket', 'Vers_grouped')
        elif not self.vergroups and showing_vg:
            outs.remove(outs['Vers_grouped'])

    def modifiers_handle(self, context):
        set_sv_depsgraph_need(self.modifiers)
        updateNode(self, context)

    modifiers: BoolProperty(
        name='Modifiers',
        description='Apply modifier geometry to import (original untouched)',
        default=False, update=modifiers_handle)

    vergroups: BoolProperty(
        name='Vergroups',
        description='Use vertex groups to nesty insertion',
        default=False, update=hide_show_versgroups)

    sort: BoolProperty(
        name='sort by name',
        description='sorting inserted objects by names',
        default=True, update=updateNode)

    object_names: bpy.props.CollectionProperty(type=SvOB3BDataCollection)

    active_obj_index: bpy.props.IntProperty()

    out_np: bpy.props.BoolVectorProperty(
        name="Output Numpy",
        description="Output NumPy arrays (makes node faster)",
        size=7, update=updateNode)
    output_np_all: BoolProperty(
        name='Output all numpy',
        description='Output numpy arrays if possible',
        default=False, update=updateNode)

    def sv_init(self, context):
        new = self.outputs.new
        self.width = 150
        self.inputs.new('SvObjectSocket', "Objects")
        new('SvVerticesSocket', "Vertices")
        new('SvStringsSocket', "Edges")
        new('SvStringsSocket', "Polygons")
        new('SvVerticesSocket', "Vertex Normals")
        new('SvStringsSocket', "Material Idx")
        new('SvStringsSocket', "Polygon Areas")
        new('SvVerticesSocket', "Polygon Centers")
        new('SvVerticesSocket', "Polygon Normals")
        new('SvMatrixSocket', "Matrix")
        new('SvObjectSocket', "Object")


    def get_objects_from_scene(self, ops):
        """
        Collect selected objects
        """
        self.object_names.clear()

        names = [obj.name for obj in bpy.data.objects if (obj.select_get() and len(obj.users_scene) > 0 and len(obj.users_collection) > 0)]

        if self.sort:
            names.sort()

        for name in names:
            item = self.object_names.add()
            item.name = name
            item.icon = 'OUTLINER_OB_' + bpy.data.objects[name].type

        if not self.object_names:
            ops.report({'WARNING'}, "Warning, no selected objects in the scene")
            return

        self.process_node(None)


    def select_objs(self, ops):
        """select all objects referenced by node"""
        for item in self.object_names:
            bpy.data.objects[item.name].select = True

        if not self.object_names:
            ops.report({'WARNING'}, "Warning, no object associated with the obj in Node")


    def draw_obj_names(self, layout):
        if self.object_names:
            layout.template_list("SVOB3B_UL_NamesList", "", self, "object_names", self, "active_obj_index")
        else:
            layout.label(text='--None--')

    @property
    def by_input(self):
        return self.inputs[0].object_ref_pointer is not None or self.inputs[0].is_linked

    def sv_draw_buttons(self, context, layout):
        col = layout.column(align=True)
        by_input = self.by_input
        if not by_input:
            row = col.row()

            op_text = "Get selection"  # fallback
            callback = 'node.ob3_callback'

            if self.prefs_over_sized_buttons:
                row.scale_y = 4.0
                op_text = "G E T"

            self.wrapper_tracked_ui_draw_op(row, callback, text=op_text).fn_name = 'get_objects_from_scene'

        col = layout.column(align=True)
        row = col.row(align=True)
        if not by_input:
            row.prop(self, 'sort', text='Sort', toggle=True)
        row.prop(self, "modifiers", text="Post", toggle=True)
        row.prop(self, "vergroups", text="VeGr", toggle=True)
        if not by_input:
            self.draw_obj_names(layout)

    def sv_draw_buttons_ext(self, context, layout):
        r = layout.column(align=True)
        row = r.row(align=True)
        row.label(text="Output Numpy:")
        row.prop(self, 'output_np_all', text='If possible', toggle=True)
        if not self.output_np_all:
            for i in range(7):
                r.prop(self, "out_np", index=i, text=numpy_socket_names[i], toggle=True)

        layout.prop(self, 'draw_3dpanel', text="To Control panel")

    def rclick_menu(self, context, layout):
        '''right click sv_menu items'''
        layout.label(text="Output Numpy:")
        layout.prop(self, 'output_np_all', text='All', toggle=True)
        if not self.output_np_all:
            for i in range(7):
                layout.prop(self, "out_np", index=i, text=numpy_socket_names[i], toggle=True)

    def draw_buttons_3dpanel(self, layout):
        if not self.by_input:
            callback = 'node.ob3_callback'
            row = layout.row(align=True)
            row.label(text=self.label if self.label else self.name)
            colo = row.row(align=True)
            colo.scale_x = 1.6

            self.wrapper_tracked_ui_draw_op(colo, callback, text='Get').fn_name = 'get_objects_from_scene'
        else:
            row = layout.row(align=True)
            row.label(text=self.label if self.label else self.name)
            self.draw_animatable_buttons(row, icon_only=True)

    def get_materials_from_bmesh(self, bm):
        return [face.material_index for face in bm.faces[:]]

    def sv_free(self):
        set_sv_depsgraph_need(False)

    def process(self):

        objs = self.inputs[0].sv_get(default=[[]])
        if not self.object_names and not objs[0]:

            return
        data_objects = bpy.data.objects
        outputs = self.outputs

        vers_out_grouped = []

        o_vs, o_es, o_ps, o_vn, o_mi, o_pa, o_pc, o_pn, o_ms, o_ob = [s.is_linked for s in self.outputs[:10]]
        vs, es, ps, vn, mi, pa, pc, pn, ms = [[] for s in self.outputs[:9]]
        if self.modifiers:
            sv_depsgraph = get_sv_depsgraph()


        out_np = self.out_np if not self.output_np_all else [True for i in range(7)]
        if isinstance(objs[0], list):
            objs = objs[0]
        if not objs:
            objs = (data_objects.get(o.name) for o in self.object_names)

        # iterate through references
        for obj in objs:

            if not obj:
                continue

            mtrx = obj.matrix_world
            if obj.type in {'EMPTY', 'CAMERA', 'LAMP' }:
                if o_ms:
                    ms.append(mtrx)
                continue
            try:
                if obj.mode == 'EDIT' and obj.type == 'MESH':
                    # Mesh objects do not currently return what you see
                    # from 3dview while in edit mode when using obj.to_mesh.
                    me = obj.data
                    bm = bmesh.from_edit_mesh(me)
                    vers, edgs, pols = pydata_from_bmesh(bm)

                    if o_vs:
                        vs.append(vers)
                    if o_es:
                        es.append(edgs)
                    if o_ps:
                        ps.append(pols)
                    if o_vn:
                        vn.append([v.normal[:] for v in bm.verts])
                    if o_mi:
                        mi.append(self.get_materials_from_bmesh(bm))
                    if o_pa:
                        pa.append([p.calc_area() for p in bm.faces])
                    if o_pc:
                        pc.append([p.calc_center_median()[:] for p in bm.faces])
                    if o_pn:
                        pn.append([p.normal[:] for p in bm.faces])

                    del bm
                else:

                    if self.modifiers:
                        obj = sv_depsgraph.objects[obj.name]
                        obj_data = obj.to_mesh(preserve_all_data_layers=True, depsgraph=sv_depsgraph)
                    else:
                        obj_data = obj.to_mesh()

                    if o_vs:
                        vs.append(read_verts(obj_data, out_np[0]))
                    if o_es:
                        es.append(read_edges(obj_data, out_np[1]))
                    if o_ps:
                        ps.append([list(p.vertices) for p in obj_data.polygons])
                    if self.vergroups:
                        vers_out_grouped.append(get_vertgroups(obj_data))
                    if o_vn:
                        vn.append(read_verts_normal(obj_data, out_np[2]))
                    if o_mi:
                        mi.append(read_materials_idx(obj_data, out_np[3]))
                    if o_pa:
                        pa.append(read_face_area(obj_data, out_np[4]))
                    if o_pc:
                        if out_np[5]:
                            pc.append(read_face_center(obj_data, output_numpy=True))
                        else:
                            pc.append([p.center[:] for p in obj_data.polygons])
                    if o_pn:
                        if out_np[6]:
                            pn.append(read_face_normal(obj_data, True))
                        else:
                            pn.append([p.normal[:] for p in obj_data.polygons])

                    obj.to_mesh_clear()

            except Exception as err:
                print('failure in process between frozen area', self.name, err)

            if o_ms:
                ms.append(mtrx)


        for i, i2 in zip(self.outputs, [vs, es, ps, vn, mi, pa, pc, pn, ms]):
            if i.is_linked:
                i.sv_set(i2)

        if vers_out_grouped and vers_out_grouped[0]:
            if 'Vers_grouped' in outputs and self.vergroups:
                outputs['Vers_grouped'].sv_set(vers_out_grouped)
        if o_ob:
            if self.by_input:
                outputs['Object'].sv_set(objs)
            else:
                outputs['Object'].sv_set([data_objects.get(o.name) for o in self.object_names])
Esempio n. 18
0
class SvPipeNode(bpy.types.Node, SverchCustomTreeNode):
    ''' Pipe from edges '''
    bl_idname = 'SvPipeNode'
    bl_label = 'Pipe tube Node'
    bl_icon = 'OUTLINER_OB_EMPTY'

    #nsides = IntProperty(name='nsides', description='number of sides',
    #              default=4, min=4, max=24,
    #              options={'ANIMATABLE'}, update=updateNode)
    diameter = FloatProperty(name='diameter',
                             description='diameter',
                             default=1.0,
                             options={'ANIMATABLE'},
                             update=updateNode)
    shape_prop = [('Square', 'Square', 'Square'), ('Round', 'Round', 'Round')]
    shape = EnumProperty(items=shape_prop,
                         name='shape',
                         default='Square',
                         options={'ANIMATABLE'},
                         update=updateNode)
    #offset = FloatProperty(name='offset', description='offset from ends',
    #              default=0.0, min=-1, max=0.5,
    #              options={'ANIMATABLE'}, update=updateNode)
    #extrude = FloatProperty(name='extrude', description='extrude',
    #              default=1.0, min=0.2, max=10.0,
    #              options={'ANIMATABLE'}, update=updateNode)
    close = BoolProperty(name='close',
                         description='close ends',
                         default=True,
                         options={'ANIMATABLE'},
                         update=updateNode)
    cup_fill = BoolProperty(name='close',
                            description='close ends',
                            default=True,
                            options={'ANIMATABLE'},
                            update=updateNode)

    def draw_buttons(self, context, layout):
        layout.prop(self, 'close', text='close')
        layout.prop(self, 'cup_fill', text='cup_fill')
        layout.prop(self, 'shape', expand=True)

    def sv_init(self, context):
        self.inputs.new('VerticesSocket', 'Vers', 'Vers')
        self.inputs.new('StringsSocket', "Edgs", "Edgs")
        #self.inputs.new('StringsSocket', "Diameter", "Diameter").prop_name = 'diameter'
        #self.inputs.new('StringsSocket', "Sides", "Sides").prop_name = 'nsides'
        #self.inputs.new('StringsSocket', "Offset", "Offset").prop_name = 'offset'
        s = self.inputs.new('VerticesSocket', "Size", "Size")
        s.use_prop = True
        s.prop = (0.5, 0.5, 0.5)
        #self.inputs.new('StringsSocket', "Extrude", "Extrude").prop_name = 'extrude'
        self.outputs.new('VerticesSocket', 'Vers', 'Vers')
        self.outputs.new('StringsSocket', "Pols", "Pols")

    def process(self):

        if self.outputs['Vers'].is_linked and self.inputs['Vers'].is_linked:
            Vecs = self.inputs['Vers'].sv_get()
            Edgs = self.inputs['Edgs'].sv_get()
            #Nsides = max(self.inputs['Sides'].sv_get()[0][0], 4)
            Shape = self.shape
            Cup = self.cup_fill
            #Diameter = self.inputs['Diameter'].sv_get()[0][0]
            Diameter = 1.0
            Size = self.inputs['Size'].sv_get()[0]
            #Offset = self.inputs['Offset'].sv_get()[0][0]
            #Extrude = self.inputs['Extrude'].sv_get()[0][0]
            outv, outp = self.Do_vecs(Vecs, Edgs, Diameter, Shape, Size,
                                      Cup)  #Nsides,Offset,Extrude)

            if self.outputs['Vers'].is_linked:
                self.outputs['Vers'].sv_set(outv)
            if self.outputs['Pols'].is_linked:
                self.outputs['Pols'].sv_set(outp)

    def Do_vecs(self, Vecs, Edgs, Diameter, Shape, Size,
                Cup):  #Offset,Extrude):
        if Shape == 'Square':
            Nsides = 4
            Diameter = Diameter * sqrt(2) / 2
            Sides = 90
        else:
            Nsides = 12
            Diameter = Diameter / 2
            Sides = 30

        outv = []
        outp = []
        for E, V in zip(Edgs, Vecs):
            outv_ = []
            outp_ = []
            k = 0
            for e, S in zip(E, Size):
                S0, S1, S2 = S
                S2 = (S2 - 1) / 2
                circle = [ (Vector((sin(radians(i))*S0,cos(radians(i))*S1,0))*Diameter) \
                            for i in range(45,405,Sides) ]
                v2, v1 = Vector(V[e[1]]), Vector(V[e[0]])
                vecdi = v2 - v1
                matrix_rot = vecdi.rotation_difference(Vector(
                    (0, 0, 1))).to_matrix().to_4x4()
                verts1 = [(ve * matrix_rot + v1 - vecdi * S2)[:]
                          for ve in circle]
                verts2 = [(ve * matrix_rot + v2 + vecdi * S2)[:]
                          for ve in circle]
                outv_.extend(verts1)
                outv_.extend(verts2)
                pols = [[
                    k + i + 0, k + i - 1, k + i + Nsides - 1, k + i + Nsides
                ] for i in range(1, Nsides, 1)]
                pols.append(
                    [k + 0, k + Nsides - 1, k + Nsides * 2 - 1, k + Nsides])
                if Cup:
                    p1 = [
                        k + i - Nsides for i in reversed(range(1, Nsides, 1))
                    ]
                    p2 = [k + i for i in range(1, Nsides, 1)]
                    p2.append(k)
                    p1.append(k - Nsides)
                    pols.append(p1)
                    pols.append(p2)

                if self.close and k != 0:
                    p = [[
                        k + i + 0 - Nsides, k + i - 1 - Nsides, k + i - 1,
                        k + i
                    ] for i in range(1, Nsides, 1)]
                    pols.extend(p)
                    pols.append([k + 0 - Nsides, k - 1, k + Nsides - 1, k])
                outp_.extend(pols)
                k += Nsides * 2
            outv.append(outv_)
            outp.append(outp_)
        return outv, outp
Esempio n. 19
0
class ANIM_OT_animation_offset(Operator, AdOffset, OffsetMethods):
    bl_label = "Commotion Offset Animation"
    bl_description = "Offset animation"
    bl_idname = "anim.commotion_animation_offset"
    bl_options = {"REGISTER", "UNDO"}

    offset: FloatProperty(name="Frame Offset", description="Frame step for animation offset", default=1, min=0, step=10, precision=3)
    threshold: IntProperty(name="Threshold", description="Number of objects to animate per frame step", default=1, min=1)
    use_reverse: BoolProperty(name="Reverse", description="Reverse animation offset")
    seed: IntProperty(name="Seed", description="Seed value for randomizer to get different offset patterns", min=0)

    def draw(self, context):
        if self.sort_method == "MULTI" and self.use_proxy:
            return

        layout = self.layout
        layout.use_property_split = True

        col = layout.column()
        col.prop(self, "offset")
        col.prop(self, "threshold")
        col.prop(self, "use_reverse")

        if self.sort_method == "RANDOM":
            col.prop(self, "seed")

    def invoke(self, context, event):
        scene = context.scene
        props = scene.commotion

        self.use_ob = props.offset_id_type in {"OBJECT", "ALL"}
        self.use_data = props.offset_id_type in {"OBJECT_DATA", "ALL"}
        self.use_sk = props.offset_id_type in {"SHAPE_KEYS", "ALL"}
        self.use_mat = props.offset_id_type in {"MATERIAL", "ALL"}
        self.frame = scene.frame_current
        self.cursor = scene.cursor.location
        self.offset = props.offset_offset
        self.threshold = props.offset_threshold
        self.seed = props.offset_seed
        self.use_reverse = props.offset_use_reverse
        self.sort_method = props.offset_sort_method
        self.radius = props.offset_proxy_radius
        self.use_proxy = props.offset_use_proxy
        self.coll_animated_name = ""
        self.coll_effectors_name = ""

        if self.sort_method == "MULTI":
            self.coll_animated = props.offset_coll_animated
            self.coll_effectors = props.offset_coll_effectors
            self.coll_animated_name = self.coll_animated.name
            self.coll_effectors_name = self.coll_effectors.name

            if not (self.coll_animated and self.coll_effectors):
                self.report({"ERROR"}, "Animated or Effector collections are not specified")
                return {"CANCELLED"}

        return self.execute(context)

    def execute(self, context):
        if self.sort_method == "CURSOR":
            self.offset_from_cursor(context)
        elif self.sort_method == "NAME":
            self.offset_from_name(context)
        elif self.sort_method == "RANDOM":
            self.offset_from_random(context)
        else:
            if self.use_proxy:
                self.offset_from_multi_proxy(context)
            else:
                self.offset_from_multi(context)

        return {"FINISHED"}
class ImportSKP(Operator, ImportHelper):
    """Load a Trimble Sketchup SKP file"""

    bl_idname = "import_scene.skp"
    bl_label = "Import SKP"
    bl_options = {'PRESET', 'UNDO'}

    filename_ext = ".skp"

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

    import_camera: BoolProperty(
        name="Last View In SketchUP As Camera View",
        description="Import last saved view in SketchUp as a Blender Camera.",
        default=False)

    reuse_material: BoolProperty(
        name="Use Existing Materials",
        description="Doesn't copy material IDs already in the Blender Scene.",
        default=True)

    max_instance: IntProperty(name="Threshold :", default=50)

    dedub_type: EnumProperty(
        name="Instancing Type :",
        items=(
            ('FACE', "Faces", ""),
            ('VERTEX', "Verts", ""),
        ),
        default='FACE',
    )

    dedub_only: BoolProperty(name="Groups Only",
                             description="Import instanciated groups only.",
                             default=False)

    scenes_as_camera: BoolProperty(
        name="Scene(s) As Camera(s)",
        description="Import SketchUp Scenes As Blender Camera.",
        default=True)

    import_scene: StringProperty(
        name="Import A Scene :",
        description="Import a specific Sketchup Scene",
        default="")

    reuse_existing_groups: BoolProperty(
        name="Reuse Groups",
        description="Use existing Blender groups to instance componenets with.",
        default=False)

    render_engine: EnumProperty(
        name="Default Shaders In :",
        items=(('CYCLES', "Cycles", ""),
               #    ('BLENDER_RENDER', "Blender Render", "")
               ),
        default='CYCLES')

    def execute(self, context):

        keywords = self.as_keywords(ignore=("axis_forward", "axis_up",
                                            "filter_glob", "split_mode"))

        return SceneImporter().set_filename(keywords['filepath']).load(
            context, **keywords)

    def draw(self, context):

        layout = self.layout
        layout.label(text="- Primary Import Options -")

        row = layout.row()
        row.prop(self, "scenes_as_camera")
        row = layout.row()
        row.prop(self, "import_camera")
        row = layout.row()
        row.prop(self, "reuse_material")
        row = layout.row()
        row.prop(self, "dedub_only")
        row = layout.row()
        row.prop(self, "reuse_existing_groups")
        # row = layout.row()
        col = layout.column()
        col.label(text="- Instanciate When Similar Objects Are Over -")
        split = col.split(factor=0.5)
        col = split.column()
        col.prop(self, "max_instance")
        row = layout.row()
        row.use_property_split = True
        row.prop(self, "dedub_type")
        row = layout.row()
        row.use_property_split = True
        row.prop(self, "import_scene")
        row = layout.row()
        row.use_property_split = True
        row.prop(self, "render_engine")
Esempio n. 21
0
class DemoModeSetup(bpy.types.Operator):
    """Create a demo script and optionally execute it"""
    bl_idname = "wm.demo_mode_setup"
    bl_label = "Demo Mode (Setup)"
    bl_options = {'PRESET'}

    # List of operator properties, the attributes will be assigned
    # to the class instance from the operator settings before calling.

    # these are used to create the file list.
    directory: StringProperty(
        name="Search Path",
        description="Directory used for importing the file",
        maxlen=1024,
        subtype='DIR_PATH',
    )
    random_order: BoolProperty(
        name="Random Order",
        description="Select files randomly",
        default=False,
    )
    mode: EnumProperty(name="Method",
                       items=(
                           ('AUTO', "Auto", ""),
                           ('PLAY', "Play", ""),
                           ('RENDER', "Render", ""),
                       ))

    run: BoolProperty(
        name="Run Immediately!",
        description="Run demo immediately",
        default=True,
    )
    exit: BoolProperty(
        name="Exit",
        description="Run once and exit",
        default=False,
    )

    # these are mapped directly to the config!
    #
    # anim
    # ====
    anim_cycles: IntProperty(
        name="Cycles",
        description="Number of times to play the animation",
        min=1,
        max=1000,
        default=2,
    )
    anim_time_min: FloatProperty(
        name="Time Min",
        description="Minimum number of seconds to show the animation for "
        "(for small loops)",
        min=0.0,
        max=1000.0,
        soft_min=1.0,
        soft_max=1000.0,
        default=4.0,
    )
    anim_time_max: FloatProperty(
        name="Time Max",
        description="Maximum number of seconds to show the animation for "
        "(in case the end frame is very high for no reason)",
        min=0.0,
        max=100000000.0,
        soft_min=1.0,
        soft_max=100000000.0,
        default=8.0,
    )
    anim_screen_switch: FloatProperty(
        name="Screen Switch",
        description="Time between switching screens (in seconds) "
        "or 0 to disable",
        min=0.0,
        max=100000000.0,
        soft_min=1.0,
        soft_max=60.0,
        default=0.0,
    )
    #
    # render
    # ======
    display_render: FloatProperty(
        name="Render Delay",
        description="Time to display the rendered image before moving on "
        "(in seconds)",
        min=0.0,
        max=60.0,
        default=4.0,
    )
    anim_render: BoolProperty(
        name="Render Anim",
        description="Render entire animation (render mode only)",
        default=False,
    )

    def execute(self, context):
        from . import config

        keywords = self.as_keywords(ignore=("directory", "random_order", "run",
                                            "exit"))
        cfg_str, _dirpath = config.as_string(
            self.directory,
            self.random_order,
            self.exit,
            **keywords,
        )
        text = bpy.data.texts.get("demo.py")
        if text:
            text.name += ".back"

        text = bpy.data.texts.new("demo.py")
        text.from_string(cfg_str)

        if self.run:
            extern_demo_mode_run()

        return {'FINISHED'}

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

    def check(self, context):
        return True  # lazy

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

        box = layout.box()
        box.label(text="Search *.blend recursively")
        box.label(text="Writes: demo.py config text")

        layout.prop(self, "run")
        layout.prop(self, "exit")

        layout.label(text="Generate Settings:")
        row = layout.row()
        row.prop(self, "mode", expand=True)
        layout.prop(self, "random_order")

        mode = self.mode

        layout.separator()
        sub = layout.column()
        sub.active = (mode in {'AUTO', 'PLAY'})
        sub.label(text="Animate Settings:")
        sub.prop(self, "anim_cycles")
        sub.prop(self, "anim_time_min")
        sub.prop(self, "anim_time_max")
        sub.prop(self, "anim_screen_switch")

        layout.separator()
        sub = layout.column()
        sub.active = (mode in {'AUTO', 'RENDER'})
        sub.label(text="Render Settings:")
        sub.prop(self, "display_render")
Esempio n. 22
0
def register():
    from bpy.utils import register_class

    # Sub-modules.
    ui.register()
    feature_set_list.register()
    metarig_menu.register()
    operators.register()

    # Classes.
    for cls in classes:
        register_class(cls)

    # Properties.
    bpy.types.Armature.rigify_layers = CollectionProperty(
        type=RigifyArmatureLayer)

    bpy.types.Armature.active_feature_set = EnumProperty(
        items=feature_set_list.feature_set_items,
        name="Feature Set",
        description="Restrict the rig list to a specific custom feature set")

    bpy.types.PoseBone.rigify_type = StringProperty(
        name="Rigify Type", description="Rig type for this bone")
    bpy.types.PoseBone.rigify_parameters = PointerProperty(
        type=RigifyParameters)

    bpy.types.Armature.rigify_colors = CollectionProperty(type=RigifyColorSet)

    bpy.types.Armature.rigify_selection_colors = PointerProperty(
        type=RigifySelectionColors)

    bpy.types.Armature.rigify_colors_index = IntProperty(default=-1)
    bpy.types.Armature.rigify_colors_lock = BoolProperty(default=True)
    bpy.types.Armature.rigify_theme_to_add = EnumProperty(
        items=(('THEME01', 'THEME01', ''), ('THEME02', 'THEME02', ''),
               ('THEME03', 'THEME03', ''), ('THEME04', 'THEME04', ''),
               ('THEME05', 'THEME05', ''), ('THEME06', 'THEME06', ''),
               ('THEME07', 'THEME07', ''), ('THEME08', 'THEME08', ''),
               ('THEME09', 'THEME09', ''), ('THEME10', 'THEME10',
                                            ''), ('THEME11', 'THEME11', ''),
               ('THEME12', 'THEME12', ''), ('THEME13', 'THEME13',
                                            ''), ('THEME14', 'THEME14', ''),
               ('THEME15', 'THEME15', ''), ('THEME16', 'THEME16',
                                            ''), ('THEME17', 'THEME17', ''),
               ('THEME18', 'THEME18', ''), ('THEME19', 'THEME19',
                                            ''), ('THEME20', 'THEME20', '')),
        name='Theme')

    IDStore = bpy.types.WindowManager
    IDStore.rigify_collection = EnumProperty(
        items=(("All", "All", "All"), ),
        default="All",
        name="Rigify Active Collection",
        description="The selected rig collection")

    IDStore.rigify_widgets = CollectionProperty(type=RigifyName)

    IDStore.rigify_types = CollectionProperty(type=RigifyName)
    IDStore.rigify_active_type = IntProperty(
        name="Rigify Active Type", description="The selected rig type")

    bpy.types.Armature.rigify_advanced_generation = BoolProperty(
        name="Advanced Options",
        description=
        "Enables/disables advanced options for Rigify rig generation",
        default=False)

    def update_mode(self, context):
        if self.rigify_generate_mode == 'new':
            self.rigify_force_widget_update = False

    bpy.types.Armature.rigify_generate_mode = EnumProperty(
        name="Rigify Generate Rig Mode",
        description=
        "'Generate Rig' mode. In 'overwrite' mode the features of the target rig will be updated as defined by the metarig. In 'new' mode a new rig will be created as defined by the metarig. Current mode",
        update=update_mode,
        items=(('overwrite', 'overwrite', ''), ('new', 'new', '')))

    bpy.types.Armature.rigify_force_widget_update = BoolProperty(
        name="Force Widget Update",
        description=
        "Forces Rigify to delete and rebuild all the rig widgets. if unset, only missing widgets will be created",
        default=False)

    bpy.types.Armature.rigify_target_rig = PointerProperty(
        type=bpy.types.Object,
        name="Rigify Target Rig",
        description=
        "Defines which rig to overwrite. If unset, a new one called 'rig' will be created",
        poll=lambda self, obj: obj.type == 'ARMATURE' and obj.data is not self)

    bpy.types.Armature.rigify_rig_ui = PointerProperty(
        type=bpy.types.Text,
        name="Rigify Target Rig UI",
        description=
        "Defines the UI to overwrite. If unset, 'rig_ui.py' will be used")

    bpy.types.Armature.rigify_rig_basename = StringProperty(
        name="Rigify Rig Name",
        description=
        "Defines the name of the Rig. If unset, in 'new' mode 'rig' will be used, in 'overwrite' mode the target rig name will be used",
        default="")

    IDStore.rigify_transfer_only_selected = BoolProperty(
        name="Transfer Only Selected",
        description="Transfer selected bones only",
        default=True)

    bpy.context.preferences.addons[
        __package__].preferences.register_feature_sets(True)
    bpy.context.preferences.addons[
        __package__].preferences.update_external_rigs()

    # Add rig parameters
    register_rig_parameters()
Esempio n. 23
0
class ExportQuakeMap(bpy.types.Operator, ExportHelper):
    bl_idname = 'export.map'
    bl_label = bl_info['name']
    bl_description = bl_info['description']
    bl_options = {'UNDO'}
    filename_ext = ".map"
    filter_glob: StringProperty(default="*.map", options={'HIDDEN'})

    option_sel: BoolProperty(name="Selection only", default=True)
    option_geo: EnumProperty(name="Geo",
                             default='Faces',
                             items=(('Brushes', "Brushes",
                                     "Export each object as a convex brush"),
                                    ('Faces', "Faces",
                                     "Export each face as a pyramid brush")))
    option_grid: FloatProperty(name="Grid",
                               default=4.0,
                               description="Snap to grid (0 for off-grid)",
                               min=0.0,
                               max=256.0)
    option_depth: FloatProperty(name="Depth",
                                default=8.0,
                                description="Pyramid poke offset",
                                min=0.0,
                                max=256.0)
    option_format: EnumProperty(name="Format",
                                default='Valve',
                                items=(('Quake', "Standard",
                                        "Axis-aligned texture projection"),
                                       ('Valve', "Valve220",
                                        "Face-bound texture projection")))
    option_dest: EnumProperty(name="Save to",
                              default='File',
                              items=(('File', "File",
                                      "Write data to a .map file"),
                                     ('Clip', "Clipboard",
                                      "Store data in system buffer")))
    option_skip: StringProperty(
        name="Fallback",
        default='skip',
        description="Texture to use on new and unassigned faces")

    def gridsnap(self, vector):
        grid = self.option_grid
        if grid:
            return [round(co / grid) * grid for co in vector]
        else:
            return vector

    def printvec(self, vector):
        return ' '.join([f'{co:.5g}' for co in vector])

    def texdata(self, face, mesh, obj):
        mat = None
        width = height = 64
        if obj.material_slots:
            mat = obj.material_slots[face.material_index].material
        if mat:
            for node in mat.node_tree.nodes:
                if node.type == 'TEX_IMAGE':
                    width, height = node.image.size
                    break
            texstring = mat.name
        else:
            texstring = self.option_skip

        V = [loop.vert.co for loop in face.loops]
        uv_layer = mesh.loops.layers.uv.active
        T = [loop[uv_layer].uv for loop in face.loops]

        # UV handling ported from: https://bitbucket.org/khreathor/obj-2-map

        if self.option_format == 'Valve':
            # [ Ux Uy Uz Uoffs ] [ Vx Vy Vz Voffs ] rotation scaleU scaleV
            dummy = ' [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1\n'

            height = -height  # workaround for flipped v

            # Set up "2d world" coordinate system with the 01 edge along X
            world01 = V[1] - V[0]
            world02 = V[2] - V[0]
            world01_02Angle = world01.angle(world02)
            if face.normal.dot(world01.cross(world02)) < 0:
                world01_02Angle = -world01_02Angle
            world01_2d = Vector((world01.length, 0.0))
            world02_2d = Vector((math.cos(world01_02Angle),
                                 math.sin(world01_02Angle))) * world02.length

            # Get 01 and 02 vectors in UV space and scale them
            tex01 = T[1] - T[0]
            tex02 = T[2] - T[0]
            tex01.x *= width
            tex02.x *= width
            tex01.y *= height
            tex02.y *= height
            '''
            a = world01_2d
            b = world02_2d
            p = tex01
            q = tex02

            [ px ]   [ m11 m12 0 ] [ ax ]
            [ py ] = [ m21 m22 0 ] [ ay ]
            [ 1  ]   [ 0   0   1 ] [ 1  ]

            [ qx ]   [ m11 m12 0 ] [ bx ]
            [ qy ] = [ m21 m22 0 ] [ by ]
            [ 1  ]   [ 0   0   1 ] [ 1  ]

            px = ax * m11 + ay * m12
            py = ax * m21 + ay * m22
            qx = bx * m11 + by * m12
            qy = bx * m21 + by * m22

            [ px ]   [ ax ay 0  0  ] [ m11 ]
            [ py ] = [ 0  0  ax ay ] [ m12 ]
            [ qx ]   [ bx by 0  0  ] [ m21 ]
            [ qy ]   [ 0  0  bx by ] [ m22 ]
            '''

            # Find an affine transformation to convert
            # world01_2d and world02_2d to their respective UV coords
            texCoordsVec = Vector((tex01.x, tex01.y, tex02.x, tex02.y))
            world2DMatrix = Matrix(((world01_2d.x, world01_2d.y, 0,
                                     0), (0, 0, world01_2d.x, world01_2d.y),
                                    (world02_2d.x, world02_2d.y, 0,
                                     0), (0, 0, world02_2d.x, world02_2d.y)))
            try:
                mCoeffs = solve(world2DMatrix, texCoordsVec)
            except:
                return texstring + dummy
            right_2dworld = Vector(mCoeffs[0:2])
            up_2dworld = Vector(mCoeffs[2:4])

            # These are the final scale values
            # (avoid division by 0 for degenerate or missing UVs)
            scalex = 1 / max(0.00001, right_2dworld.length)
            scaley = 1 / max(0.00001, up_2dworld.length)
            scale = Vector((scalex, scaley))

            # Get the angles of the texture axes. These are in the 2d world
            # coordinate system, so they're relative to the 01 vector
            right_2dworld_angle = math.atan2(right_2dworld.y, right_2dworld.x)
            up_2dworld_angle = math.atan2(up_2dworld.y, up_2dworld.x)

            # Recreate the texture axes in 3d world coordinates,
            # using the angles from the 01 edge
            rt = world01.normalized()
            up = rt.copy()
            rt.rotate(Matrix.Rotation(right_2dworld_angle, 3, face.normal))
            up.rotate(Matrix.Rotation(up_2dworld_angle, 3, face.normal))

            # Now we just need the offsets
            rt_full = rt.to_4d()
            up_full = up.to_4d()
            test_s = V[0].dot(rt) / (width * scale.x)
            test_t = V[0].dot(up) / (height * scale.y)
            rt_full[3] = (T[0].x - test_s) * width
            up_full[3] = (T[0].y - test_t) * height

            texstring += f" [ {self.printvec(rt_full)} ]"\
                        f"[ {self.printvec(up_full)} ]"\
                        f" 0 {self.printvec(scale)}\n"

        elif self.option_format == 'Quake':
            # offsetU offsetV rotation scaleU scaleV
            dummy = ' 0 0 0 1 1\n'

            # 01 and 02 in 3D space
            world01 = V[1] - V[0]
            world02 = V[2] - V[0]

            # 01 and 02 projected along the closest axis
            maxn = max(abs(round(crd, 5)) for crd in face.normal)
            for i in [2, 0, 1]:  # axis priority for 45 degree angles
                if round(abs(face.normal[i]), 5) == maxn:
                    axis = i
                    break
            world01_2d = Vector((world01[:axis] + world01[(axis + 1):]))
            world02_2d = Vector((world02[:axis] + world02[(axis + 1):]))

            # 01 and 02 in UV space (scaled to texture size)
            tex01 = T[1] - T[0]
            tex02 = T[2] - T[0]
            tex01.x *= width
            tex02.x *= width
            tex01.y *= height
            tex02.y *= height

            # Find affine transformation between 2D and UV
            texCoordsVec = Vector((tex01.x, tex01.y, tex02.x, tex02.y))
            world2DMatrix = Matrix(((world01_2d.x, world01_2d.y, 0,
                                     0), (0, 0, world01_2d.x, world01_2d.y),
                                    (world02_2d.x, world02_2d.y, 0,
                                     0), (0, 0, world02_2d.x, world02_2d.y)))
            try:
                mCoeffs = solve(world2DMatrix, texCoordsVec)
            except:
                return texstring + dummy

            # Build the transformation matrix and decompose it
            tformMtx = Matrix(((mCoeffs[0], mCoeffs[1], 0),
                               (mCoeffs[2], mCoeffs[3], 0), (0, 0, 1)))
            t0 = Vector((T[0].x * width, T[0].y * height)).to_3d()
            v0 = Vector((V[0][:axis] + V[0][(axis + 1):])).to_3d()

            offset = t0 - (tformMtx @ v0)
            rotation = math.degrees(tformMtx.inverted_safe().to_euler().z)
            scale = tformMtx.inverted_safe().to_scale()  # always positive

            # Compare normals between UV and projection to get the scale sign
            tn = tex01.to_3d().cross(tex02.to_3d())
            vn = world01_2d.to_3d().cross(world02_2d.to_3d())
            if tn.dot(vn) < 0: scale.x *= -1

            # fudge
            offset.x += width
            offset.y *= -1

            finvals = [offset.x, offset.y, rotation, scale.x, scale.y]
            texstring += f" {self.printvec(finvals)}\n"

        return texstring

    def execute(self, context):
        if self.option_sel:
            objects = context.selected_objects
        else:
            objects = context.scene.objects
        objects = [obj for obj in objects if obj.type == 'MESH']

        geo = []
        fw = geo.append
        fw('{\n"classname" "worldspawn"\n')
        if self.option_format == 'Valve':
            fw('"mapversion" "220"\n')
        bm = bmesh.new()

        if self.option_geo == 'Faces' and objects != []:
            orig_mode = context.object.mode
            orig_sel = context.selected_objects
            orig_act = context.active_object
            bpy.ops.object.mode_set(mode='OBJECT')
            bpy.ops.object.select_all(action='DESELECT')
            for obj in objects:
                obj.select_set(True)
            context.view_layer.objects.active = objects[0]
            bpy.ops.object.duplicate()
            bpy.ops.object.join()
            mobj = context.active_object
            mobj.data.materials.append(None)  # empty slot for new faces
            bm.from_mesh(mobj.data)

            for vert in bm.verts:
                vert.co = self.gridsnap(vert.co)
            bmesh.ops.connect_verts_concave(bm, faces=bm.faces)
            bmesh.ops.connect_verts_nonplanar(bm,
                                              faces=bm.faces,
                                              angle_limit=0.0)
            for face in bm.faces[:]:
                fw('{\n')
                for vert in reversed(face.verts[0:3]):
                    fw(f'( {self.printvec(vert.co)} ) ')
                fw(self.texdata(face, bm, mobj))
                pyr = bmesh.ops.poke(bm,
                                     faces=[face],
                                     offset=-self.option_depth)
                apex = pyr['verts'][0].co
                pyr['verts'][0].co = self.gridsnap(apex)
                for pyrface in pyr['faces']:
                    for vert in pyrface.verts[0:3]:  # backfacing
                        fw(f'( {self.printvec(vert.co)} ) ')
                    pyrface.material_index = len(mobj.data.materials) - 1
                    fw(self.texdata(pyrface, bm, mobj))
                fw('}\n')

            bpy.data.objects.remove(mobj)
            for obj in orig_sel:
                obj.select_set(True)
            context.view_layer.objects.active = orig_act
            bpy.ops.object.mode_set(mode=orig_mode)

        elif self.option_geo == 'Brushes':
            for obj in objects:
                bm.from_mesh(obj.data)
                for vert in bm.verts:
                    vert.co = self.gridsnap(vert.co)
                hull = bmesh.ops.convex_hull(bm,
                                             input=bm.verts,
                                             use_existing_faces=True)
                geom = hull['geom'] + hull['geom_holes']
                oldfaces = [face for face in bm.faces if face not in geom]
                bmesh.ops.delete(bm, geom=oldfaces, context='FACES')
                bmesh.ops.recalc_face_normals(bm, faces=bm.faces)
                bmesh.ops.join_triangles(bm,
                                         faces=bm.faces,
                                         angle_face_threshold=0.01,
                                         angle_shape_threshold=0.7)
                bmesh.ops.connect_verts_nonplanar(bm,
                                                  faces=bm.faces,
                                                  angle_limit=0.0)
                fw('{\n')
                for face in bm.faces:
                    for vert in reversed(face.verts[0:3]):
                        fw(f'( {self.printvec(vert.co)} ) ')
                    fw(self.texdata(face, bm, obj))
                fw('}\n')
                bm.clear()

        bm.free()
        fw('}')

        if self.option_dest == 'File':
            with open(self.filepath, 'w') as file:
                file.write(''.join(geo))
        else:
            bpy.context.window_manager.clipboard = ''.join(geo)

        return {'FINISHED'}
Esempio n. 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_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 independent 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,
    )
Esempio n. 25
0
class SvSolidBooleanNode(bpy.types.Node, SverchCustomTreeNode):
    """
    Triggers: Union, Diff, Intersect
    Tooltip: Perform Boolean Operations on Solids
    """
    bl_idname = 'SvSolidBooleanNode'
    bl_label = 'Solid Boolean'
    bl_icon = 'OUTLINER_OB_EMPTY'
    sv_icon = 'SV_SOLID_BOOLEAN'
    solid_catergory = "Operators"

    mode_options = [("ITX", "Intersect", "", 0), ("UNION", "Union", "", 1),
                    ("DIFF", "Difference", "", 2)]

    selected_mode: EnumProperty(name='Operation',
                                items=mode_options,
                                description="basic booleans using solids",
                                default="ITX",
                                update=updateNode)

    @throttled
    def update_mode(self, context):
        self.inputs['Solid A'].hide_safe = self.nest_objs
        self.inputs['Solid B'].hide_safe = self.nest_objs
        self.inputs['Solids'].hide_safe = not self.nest_objs
        self.outputs['EdgesMask'].hide_safe = not self.generate_masks
        self.outputs['EdgeSources'].hide_safe = not self.generate_masks
        self.outputs['FacesMask'].hide_safe = not self.generate_masks
        self.outputs['FaceSources'].hide_safe = not self.generate_masks

    nest_objs: BoolProperty(
        name="Accumulate nested",
        description=
        "bool first two solids, then applies rest to result one by one",
        default=False,
        update=update_mode)

    refine_solid: BoolProperty(
        name="Refine Solid",
        description="Removes redundant edges (may slow the process)",
        default=True,
        update=updateNode)

    generate_masks: BoolProperty(
        name="Generate Masks",
        description=
        "Calculate masks so it will be possible to know which edges / faces are new",
        default=False,
        update=update_mode)

    def draw_buttons(self, context, layout):
        layout.prop(self, "selected_mode", toggle=True)
        layout.prop(self, 'generate_masks', toggle=True)
        layout.prop(self, "nest_objs", toggle=True)
        if self.selected_mode == 'UNION':
            layout.prop(self, "refine_solid")

    def sv_init(self, context):
        self.inputs.new('SvSolidSocket', "Solid A")
        self.inputs.new('SvSolidSocket', "Solid B")
        self.inputs.new('SvSolidSocket', "Solids")

        self.outputs.new('SvSolidSocket', "Solid")
        self.outputs.new('SvStringsSocket', "EdgesMask")
        self.outputs.new('SvStringsSocket', "EdgeSources")
        self.outputs.new('SvStringsSocket', "FacesMask")
        self.outputs.new('SvStringsSocket', "FaceSources")

        self.update_mode(context)

    def make_solid(self, solids):
        if self.generate_masks:
            return self.make_solid_general(solids)
        else:
            solid = self.make_solid_simple(solids)
            return SvBoolResult(solid)

    def make_solid_simple(self, solids):
        base = solids[0].copy()
        rest = solids[1:]
        if self.selected_mode == 'UNION':
            solid = base.fuse(rest)
        elif self.selected_mode == 'ITX':
            solid = base.common(rest)
        elif self.selected_mode == 'DIFF':
            solid = base.cut(rest)
        else:
            raise Exception("Unknown mode")
        do_refine = self.refine_solid and self.selected_mode in {'UNION'}
        if do_refine:
            solid = solid.removeSplitter()
        return solid

    def make_solid_general(self, solids):
        do_refine = self.refine_solid and self.selected_mode in {'UNION'}

        for i in range(len(solids)):
            if not isinstance(solids[i], Part.Solid):
                solids[i] = Part.makeSolid(solids[i])

        fused = SvGeneralFuse(solids)
        if self.selected_mode == 'UNION':
            solid = fused.get_union_all(refine=do_refine)
        elif self.selected_mode == 'ITX':
            solid = fused.get_intersect_all(refine=do_refine)
        elif self.selected_mode == 'DIFF':
            solid = fused.get_clean_part_by_idx(0, refine=do_refine)
        else:
            raise Exception("Unknown mode")

        edge_mask = []
        edge_map = []
        face_mask = []
        face_map = []

        if solid is not None:
            for edge in solid.Edges:
                srcs = fused.get_edge_source_idxs(edge)
                edge_map.append(list(srcs))
                is_new = len(srcs) > 1
                edge_mask.append(is_new)

            for face in solid.Faces:
                srcs = fused.get_face_source_idxs(face)
                face_map.append(list(srcs))
                is_new = len(srcs) > 1
                face_mask.append(is_new)

        return SvBoolResult(solid, edge_mask, edge_map, face_mask, face_map)

    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        solids_out = []
        edge_masks_out = []
        edge_srcs_out = []
        face_masks_out = []
        face_srcs_out = []
        if self.nest_objs:
            solids_in = self.inputs['Solids'].sv_get()
            #level = get_data_nesting_level(solids_in, data_types=(Part.Shape,))
            solids_in = ensure_nesting_level(solids_in,
                                             2,
                                             data_types=(Part.Shape, ))

            for solids in solids_in:
                result = self.make_solid(solids)
                solids_out.append(result.solid)
                edge_masks_out.append(result.edge_mask)
                edge_srcs_out.append(result.edge_map)
                face_masks_out.append(result.face_mask)
                face_srcs_out.append(result.face_map)

        else:
            solids_a_in = self.inputs['Solid A'].sv_get()
            solids_b_in = self.inputs['Solid B'].sv_get()
            level_a = get_data_nesting_level(solids_a_in,
                                             data_types=(Part.Shape, ))
            level_b = get_data_nesting_level(solids_b_in,
                                             data_types=(Part.Shape, ))
            solids_a_in = ensure_nesting_level(solids_a_in,
                                               2,
                                               data_types=(Part.Shape, ))
            solids_b_in = ensure_nesting_level(solids_b_in,
                                               2,
                                               data_types=(Part.Shape, ))
            level = max(level_a, level_b)

            for params in zip_long_repeat(solids_a_in, solids_b_in):
                new_solids = []
                new_edge_masks = []
                new_edge_srcs = []
                new_face_masks = []
                new_face_srcs = []
                for solid_a, solid_b in zip_long_repeat(*params):
                    result = self.make_solid([solid_a, solid_b])
                    new_solids.append(result.solid)
                    new_edge_masks.append(result.edge_mask)
                    new_edge_srcs.append(result.edge_map)
                    new_face_masks.append(result.face_mask)
                    new_face_srcs.append(result.face_map)
                if level == 1:
                    solids_out.extend(new_solids)
                    edge_masks_out.extend(new_edge_masks)
                    edge_srcs_out.extend(new_edge_srcs)
                    face_masks_out.extend(new_face_masks)
                    face_srcs_out.extend(new_face_srcs)
                else:
                    solids_out.append(new_solids)
                    edge_masks_out.append(new_edge_masks)
                    edge_srcs_out.append(new_edge_srcs)
                    face_masks_out.append(new_face_masks)
                    face_srcs_out.append(new_face_srcs)

        self.outputs['Solid'].sv_set(solids_out)
        if 'EdgesMask' in self.outputs:
            self.outputs['EdgesMask'].sv_set(edge_masks_out)
        if 'EdgeSources' in self.outputs:
            self.outputs['EdgeSources'].sv_set(edge_srcs_out)
        if 'FacesMask' in self.outputs:
            self.outputs['FacesMask'].sv_set(face_masks_out)
        if 'FaceSources' in self.outputs:
            self.outputs['FaceSources'].sv_set(face_srcs_out)
Esempio n. 26
0
class ESWC_Info(bpy.types.PropertyGroup):
    bool_show_options = BoolProperty(name="Show options",
                                     description="Show options",
                                     default=False)

    bool_add_scale = BoolProperty(name="Add Scale node",
                                  description="Add Scale node",
                                  default=False)

    # todo: implement update function
    bool_show_compositions = BoolProperty(
        name="Show composite strips",
        description=
        "If activated, the composite are shown in the timeline. Otherwise, the source videos are visible.",
        default=True,
        update=toggle_composition_visibility)

    bool_reuse_compositions = BoolProperty(
        name="Reuse compositions",
        description=
        "When creating compositions for strips, reuse existing compositions that use the same source",
        default=True)

    bool_add_viewer = BoolProperty(
        name="Add Viewer",
        description="You can add a viewer node to the new compositions \
        automatically",
        default=True)

    bool_use_high_bit_depth_fix = BoolProperty(
        name="Use High Bitdepth Fix",
        description=
        "Workaround for 10 Bit videos in compositor while rendering",
        default=True)

    bool_add_group = BoolProperty(
        name="Add Nodegroup",
        description="You can add a custom node group to the new compositions \
        automatically",
        default=False)

    # the input path of the movie file the composition was created from
    # if it is empty, the operators infer that the current scene
    # is not a composition.
    path_input = StringProperty(
        name="Movie strip input",
        default="",
        description="the input path of the movie file the composition was \
            created from")

    # store original strip type so that a strip can be created from the composition
    type_original_strip = StringProperty(
        name="Original strip type",
        default="",
        description="Type of the strip associated with this composition")

    selections = [
        ("All", "All", "Copy all settings"),
        # ( "Select", "Select", "Copy selected settings" ),
        ("None", "None", "Copy none of the settings")
    ]
    settings = EnumProperty(
        name="Settings Type",
        items=selections,
        default="All",
        description=
        "Choose which settings to copy from the source clip to the created composition"
    )

    master_scene = StringProperty(
        name="Master Scene",
        description="This is the name of the Scene's Master Scene",
        default="Scene")

    scene_init_comp = BoolProperty(name="", description="", default=False)

    def avail_nodegroups(self, context):
        items = []
        for i, node_group in enumerate(bpy.data.node_groups):
            items.append((str(i), node_group.name, node_group.name))
        return items

    enum_node_groups = EnumProperty(items=avail_nodegroups, name="Node Group")

    def avail_screens(self, context):
        items = []
        for i, elem in enumerate(bpy.data.workspaces):
            items.append((elem.name, elem.name, elem.name))
        return items

    enum_edit_screen = EnumProperty(items=avail_screens,
                                    name="Editing Workspace")

    enum_comp_screen = EnumProperty(items=avail_screens,
                                    name="Compositing Workspace")
Esempio n. 27
0
class SverchokPreferences(AddonPreferences):

    bl_idname = __package__

    def update_debug_mode(self, context):
        data_structure.DEBUG_MODE = self.show_debug

    def update_heat_map(self, context):
        data_structure.heat_map_state(self.heat_map)

    def set_frame_change(self, context):
        handlers.set_frame_change(self.frame_change_mode)

    def update_theme(self, context):
        color_def.rebuild_color_cache()
        if self.auto_apply_theme:
            color_def.apply_theme()

    tab_modes = [(k, k, '', i)
                 for i, k in enumerate(["General", "Node Defaults", "Theme"])]

    selected_tab = bpy.props.EnumProperty(items=tab_modes,
                                          description="pick viewing mode",
                                          default="General")

    #  debugish...
    show_debug = BoolProperty(name="Print update timings",
                              description="Print update timings in console",
                              default=False,
                              subtype='NONE',
                              update=update_debug_mode)

    no_data_color = FloatVectorProperty(
        name="No data",
        description='When a node can not get data',
        size=3,
        min=0.0,
        max=1.0,
        default=(1, 0.3, 0),
        subtype='COLOR',
        update=update_system.update_error_colors)

    exception_color = FloatVectorProperty(
        name="Error",
        description='When node has an exception',
        size=3,
        min=0.0,
        max=1.0,
        default=(0.8, 0.0, 0),
        subtype='COLOR',
        update=update_system.update_error_colors)

    #  heat map settings
    heat_map = BoolProperty(name="Heat map",
                            description="Color nodes according to time",
                            default=False,
                            subtype='NONE',
                            update=update_heat_map)

    heat_map_hot = FloatVectorProperty(name="Heat map hot",
                                       description='',
                                       size=3,
                                       min=0.0,
                                       max=1.0,
                                       default=(.8, 0, 0),
                                       subtype='COLOR')

    heat_map_cold = FloatVectorProperty(name="Heat map cold",
                                        description='',
                                        size=3,
                                        min=0.0,
                                        max=1.0,
                                        default=(1, 1, 1),
                                        subtype='COLOR')

    # Profiling settings
    profiling_sections = [
        ("NONE", "Disable", "Disable profiling", 0),
        ("MANUAL", "Marked methods only",
         "Profile only methods that are marked with @profile decorator", 1),
        ("UPDATE", "Node tree update",
         "Profile whole node tree update process", 2)
    ]

    profile_mode = EnumProperty(name="Profiling mode",
                                items=profiling_sections,
                                default="NONE",
                                description="Performance profiling mode")

    developer_mode = BoolProperty(
        name="Developer mode",
        description=
        "Show some additional panels or features useful for Sverchok developers only",
        default=False)

    #  theme settings

    sv_theme = EnumProperty(items=color_def.themes,
                            name="Theme preset",
                            description="Select a theme preset",
                            update=color_def.color_callback,
                            default="default_theme")

    auto_apply_theme = BoolProperty(name="Apply theme",
                                    description="Apply theme automaticlly",
                                    default=False)

    apply_theme_on_open = BoolProperty(name="Apply theme",
                                       description="Apply theme automaticlly",
                                       default=False)

    color_viz = FloatVectorProperty(name="Visualization",
                                    description='',
                                    size=3,
                                    min=0.0,
                                    max=1.0,
                                    default=(1, 0.3, 0),
                                    subtype='COLOR',
                                    update=update_theme)

    color_tex = FloatVectorProperty(name="Text",
                                    description='',
                                    size=3,
                                    min=0.0,
                                    max=1.0,
                                    default=(0.5, 0.5, 1),
                                    subtype='COLOR',
                                    update=update_theme)

    color_sce = FloatVectorProperty(name="Scene",
                                    description='',
                                    size=3,
                                    min=0.0,
                                    max=1.0,
                                    default=(0, 0.5, 0.2),
                                    subtype='COLOR',
                                    update=update_theme)

    color_lay = FloatVectorProperty(name="Layout",
                                    description='',
                                    size=3,
                                    min=0.0,
                                    max=1.0,
                                    default=(0.674, 0.242, 0.363),
                                    subtype='COLOR',
                                    update=update_theme)

    color_gen = FloatVectorProperty(name="Generator",
                                    description='',
                                    size=3,
                                    min=0.0,
                                    max=1.0,
                                    default=(0, 0.5, 0.5),
                                    subtype='COLOR',
                                    update=update_theme)

    #  frame change
    frame_change_modes = [
        ("PRE", "Pre", "Update Sverchok before frame change", 0),
        ("POST", "Post", "Update Sverchok after frame change", 1),
        ("NONE", "None", "Sverchok doesn't update on frame change", 2)
    ]

    frame_change_mode = EnumProperty(items=frame_change_modes,
                                     name="Frame change",
                                     description="Select frame change handler",
                                     default="POST",
                                     update=set_frame_change)

    #  ctrl+space settings

    show_icons = BoolProperty(name="Show icons in ctrl+space menu",
                              default=False,
                              description="Use icons in ctrl+space menu")

    over_sized_buttons = BoolProperty(default=False,
                                      name="Big buttons",
                                      description="Very big buttons")

    enable_live_objin = BoolProperty(
        description="Objects in edit mode will be updated in object-in Node")

    render_scale = FloatProperty(default=1.0,
                                 min=0.01,
                                 step=0.01,
                                 description='default render scale')

    render_location_xy_multiplier = FloatProperty(
        default=1.0,
        min=0.01,
        step=0.01,
        description='default render location xy multiplier')

    stethoscope_view_scale = FloatProperty(
        default=1.0,
        min=0.01,
        step=0.01,
        description='default stethoscope scale')

    index_viewer_scale = FloatProperty(
        default=1.0,
        min=0.01,
        step=0.01,
        description='default index viewer scale')

    datafiles = os.path.join(
        bpy.utils.user_resource('DATAFILES', path='sverchok', create=True))
    defaults_location = StringProperty(
        default=datafiles,
        description='usually ..data_files\\sverchok\\defaults\\nodes.json')
    external_editor = StringProperty(
        description='which external app to invoke to view sources')
    real_sverchok_path = StringProperty(
        description='use with symlinked to get correct src->dst')

    # Logging settings

    def update_log_level(self, context):
        logging.info("Setting log level to %s", self.log_level)
        logging.setLevel(self.log_level)

    log_levels = [("DEBUG", "Debug", "Debug output", 0),
                  ("INFO", "Information", "Informational output", 1),
                  ("WARNING", "Warnings", "Show only warnings and errors", 2),
                  ("ERROR", "Errors", "Show errors only", 3)]

    log_level = EnumProperty(
        name="Logging level",
        description=
        "Minimum events severity level to output. All more severe messages will be logged as well.",
        items=log_levels,
        update=update_log_level,
        default="INFO")

    log_to_buffer = BoolProperty(
        name="Log to text buffer",
        description="Enable log output to internal Blender's text buffer",
        default=True)
    log_to_buffer_clean = BoolProperty(
        name="Clear buffer at startup",
        description="Clear text buffer at each Blender startup",
        default=False)
    log_to_file = BoolProperty(
        name="Log to file",
        description="Enable log output to external file",
        default=False)
    log_to_console = BoolProperty(
        name="Log to console",
        description=
        "Enable log output to console / terminal / standard output.",
        default=True)

    log_buffer_name = StringProperty(name="Buffer name",
                                     default="sverchok.log")
    log_file_name = StringProperty(name="File path",
                                   default=os.path.join(
                                       datafiles, "sverchok.log"))

    # updating sverchok
    dload_archive_name = StringProperty(name="archive name", default="master")
    dload_archive_path = StringProperty(
        name="archive path",
        default="https://github.com/nortikin/sverchok/archive/")

    def draw(self, context):

        layout = self.layout
        layout.row().prop(self, 'selected_tab', expand=True)

        if self.selected_tab == "General":

            col = layout.row().column()
            col_split = col.split(0.5)
            col1 = col_split.column()
            col1.label(text="UI:")
            col1.prop(self, "show_icons")
            col1.prop(self, "over_sized_buttons")
            col1.prop(self, "enable_live_objin", text='Enable Live Object-In')
            col1.prop(self, "external_editor", text="Ext Editor")
            col1.prop(self, "real_sverchok_path", text="Src Directory")

            col2 = col_split.split().column()
            col2.label(text="Frame change handler:")
            col2.row().prop(self, "frame_change_mode", expand=True)
            col2.separator()

            col2box = col2.box()
            col2box.label(text="Debug:")
            col2box.prop(self, "profile_mode")
            col2box.prop(self, "show_debug")
            col2box.prop(self, "heat_map")
            col2box.prop(self, "developer_mode")

            log_box = col2.box()
            log_box.label(text="Logging:")
            log_box.prop(self, "log_level")

            buff_row = log_box.row()
            buff_row.prop(self, "log_to_buffer")
            if self.log_to_buffer:
                buff_row.prop(self, "log_buffer_name")
                log_box.prop(self, "log_to_buffer_clean")

            file_row = log_box.row()
            file_row.prop(self, "log_to_file")
            if self.log_to_file:
                file_row.prop(self, "log_file_name")

            log_box.prop(self, "log_to_console")

        if self.selected_tab == "Node Defaults":

            row = layout.row()
            col = row.column(align=True)
            row_sub1 = col.row().split(0.5)
            box_sub1 = row_sub1.box()
            box_sub1_col = box_sub1.column(align=True)
            box_sub1_col.label('Render Scale & Location')
            box_sub1_col.prop(self,
                              'render_location_xy_multiplier',
                              text='xy multiplier')
            box_sub1_col.prop(self, 'render_scale', text='scale')
            box_sub1_col.label('Stethoscope MK2 settings')
            box_sub1_col.prop(self, 'stethoscope_view_scale', text='scale')
            box_sub1_col.label('Index Viewer settings')
            box_sub1_col.prop(self, 'index_viewer_scale', text='scale')

            col3 = row_sub1.split().column()
            col3.label('Location of custom defaults')
            col3.prop(self, 'defaults_location', text='')

        if self.selected_tab == "Theme":

            row = layout.row()
            col = row.column(align=True)
            split = col.row().split(0.66)
            split2 = col.row().split(0.66)
            left_split = split.row()
            right_split = split.row()

            split_viz_colors = left_split.column().split(percentage=0.5,
                                                         align=True)

            if True:
                col1 = split_viz_colors.column()
                for name in ['color_viz', 'color_tex', 'color_sce']:
                    r = col1.row()
                    r.prop(self, name)

                col2 = split_viz_colors.column()
                for name in ['color_lay', 'color_gen']:
                    r = col2.row()
                    r.prop(self, name)

            split_extra_colors = split2.column().split()
            col_x1 = split_extra_colors.column()
            col_x1.label("Error colors: ( error / no data )")
            row_x1 = col_x1.row()
            row_x1.prop(self, "exception_color", text='')
            row_x1.prop(self, "no_data_color", text='')

            col_x2 = split_extra_colors.split().column()
            col_x2.label("Heat map colors: ( hot / cold )")
            row_x2 = col_x2.row()
            row_x2.active = self.heat_map
            row_x2.prop(self, "heat_map_hot", text='')
            row_x2.prop(self, "heat_map_cold", text='')

            col3 = right_split.column()
            col3.label('Theme:')
            col3.prop(self, 'sv_theme', text='')
            col3.separator()
            col3.prop(self,
                      'auto_apply_theme',
                      text="Auto apply theme changes")
            col3.prop(self,
                      'apply_theme_on_open',
                      text="Apply theme when opening file")
            col3.operator('node.sverchok_apply_theme',
                          text="Apply theme to layouts")

        # FOOTER

        row = layout.row()
        col = row.column(align=True)
        col.label(text="Links:")
        row1 = col.row(align=True)
        row1.scale_y = 2.0
        row1.operator('wm.url_open', text='Sverchok home page'
                      ).url = 'http://nikitron.cc.ua/blend_scripts.html'
        row1.operator('wm.url_open', text='Documentation'
                      ).url = 'http://nikitron.cc.ua/sverch/html/main.html'

        if context.scene.sv_new_version:
            row1.operator('node.sverchok_update_addon',
                          text='Upgrade Sverchok addon')
        else:
            row1.operator('node.sverchok_check_for_upgrades_wsha',
                          text='Check for new version')
Esempio n. 28
0
class UI_OT_i18n_updatetranslation_svn_statistics(Operator):
    """Create or extend a 'i18n_info.txt' Text datablock"""
    """(it will contain statistics and checks about current branches and/or trunk)"""
    bl_idname = "ui.i18n_updatetranslation_svn_statistics"
    bl_label = "Update I18n Statistics"

    use_branches: BoolProperty(
        name="Check Branches",
        description="Check po files in branches",
        default=True,
    )

    use_trunk: BoolProperty(
        name="Check Trunk",
        description="Check po files in trunk",
        default=False,
    )

    report_name = "i18n_info.txt"

    def execute(self, context):
        if not hasattr(self, "settings"):
            self.settings = settings.settings
        i18n_sett = context.window_manager.i18n_update_svn_settings

        buff = io.StringIO()
        lst = []
        if self.use_branches:
            lst += [(lng, lng.po_path) for lng in i18n_sett.langs]
        if self.use_trunk:
            lst += [(lng, lng.po_path_trunk) for lng in i18n_sett.langs
                    if lng.uid not in self.settings.IMPORT_LANGUAGES_SKIP]

        context.window_manager.progress_begin(0, len(lst))
        context.window_manager.progress_update(0)
        for progress, (lng, path) in enumerate(lst):
            context.window_manager.progress_update(progress + 1)
            if not lng.use:
                print("Skipping {} language ({}).".format(lng.name, lng.uid))
                continue
            buff.write("Processing {} language ({}, {}).\n".format(
                lng.name, lng.uid, path))
            po = utils_i18n.I18nMessages(uid=lng.uid,
                                         kind='PO',
                                         src=path,
                                         settings=self.settings)
            po.print_info(prefix="    ", output=buff.write)
            errs = po.check(fix=False)
            if errs:
                buff.write("    WARNING! Po contains following errors:\n")
                buff.write("        " + "\n        ".join(errs))
                buff.write("\n")
            buff.write("\n\n")

        text = None
        if self.report_name not in bpy.data.texts:
            text = bpy.data.texts.new(self.report_name)
        else:
            text = bpy.data.texts[self.report_name]
        data = text.as_string()
        data = data + "\n" + buff.getvalue()
        text.from_string(data)
        self.report({'INFO'}, "Info written to {} text datablock!".format(
            self.report_name))
        context.window_manager.progress_end()

        return {'FINISHED'}

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_dialog(self)
Esempio n. 29
0
class SvTimerNode(bpy.types.Node, SverchCustomTreeNode, SvAnimatableNode):
    """
    Triggers: Timer, Elapse
    Tooltip: Manage elapsed time via Start, Stop, Pause, Reset, Expire operations.
    """
    bl_idname = 'SvTimerNode'
    bl_label = 'Timer'
    bl_icon = 'PREVIEW_RANGE'

    timers: CollectionProperty(name="Timers", type=SvTimerPropertyGroup)

    properties_to_skip_iojson = ['timers']

    def update_time_slider(self, context):
        ''' Callback to update timers time when scrubbing the timer slider '''
        if self.inhibit_update:
            return

        for timer in self.timers:
            timer.scrub_time(self.timer_slider * timer.timer_duration)

        updateNode(self, context)

    def update_duration(self, context):
        ''' Update the timer slider when the node duration updates '''
        time = get_average([timer.timer_time for timer in self.timers])
        duration = self.timer_duration
        slider_value = min(1.0, max(0.0, time / duration))
        self.sync_time_slider(slider_value)

        updateNode(self, context)

    timer_slider: FloatProperty(
        name="Slider",
        description="Time slider for scrubbing and feedback",
        default=0.0,
        min=0.0,
        max=1.0,
        precision=3,
        update=update_time_slider)

    timer_duration: FloatProperty(
        name="Duration",
        description="Time after which the timer expires",
        default=10.0,
        min=0.0,
        update=update_duration)

    timer_speed: FloatProperty(
        name="Speed",
        description="Time speed as a multiplier of playback time",
        default=1.0,
        update=updateNode)

    timer_loops: IntProperty(
        name="Loops",
        description="Number of times it loops until expires (0 = no loop)",
        default=0,
        min=0)

    normalize: BoolProperty(
        name="normalize",
        description="Display times as percetage of the duration",
        default=False,
        update=updateNode)

    inhibit_update: BoolProperty(name="Inhibiter",
                                 description="Inhibit the update calls",
                                 default=False)

    absolute: BoolProperty(name="Absolute",
                           description="Absolute time reference",
                           default=False)

    sticky: BoolProperty(
        name="Sticky",
        description="Make timer stick to the STOPPED/EXPIRED ends",
        default=False)

    def sync_time_slider(self, value):
        self.inhibit_update = True
        self.timer_slider = value
        self.inhibit_update = False

    def draw_buttons(self, context, layout):
        cb = SvTimerOperatorCallback.bl_idname

        box = layout.box()

        row = box.row(align=True)
        split = row.split(align=True, factor=1 / 4)

        reset_button = split.operator(cb, text='', icon="REW")
        reset_button.function_name = "reset_timer"

        split = split.split(align=True, factor=2 / 3)

        timer_status = TIMER_STATUS_PAUSED
        for timer in self.timers:
            if timer.timer_status == TIMER_STATUS_STARTED:
                timer_status = TIMER_STATUS_STARTED
                break

        if timer_status == TIMER_STATUS_STARTED:
            pause_button = split.operator(cb, text='', icon="PAUSE")
            pause_button.function_name = "pause_timer"
        else:  # PAUSED
            start_button = split.operator(cb, text='', icon='PLAY')
            start_button.function_name = "start_timer"

        expire_button = split.operator(cb, text='', icon='FF')
        expire_button.function_name = "expire_timer"

        row = box.row(align=True)

        loop_backward_button = row.operator(cb, text='', icon="LOOP_BACK")
        loop_backward_button.function_name = "loop_backward_timer"

        row.prop(self, 'timer_slider', text="", slider=True)

        loop_forward_button = row.operator(cb, text='', icon='LOOP_FORWARDS')
        loop_forward_button.function_name = "loop_forward_timer"

        col = layout.column(align=True)
        col.prop(self, "normalize", text="Normalize Time")

    def draw_buttons_ext(self, context, layout):
        self.draw_buttons(context, layout)
        self.draw_animatable_buttons(layout)
        layout.prop(self, "absolute")
        layout.prop(self, "sticky")

    def start_timer(self, context):
        debug("* Timer: start_timer")
        for timer in self.timers:
            timer.start()
        updateNode(self, context)

    def stop_timer(self, context):
        debug("* Timer: stop_timer")
        for timer in self.timers:
            timer.stop()
        self.sync_time_slider(0)
        updateNode(self, context)

    def pause_timer(self, context):
        debug("* Timer: pause_timer")
        for timer in self.timers:
            timer.pause()
        updateNode(self, context)

    def reset_timer(self, context):
        debug("* Timer: reset_timer")
        for timer in self.timers:
            timer.reset()
        self.sync_time_slider(0)
        updateNode(self, context)

    def expire_timer(self, context):
        debug("* Timer: expire_timer")
        for timer in self.timers:
            timer.expire()
        self.sync_time_slider(1)
        updateNode(self, context)

    def loop_backward_timer(self, context):
        debug("* Timer: loop_backward_timer")
        for timer in self.timers:
            timer.loop_backward()
        self.sync_time_slider(0)
        updateNode(self, context)

    def loop_forward_timer(self, context):
        debug("* Timer: loop_forward_timer")
        for timer in self.timers:
            timer.loop_forward()
        self.sync_time_slider(1)
        updateNode(self, context)

    def sv_init(self, context):
        self.width = 150
        self.inputs.new('SvStringsSocket',
                        "Duration").prop_name = "timer_duration"
        self.inputs.new('SvStringsSocket', "Speed").prop_name = "timer_speed"
        self.inputs.new('SvStringsSocket', "Loops").prop_name = "timer_loops"
        self.inputs.new('SvStringsSocket', "Operation")

        self.outputs.new('SvStringsSocket', "Status")
        self.outputs.new('SvStringsSocket', "Elapsed Time")
        self.outputs.new('SvStringsSocket', "Remaining Time")
        self.outputs.new('SvStringsSocket', "Expired")
        self.outputs.new('SvStringsSocket', "Loop")

    def process(self):
        # return if no outputs are connected
        if not any(s.is_linked for s in self.outputs):
            return

        # input values lists (single or multi value)
        input_loops = self.inputs["Loops"].sv_get()[0]
        input_speed = self.inputs["Speed"].sv_get()[0]
        input_duration = self.inputs["Duration"].sv_get()[0]
        input_operation = self.inputs["Operation"].sv_get(default=[[-1]])[0]

        # sanitize the inputs
        input_loops = list(map(lambda n: max(0, n), input_loops))
        input_duration = list(map(lambda d: max(EPSILON, d), input_duration))

        # update the array of timers
        parameters = match_long_repeat(
            [input_loops, input_speed, input_duration, input_operation])

        old_timer_count = len(self.timers)
        new_timer_count = len(parameters[0])
        # debug("we need {0} timers".format(new_timer_count))
        # debug("old_timer_count = {0}".format(old_timer_count))
        # debug("new_timer_count = {0}".format(new_timer_count))

        # did the number of timers change ? => add or remove timers
        if old_timer_count != new_timer_count:
            if new_timer_count > old_timer_count:  # add new timers
                for n in range(old_timer_count, new_timer_count):
                    # debug("creating new timer: {0}".format(n))
                    timer = self.timers.add()
                    timer.timer_id = n
            else:  # remove old timers
                while len(self.timers) > new_timer_count:
                    n = len(self.timers) - 1
                    # debug("removing old timer: {0}".format(self.timers[n].timer_id))
                    self.timers.remove(n)

        # process timers
        status_list = []
        elapsed_list = []
        remaining_list = []
        expired_list = []
        loop_list = []
        for index, params in enumerate(zip(*parameters)):
            loops, speed, duration, operation = params
            # update timer
            timer = self.timers[index]
            timer.update_time(loops, speed, duration, operation, self.absolute,
                              self.sticky)
            # update lists
            status_list.append(timer.status())
            elapsed_list.append(timer.elapsed_time(self.normalize))
            remaining_list.append(timer.remaining_time(self.normalize))
            expired_list.append(timer.expired())
            loop_list.append(timer.loop_count())

        # update slider if needed (todo: figure out a better way to do this)
        time = get_average([timer.timer_time for timer in self.timers])
        duration = get_average([timer.timer_duration for timer in self.timers])
        slider_value = min(1.0, max(0.0, time / duration))
        self.sync_time_slider(slider_value)

        self.outputs["Status"].sv_set([status_list])
        self.outputs["Elapsed Time"].sv_set([elapsed_list])
        self.outputs["Remaining Time"].sv_set([remaining_list])
        self.outputs["Expired"].sv_set([expired_list])
        self.outputs["Loop"].sv_set([loop_list])
Esempio n. 30
0
class ShapeTransfer(Operator):
    '''Copy another selected objects active shape to this one by ''' \
    '''applying the relative offsets'''

    bl_idname = "object.shape_key_transfer"
    bl_label = "Transfer Shape Key"
    bl_options = {'REGISTER', 'UNDO'}

    mode = EnumProperty(
            items=(('OFFSET',
                    "Offset",
                    "Apply the relative positional offset",
                    ),
                   ('RELATIVE_FACE',
                    "Relative Face",
                    "Calculate relative position (using faces)",
                    ),
                   ('RELATIVE_EDGE',
                   "Relative Edge",
                   "Calculate relative position (using edges)",
                   ),
                   ),
            name="Transformation Mode",
            description="Relative shape positions to the new shape method",
            default='OFFSET',
            )
    use_clamp = BoolProperty(
            name="Clamp Offset",
            description=("Clamp the transformation to the distance each "
                         "vertex moves in the original shape"),
            default=False,
            )

    def _main(self, ob_act, objects, mode='OFFSET', use_clamp=False):

        def me_nos(verts):
            return [v.normal.copy() for v in verts]

        def me_cos(verts):
            return [v.co.copy() for v in verts]

        def ob_add_shape(ob, name):
            me = ob.data
            key = ob.shape_key_add(from_mix=False)
            if len(me.shape_keys.key_blocks) == 1:
                key.name = "Basis"
                key = ob.shape_key_add(from_mix=False)  # we need a rest
            key.name = name
            ob.active_shape_key_index = len(me.shape_keys.key_blocks) - 1
            ob.show_only_shape_key = True

        from mathutils.geometry import barycentric_transform
        from mathutils import Vector

        if use_clamp and mode == 'OFFSET':
            use_clamp = False

        me = ob_act.data
        orig_key_name = ob_act.active_shape_key.name

        orig_shape_coords = me_cos(ob_act.active_shape_key.data)

        orig_normals = me_nos(me.vertices)
        # actual mesh vertex location isn't as reliable as the base shape :S
        #~ orig_coords = me_cos(me.vertices)
        orig_coords = me_cos(me.shape_keys.key_blocks[0].data)

        for ob_other in objects:
            me_other = ob_other.data
            if len(me_other.vertices) != len(me.vertices):
                self.report({'WARNING'},
                            ("Skipping '%s', "
                             "vertex count differs") % ob_other.name)
                continue

            target_normals = me_nos(me_other.vertices)
            if me_other.shape_keys:
                target_coords = me_cos(me_other.shape_keys.key_blocks[0].data)
            else:
                target_coords = me_cos(me_other.vertices)

            ob_add_shape(ob_other, orig_key_name)

            # editing the final coords, only list that stores wrapped coords
            target_shape_coords = [v.co for v in
                                   ob_other.active_shape_key.data]

            median_coords = [[] for i in range(len(me.vertices))]

            # Method 1, edge
            if mode == 'OFFSET':
                for i, vert_cos in enumerate(median_coords):
                    vert_cos.append(target_coords[i] +
                                    (orig_shape_coords[i] - orig_coords[i]))

            elif mode == 'RELATIVE_FACE':
                for face in me.faces:
                    i1, i2, i3, i4 = face.vertices_raw
                    if i4 != 0:
                        pt = barycentric_transform(orig_shape_coords[i1],
                                                   orig_coords[i4],
                                                   orig_coords[i1],
                                                   orig_coords[i2],
                                                   target_coords[i4],
                                                   target_coords[i1],
                                                   target_coords[i2],
                                                   )
                        median_coords[i1].append(pt)

                        pt = barycentric_transform(orig_shape_coords[i2],
                                                   orig_coords[i1],
                                                   orig_coords[i2],
                                                   orig_coords[i3],
                                                   target_coords[i1],
                                                   target_coords[i2],
                                                   target_coords[i3],
                                                   )
                        median_coords[i2].append(pt)

                        pt = barycentric_transform(orig_shape_coords[i3],
                                                   orig_coords[i2],
                                                   orig_coords[i3],
                                                   orig_coords[i4],
                                                   target_coords[i2],
                                                   target_coords[i3],
                                                   target_coords[i4],
                                                   )
                        median_coords[i3].append(pt)

                        pt = barycentric_transform(orig_shape_coords[i4],
                                                   orig_coords[i3],
                                                   orig_coords[i4],
                                                   orig_coords[i1],
                                                   target_coords[i3],
                                                   target_coords[i4],
                                                   target_coords[i1],
                                                   )
                        median_coords[i4].append(pt)

                    else:
                        pt = barycentric_transform(orig_shape_coords[i1],
                                                   orig_coords[i3],
                                                   orig_coords[i1],
                                                   orig_coords[i2],
                                                   target_coords[i3],
                                                   target_coords[i1],
                                                   target_coords[i2],
                                                   )
                        median_coords[i1].append(pt)

                        pt = barycentric_transform(orig_shape_coords[i2],
                                                   orig_coords[i1],
                                                   orig_coords[i2],
                                                   orig_coords[i3],
                                                   target_coords[i1],
                                                   target_coords[i2],
                                                   target_coords[i3],
                                                   )
                        median_coords[i2].append(pt)

                        pt = barycentric_transform(orig_shape_coords[i3],
                                                   orig_coords[i2],
                                                   orig_coords[i3],
                                                   orig_coords[i1],
                                                   target_coords[i2],
                                                   target_coords[i3],
                                                   target_coords[i1],
                                                   )
                        median_coords[i3].append(pt)

            elif mode == 'RELATIVE_EDGE':
                for ed in me.edges:
                    i1, i2 = ed.vertices
                    v1, v2 = orig_coords[i1], orig_coords[i2]
                    edge_length = (v1 - v2).length
                    n1loc = v1 + orig_normals[i1] * edge_length
                    n2loc = v2 + orig_normals[i2] * edge_length

                    # now get the target nloc's
                    v1_to, v2_to = target_coords[i1], target_coords[i2]
                    edlen_to = (v1_to - v2_to).length
                    n1loc_to = v1_to + target_normals[i1] * edlen_to
                    n2loc_to = v2_to + target_normals[i2] * edlen_to

                    pt = barycentric_transform(orig_shape_coords[i1],
                        v2, v1, n1loc,
                        v2_to, v1_to, n1loc_to)
                    median_coords[i1].append(pt)

                    pt = barycentric_transform(orig_shape_coords[i2],
                        v1, v2, n2loc,
                        v1_to, v2_to, n2loc_to)
                    median_coords[i2].append(pt)

            # apply the offsets to the new shape
            from functools import reduce
            VectorAdd = Vector.__add__

            for i, vert_cos in enumerate(median_coords):
                if vert_cos:
                    co = reduce(VectorAdd, vert_cos) / len(vert_cos)

                    if use_clamp:
                        # clamp to the same movement as the original
                        # breaks copy between different scaled meshes.
                        len_from = (orig_shape_coords[i] -
                                    orig_coords[i]).length
                        ofs = co - target_coords[i]
                        ofs.length = len_from
                        co = target_coords[i] + ofs

                    target_shape_coords[i][:] = co

        return {'FINISHED'}

    @classmethod
    def poll(cls, context):
        obj = context.active_object
        return (obj and obj.mode != 'EDIT')

    def execute(self, context):
        ob_act = context.active_object
        objects = [ob for ob in context.selected_editable_objects
                   if ob != ob_act]

        if 1:  # swap from/to, means we cant copy to many at once.
            if len(objects) != 1:
                self.report({'ERROR'},
                            ("Expected one other selected "
                             "mesh object to copy from"))

                return {'CANCELLED'}
            ob_act, objects = objects[0], [ob_act]

        if ob_act.type != 'MESH':
            self.report({'ERROR'}, "Other object is not a mesh")
            return {'CANCELLED'}

        if ob_act.active_shape_key is None:
            self.report({'ERROR'}, "Other object has no shape key")
            return {'CANCELLED'}
        return self._main(ob_act, objects, self.mode, self.use_clamp)