Beispiel #1
0
    def draw(self, context):
        if addon_exists("kitops"):
            from kitops.addon.interface.panel import KO_PT_ui
            KO_PT_ui.draw(self, context)

            from kitops.addon.utility.addon import preference

            preference = preference()

            self.layout.separator()

            row = self.layout.row()
            row.label(text='Sort Modifiers')
            row.prop(preference, 'sort_modifiers', text='')

            if preference.sort_modifiers:
                row = self.layout.row(align=True)
                row.alignment = 'RIGHT'
                row.prop(preference, 'sort_bevel', text='', icon='MOD_BEVEL')
                row.prop(preference,
                         'sort_weighted_normal',
                         text='',
                         icon='MOD_NORMALEDIT')
                row.prop(preference, 'sort_array', text='', icon='MOD_ARRAY')
                row.prop(preference, 'sort_mirror', text='', icon='MOD_MIRROR')
                row.prop(preference,
                         'sort_simple_deform',
                         text='',
                         icon='MOD_SIMPLEDEFORM')
                row.prop(preference,
                         'sort_triangulate',
                         text='',
                         icon='MOD_TRIANGULATE')
Beispiel #2
0
    def draw(self, context):
        """Draw all options for the user to input to."""
        layout = self.layout
        scene = context.scene
        option = addon.option()

        col = layout.column(align=True)
        col.operator('ko.synth_bake', text="Bake Object", icon='EXPERIMENTAL')
        col.operator('ko.remove_wire_inserts',
                     text='Remove Unused Wire INSERTs',
                     icon='MESH_ICOSPHERE')
        col.operator('ko.synth_refresh_kpacks',
                     text='Refresh KIT OPS KPACKS',
                     icon='FILE_REFRESH')
        # col.operator('ko.synth_recalc_normals', text='Recalculate Normals', icon='NORMALS_FACE') TODO recalculate normals may still be introduced
        col.operator('ko.synth_reset_all',
                     text='Reset SYNTH Settings',
                     icon='DECORATE_OVERRIDE')

        col.separator()
        col.label(text='KIT OPS')
        kitops_preference = kitops_addon.preference()
        box = col.box()
        row = box.row()
        row.label(text='Mode')
        row.prop(kitops_preference, 'mode', expand=True)
Beispiel #3
0
def insert_add(op, context, boolean_solver):

    if bpy.app.version[1] > 90:
        kitops_preference = kitops_addon.preference()
        old_boolean_solver_ref = kitops_preference.boolean_solver

    uid = ''

    try:
        if bpy.app.version[1] > 90:
            kitops_preference.boolean_solver = boolean_solver

        uid = insert.add(op, context)

    except OSError:
        report_message = 'Failed to load .blend file for INSERT.'
        op.report({'ERROR'}, report_message)
    finally:
        if bpy.app.version[1] > 90:
            kitops_preference.boolean_solver = old_boolean_solver_ref

    return uid
Beispiel #4
0
def add_random_insert(op,
                      context,
                      layer,
                      inserts,
                      insert_frame_cache,
                      rng=np.random.RandomState(123456),
                      insert_name_ignore_list=[]):
    """Searches for and returns a random INSERT."""

    option = addon.option()

    layer_inserts = [
        insert for insert in inserts
        if insert.insert_name not in insert_name_ignore_list
    ]

    # construct probability profile
    p = []
    total = len(layer_inserts)
    total_probabilities = 0
    probabilities = []
    for insert_entry in layer_inserts:
        if insert_entry.is_enabled:
            probability = insert_entry.proportionality
        else:
            probability = 0
        probabilities.append(probability)
        total_probabilities += probability

    if total_probabilities != 0:
        for probability in probabilities:
            p.append(probability / total_probabilities)

        random_insert_index = rng.choice(range(0, len(layer_inserts)), p=p)
        random_insert = layer_inserts[random_insert_index]

        category_name = random_insert.category

        if bpy.app.version[1] > 90:
            kitops_preference = kitops_addon.preference()
            old_boolean_solver_ref = kitops_preference.boolean_solver
        try:
            if bpy.app.version[1] > 90:
                kitops_preference.boolean_solver = layer.boolean_solver

            for index, category in enumerate(option.kpack.categories):
                if category.name == category_name:
                    if index < len(option.kpack.categories):
                        category_item = option.kpack.categories[index]
                        for index, blend in enumerate(category_item.blends):
                            if blend.name == random_insert.insert_name:
                                op.location = blend.location

                                insert_obj = insert_frame_cache.get_insert_frame(
                                    op)

                                if insert_obj is None:
                                    # will we ever retrieve an insert?
                                    all_equal = True
                                    for insert_entry in layer_inserts:
                                        if insert_entry.is_enabled and insert_entry.proportionality > 0:
                                            all_equal &= (
                                                insert_entry.insert_name ==
                                                random_insert.insert_name)
                                    if all_equal:
                                        return None, None
                                    else:
                                        return add_random_insert(
                                            op, context, layer, inserts,
                                            insert_frame_cache, rng,
                                            insert_name_ignore_list)

                                # cleanup(op, context)
                                return insert_obj, random_insert
        finally:
            if bpy.app.version[1] > 90:
                kitops_preference.boolean_solver = old_boolean_solver_ref

    return None, None
