You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Blender-TexTools/op_meshtex_pattern.py

194 lines
6.3 KiB
Python

import bpy
import bmesh
import operator
from mathutils import Vector
from collections import defaultdict
from math import pi
import math
from . import utilities_meshtex
from . import utilities_ui
class op(bpy.types.Operator):
bl_idname = "uv.textools_meshtex_pattern"
bl_label = "Create Pattern"
bl_description = "Create mesh pattern"
bl_options = {'REGISTER', 'UNDO'}
mode : bpy.props.EnumProperty(items=
[('hexagon', 'Hexagons', ''),
('triangle', 'Triangles', ''),
('diamond', 'Diamonds', ''),
('rectangle', 'Rectangles', ''),
('stripe', 'Stripes', ''),
('brick', 'Bricks', '')],
name = "Mode",
default = 'brick'
)
size : bpy.props.IntProperty(
name = "Size",
description = "Size X and Y of the repetition",
default = 4,
min = 1,
max = 128
)
scale : bpy.props.FloatProperty(
name = "Scale",
description = "Scale of the mesh pattern",
default = 1,
min = 0
)
@classmethod
def poll(cls, context):
if bpy.context.active_object and bpy.context.active_object.mode != 'OBJECT':
return False
return True
def draw(self, context):
layout = self.layout
layout.prop(self, "mode")
layout.prop(self, "size")
layout.prop(self, "scale")
def execute(self, context):
create_pattern(self, self.mode, self.size, self.scale)
return {'FINISHED'}
def AddArray(name, offset_x, offset_y, count):
modifier = bpy.context.object.modifiers.new(name=name, type='ARRAY')
# modifier = bpy.context.object.modifiers.new(name="{}_{}".format(name,count), type='ARRAY')
modifier.relative_offset_displace[0] = offset_x
modifier.relative_offset_displace[1] = offset_y
modifier.count = count
modifier.show_expanded = False
return modifier
def create_pattern(self, mode, size, scale):
print("Create pattern {}".format(mode))
# bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
context_override = None
if bpy.context.area.type != 'VIEW_3D':
context_override = utilities_ui.GetContextView3D()
if not context_override:
self.report({'ERROR_INVALID_INPUT'}, "This tool requires an available View3D view.")
return
print("Mode '{}' size: '{}'".format(mode, size))
if mode == 'hexagon':
bpy.ops.mesh.primitive_circle_add(vertices=6, radius=scale, fill_type='NGON')
bpy.ops.object.mode_set(mode = 'EDIT')
if context_override:
bpy.ops.transform.rotate(context_override, value=math.pi*0.5, orient_axis='Z')
else:
bpy.ops.transform.rotate(value=math.pi*0.5, orient_axis='Z')
bpy.ops.object.mode_set(mode = 'OBJECT')
AddArray("Array0", 0.75,-0.5,2)
AddArray("Array1", 0,-0.66666666666,size)
AddArray("Array2", 1 - (0.5/3.5),0,size*0.66)
elif mode == 'triangle':
bpy.ops.mesh.primitive_circle_add(vertices=3, radius=scale, fill_type='NGON')
bpy.ops.object.mode_set(mode = 'EDIT')
if context_override:
bpy.ops.transform.translate(context_override, value=(0, scale*0.5, 0), constraint_axis=(False, True, False))
else:
bpy.ops.transform.translate(value=(0, scale*0.5, 0), constraint_axis=(False, True, False))
bpy.ops.object.mode_set(mode = 'OBJECT')
modifier = bpy.context.object.modifiers.new(name="Mirror", type='MIRROR')
modifier.use_axis[0] = False
modifier.use_axis[1] = True
modifier.show_expanded = False
AddArray("Array0", 0.5,-0.5,2)
AddArray("Array1", 1-1/3.0,0,size)
AddArray("Array1", 0,-(1-1/3.0),size*0.66)
elif mode == 'rectangle':
bpy.ops.mesh.primitive_plane_add(size=scale)
AddArray("Array0", 1,0,size)
AddArray("Array1", 0,-1,size)
elif mode == 'diamond':
bpy.ops.mesh.primitive_plane_add(size=scale)
bpy.ops.object.mode_set(mode = 'EDIT')
if context_override:
bpy.ops.transform.rotate(context_override, value=math.pi*0.25, orient_axis='Z')
else:
bpy.ops.transform.rotate(value=math.pi*0.25, orient_axis='Z')
bpy.ops.object.mode_set(mode = 'OBJECT')
AddArray("Array0", 0.5,-0.5,2)
AddArray("Array1", 1-1/3,0,size)
AddArray("Array2", 0,-(1-1/3),size)
elif mode == 'brick':
bpy.ops.mesh.primitive_plane_add(size=scale)
bpy.ops.object.mode_set(mode = 'EDIT')
if context_override:
bpy.ops.transform.resize(context_override, value=(1, 0.5, 1), constraint_axis=(True, True, False), orient_type='GLOBAL')
else:
bpy.ops.transform.resize(value=(1, 0.5, 1), constraint_axis=(True, True, False), orient_type='GLOBAL')
bpy.ops.object.mode_set(mode = 'OBJECT')
AddArray("Array0", 0.5,-1,2)
AddArray("Array1", 1-(1/3),0,size)
AddArray("Array2", 0,-1,size)
elif mode == 'stripe':
bpy.ops.mesh.primitive_plane_add(size=1)
bpy.ops.object.mode_set(mode = 'EDIT')
if context_override:
bpy.ops.transform.resize(context_override, value=(0.5, size/2, 1), constraint_axis=(True, True, False), orient_type='GLOBAL')
bpy.ops.transform.resize(context_override, value=(scale, scale, 1), constraint_axis=(True, True, False), orient_type='GLOBAL')
bpy.ops.transform.translate(context_override, value=(0, (-size/2)*scale, 0), constraint_axis=(False, True, False))
else:
bpy.ops.transform.resize(value=(0.5, size/2, 1), constraint_axis=(True, True, False), orient_type='GLOBAL')
bpy.ops.transform.resize(value=(scale, scale, 1), constraint_axis=(True, True, False), orient_type='GLOBAL')
bpy.ops.transform.translate(value=(0, (-size/2)*scale, 0), constraint_axis=(False, True, False))
bpy.ops.object.mode_set(mode = 'OBJECT')
AddArray("Array0", 1,0, size)
# if bpy.context.object:
# bpy.context.object.name = "pattern_{}".format(mode)
# bpy.context.object.show_wire = True
bpy.utils.register_class(op)