zeffii/mesh_tiny_cad

Quick Radial Array

zeffii opened this issue · 4 comments

One more thing I miss from AutoCAD is the radial array. Currently in Blender one must add an empty with a rotation and add a modifier and untick relative steps and select the empty and set the rotation object. This is too many steps.

My radial arrays need only use the origin as a radial pivot, and the current View (top, side..etc) as the Empty orientation. The operator shall allow a slider to adjust the number of iterations of the object (and this will auto update the Empty's rotation.

milestones

  • basic empty + modifier creation
  • allow operator to adjust empty rotation
  • allow operator to pick up previously generated empty + modifier and adjust the same slider to modify the empty rotation. (tricky)

RAR.py

import bpy
import mathutils
from mathutils import Euler

import time
import math
from math import radians

def get_orthographic_view(context):
    return 'TOP'

def add_empty(loc, name):
    scene = bpy.context.scene
    objects = bpy.data.objects
    mt = objects.new(name, None)
    mt.location = loc
    mt.empty_draw_size = 2
    scene.objects.link(mt)
    scene.update()
    return mt

def main(self, context):

    active_object = bpy.context.active_object
    loc = active_object.location
    mts = [o for o in bpy.data.objects if o.type == 'EMPTY' and o['UID'] == self.UID]
    if mts:
        mt = mts[-1] 
    else:
        mt = add_empty(loc, name="empty_name")
        mt['UID'] = self.UID

    modifiers = active_object.modifiers
    array = modifiers.get('radial_array')
    if not array:
        array = modifiers.new(name='radial_array', type='ARRAY')
    array.use_relative_offset = False
    array.use_object_offset = True
    array.offset_object = mt

    # depending on view, must be ortographic.
    view_kind = get_orthographic_view(context)
    if self.count == 0:
        rotation = 0
        array.count = 1
    else:
        array.count = abs(self.count)
        rotation = radians(360 / self.count)

    comp = 'XYZ'.index(self.orientation)
    vec = [0, 0, 0]
    vec[comp] = rotation
    mt.rotation_euler = Euler(vec, 'XYZ')




class TCRadialArray(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "tinycad.radial_array"
    bl_label = "Radial Array"
    bl_options = {'REGISTER', 'UNDO'}

    count = bpy.props.IntProperty(min=0, default=3)
    orientation = bpy.props.EnumProperty(
        default='X',
        items=[('X','X', '', 0), ('Y','Y', '', 1), ('Z','Z', '', 2)]
    )


    @classmethod
    def poll(cls, context):
        return bool(context.active_object)

    def execute(self, context):
        main(self, context)
        return {'FINISHED'}

    def invoke(self, context, event):
        self.UID = str(hash(self) ^ hash(time.monotonic()))
        return self.execute(context)


def register():
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)

fancy

Wow this looks exciting. Looking forward to it.

Find empties for steps etc pretty tedious.

yeah - I might add an additional option to pick the axis for the rotation based on the current rotation_matrix of the object . so [X, Y, Z, rotation_matrix]