Beispiel #5
0
    def to_object(self, op, context, convert_matrix):
        op.location = self.op_location

        if context.scene.kitopssynth.preview_mode and context.scene.kitopssynth.preview_type == 'FAST':
            #we're gonna draw something instead based on object bounding box....
            kitops_preference = kitops_addon.preference()
            basename = os.path.basename(op.location)
            collection_name = regex.clean_name(
                basename[:-6].title(),
                use_re=kitops_preference.clean_datablock_names)
            insert_name = collection_name + " Preview"

            me = bpy.data.meshes.new(insert_name)
            insert_obj = bpy.data.objects.new(insert_name, me)
            insert_obj.kitopssynth_insert.is_preview_insert = True
            insert_obj.kitops.id = id.uuid()

            insert_obj.location = self.cache_location
            insert_obj.matrix_world = self.cache_matrix
            insert_obj.scale = self.cache_scale
            insert_obj.rotation_euler = self.cache_euler
            insert_obj.color = context.scene.kitopssynth.preview_color

            bm = bmesh.new()

            i = 0
            for loc in self.bound_box:
                # v = bm.verts.new(insert_obj.matrix_world.inverted() @ Vector(loc))
                v = bm.verts.new(loc)
                v.index = i
                i += 1

            bm.verts.ensure_lookup_table()

            if len(bm.verts) == 8:
                bm.faces.new(
                    [bm.verts[0], bm.verts[1], bm.verts[2], bm.verts[3]])
                bm.faces.new(
                    [bm.verts[7], bm.verts[6], bm.verts[5], bm.verts[4]])
                bm.faces.new(
                    [bm.verts[0], bm.verts[4], bm.verts[5], bm.verts[1]])
                bm.faces.new(
                    [bm.verts[5], bm.verts[6], bm.verts[2], bm.verts[1]])
                bm.faces.new(
                    [bm.verts[7], bm.verts[4], bm.verts[0], bm.verts[3]])
                bm.faces.new(
                    [bm.verts[7], bm.verts[3], bm.verts[2], bm.verts[6]])

            bm.to_mesh(me)
            bm.free()

            if 'INSERTS' not in bpy.data.collections:
                context.scene.collection.children.link(
                    bpy.data.collections.new(name='INSERTS'))

            collection_name = regex.clean_name(
                basename[:-6].title(),
                use_re=kitops_preference.clean_datablock_names)
            if collection_name not in bpy.data.collections:
                bpy.data.collections['INSERTS'].children.link(
                    bpy.data.collections.new(name=collection_name))

            bpy.data.collections[collection_name].objects.link(insert_obj)

        else:

            uid = insert_add(op, context, self.boolean_solver)

            insert_obj = get_insert(uid)

            if insert_obj == None:
                return None

        insert_obj.kitopssynth_insert.is_preview_insert = context.scene.kitopssynth.preview_mode

        # determine delta between central location and actual center.
        origin = insert_obj.location
        natural_center = 0.125 * sum(
            (Vector(b) for b in insert_obj.bound_box), Vector())
        natural_center = insert_obj.matrix_world @ natural_center
        natural_center[2] = origin[2]
        rotated_origin = _rotate_around_pivot(
            natural_center, origin, self.kitopssynth.intended_rotation)
        local_vector = (rotated_origin - natural_center) * self.scale
        mx_inv = convert_matrix.inverted()
        mx_norm = mx_inv.transposed().to_3x3()
        delta_vector = mx_norm @ local_vector

        # assign the object's transform properties
        point = self.location + delta_vector
        insert_obj.hide_viewport = self.hide_viewport
        insert_obj.location = point
        insert_obj.matrix_world = self.matrix_world
        insert_obj.matrix_world.translation = point
        insert_obj.rotation_euler.rotate_axis(
            "Z", self.kitopssynth.intended_rotation)
        insert_obj.scale = self.scale

        if context.scene.kitopssynth.preview_mode and context.scene.kitopssynth.preview_type == "WIREFRAME":
            set_display_type(insert_obj.kitops.id, 'WIRE')

        insert.parent_objects(insert_obj, context.scene.kitopssynth_target_obj)

        cleanup(op, context)

        return insert_obj
Beispiel #6
0
def inserts_add_layer(prop, context, layer, new_insert_objs, cleanup=True):
    '''Main code for handling layout and distribution of INSERTs'''

    #Temporary set to regular mode if SMART mode is set to improve performance.
    kitops_preference = kitops_addon.preference()
    old_mode = kitops_preference.mode
    kitops_preference.mode = 'REGULAR'
    try:

        # see if there is an existing reference to INSERTS in this selection.  If not, create a new one.
        target_obj = context.scene.kitopssynth_target_obj
        insert_entry_map = None

        # Is this the active layer?
        is_active_layer = context.scene.kitopssynth.layers[
            context.scene.kitopssynth.layer_index].name == layer.name

        old_active = context.active_object

        layer_id = layer.name
        if layer_id not in target_obj.kitopssynth_layer_face_map:
            face_map_ref = target_obj.kitopssynth_layer_face_map.add()
            face_map_ref.name = layer_id
        face_ids = target_obj.kitopssynth_layer_face_map[layer_id].face_ids

        reset_selection = False
        if is_active_layer or not len(face_ids):
            # update the layer -> face selection mapping from the existing face selection
            face_id_list = property.generate_face_id_list(target_obj)
            face_ids.clear()
            for face_id in face_id_list:
                face_ids.add().face_id = face_id
        else:
            reset_selection = True
            # get the layer -> face selection mapping from the existing layer and set accordingly.
            old_face_selection_ids = []

            obj = target_obj
            bm = bmesh.new()
            if obj.mode == 'EDIT':
                bm = bmesh.from_edit_mesh(obj.data)
            elif obj.mode == 'OBJECT':
                bm.from_mesh(obj.data)

            for f in bm.faces:
                if f.select:
                    old_face_selection_ids.append(f.index)
                f.select_set(False)
            bm.faces.ensure_lookup_table()
            for face_id_entry in face_ids:
                face_id = face_id_entry.face_id
                bm.faces[face_id].select_set(True)

            if obj.mode == 'EDIT':
                bmesh.update_edit_mesh(obj.data)
            elif obj.mode == 'OBJECT':
                bm.to_mesh(obj.data)
                bm.free()

            face_id_list = property.generate_face_id_list(target_obj)

        if context.active_object:
            bpy.ops.ko.synth_clear_layer('INVOKE_DEFAULT',
                                         layer_uid=layer.name,
                                         delete_all=True)

        #if we have no face selections after this, just do nothing.
        if len(face_id_list):
            key = property.generate_insert_map_key(target_obj, face_id_list)

            # just create a new entry for target objects -> inserts.
            insert_entry_map = target_obj.kitopssynth_insert_map[
                key] if key in target_obj.kitopssynth_insert_map else target_obj.kitopssynth_insert_map.add(
                )
            insert_entry_map.name = key

            # intitialise points and cache them.
            distribution_class_name = layer.distribution
            distributor = getattr(distributors, distribution_class_name)()

            new_insert_objs_to_add = distributor.distribute(
                prop, context, layer)
            new_insert_objs.extend(new_insert_objs_to_add)

            layer_to_update = insert_entry_map.layers[
                layer.
                name] if layer.name in insert_entry_map.layers else insert_entry_map.layers.add(
                )
            layer_to_update.name = layer.name

            for insert_obj in new_insert_objs_to_add:
                if insert_obj is not None:
                    layer_to_update.inserts.add().insert_obj = insert_obj

        # reset the selection for next time.
        context.view_layer.objects.active = old_active
        if reset_selection:
            obj = target_obj
            bm = bmesh.new()
            if obj.mode == 'EDIT':
                bm = bmesh.from_edit_mesh(obj.data)
            elif obj.mode == 'OBJECT':
                bm.from_mesh(obj.data)
            for f in bm.faces:
                f.select_set(False)
            bm.faces.ensure_lookup_table()
            for f_index in old_face_selection_ids:
                bm.faces[f_index].select_set(True)
            if obj.mode == 'EDIT':
                bmesh.update_edit_mesh(obj.data)
            elif obj.mode == 'OBJECT':
                bm.to_mesh(obj.data)
                bm.free()

        if cleanup:
            cleanup()
    finally:
        kitops_preference.mode = old_mode