Changeset View
Changeset View
Standalone View
Standalone View
add_curve_extra_objects/add_curve_spirals.py
| Show All 24 Lines | from bpy.props import ( | ||||
| ) | ) | ||||
| from mathutils import ( | from mathutils import ( | ||||
| Vector, | Vector, | ||||
| Matrix, | Matrix, | ||||
| ) | ) | ||||
| from math import ( | from math import ( | ||||
| sin, cos, pi | sin, cos, pi | ||||
| ) | ) | ||||
| from bpy_extras.object_utils import object_data_add | from bpy_extras import object_utils | ||||
| from bpy.types import ( | from bpy.types import ( | ||||
| Operator, | Operator, | ||||
| Menu, | Menu, | ||||
| ) | ) | ||||
| from bl_operators.presets import AddPresetBase | from bl_operators.presets import AddPresetBase | ||||
| # make normal spiral | # make normal spiral | ||||
| ▲ Show 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | while abs(cur_phi) <= abs(max_phi): | ||||
| cur_theta += step_theta | cur_theta += step_theta | ||||
| cur_phi += step_phi | cur_phi += step_phi | ||||
| cur_rad += step_rad | cur_rad += step_rad | ||||
| cur_inner_rad += step_inner_rad | cur_inner_rad += step_inner_rad | ||||
| cur_z += step_z | cur_z += step_z | ||||
| return verts | return verts | ||||
| # ------------------------------------------------------------ | |||||
| # calculates the matrix for the new object | |||||
| # depending on user pref | |||||
| def align_matrix(context, location): | |||||
| loc = Matrix.Translation(location) | |||||
| obj_align = context.preferences.edit.object_align | |||||
| if (context.space_data.type == 'VIEW_3D' and | |||||
| obj_align == 'VIEW'): | |||||
| rot = context.space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4() | |||||
| else: | |||||
| rot = Matrix() | |||||
| align_matrix = loc @ rot | |||||
| return align_matrix | |||||
| # ------------------------------------------------------------ | # ------------------------------------------------------------ | ||||
| # get array of vertcoordinates according to splinetype | # get array of vertcoordinates according to splinetype | ||||
| def vertsToPoints(Verts, splineType): | def vertsToPoints(Verts, splineType): | ||||
| # main vars | # main vars | ||||
| vertArray = [] | vertArray = [] | ||||
| Show All 9 Lines | else: | ||||
| if splineType == 'NURBS': | if splineType == 'NURBS': | ||||
| # for nurbs w=1 | # for nurbs w=1 | ||||
| vertArray.append(1) | vertArray.append(1) | ||||
| else: | else: | ||||
| # for poly w=0 | # for poly w=0 | ||||
| vertArray.append(0) | vertArray.append(0) | ||||
| return vertArray | return vertArray | ||||
| def draw_curve(props, context, align_matrix): | |||||
| # ------------------------------------------------------------ | |||||
| # create curve object according to the values of the add object editor | |||||
| def draw_curve(props, context): | |||||
| # output splineType 'POLY' 'NURBS' 'BEZIER' | # output splineType 'POLY' 'NURBS' 'BEZIER' | ||||
| splineType = props.curve_type | splineType = props.curve_type | ||||
| if props.spiral_type == 'ARCH': | if props.spiral_type == 'ARCH': | ||||
| verts = make_spiral(props, context) | verts = make_spiral(props, context) | ||||
| if props.spiral_type == 'LOG': | if props.spiral_type == 'LOG': | ||||
| verts = make_spiral(props, context) | verts = make_spiral(props, context) | ||||
| if props.spiral_type == 'SPHERE': | if props.spiral_type == 'SPHERE': | ||||
| verts = make_spiral_spheric(props, context) | verts = make_spiral_spheric(props, context) | ||||
| if props.spiral_type == 'TORUS': | if props.spiral_type == 'TORUS': | ||||
| verts = make_spiral_torus(props, context) | verts = make_spiral_torus(props, context) | ||||
| # create object | # create object | ||||
| if bpy.context.mode == 'EDIT_CURVE': | if bpy.context.mode == 'EDIT_CURVE': | ||||
| Curve = context.active_object | Curve = context.active_object | ||||
| newSpline = Curve.data.splines.new(type=splineType) # spline | newSpline = Curve.data.splines.new(type=splineType) # spline | ||||
| else: | else: | ||||
| # create curve | # create curve | ||||
| dataCurve = bpy.data.curves.new(name='Spiral', type='CURVE') # curvedatablock | dataCurve = bpy.data.curves.new(name='Spiral', type='CURVE') # curvedatablock | ||||
| newSpline = dataCurve.splines.new(type=splineType) # spline | newSpline = dataCurve.splines.new(type=splineType) # spline | ||||
| # create object with newCurve | # create object with newCurve | ||||
| Curve = object_data_add(context, dataCurve) # place in active scene | Curve = object_utils.object_data_add(context, dataCurve, operator=props) # place in active scene | ||||
| Curve.matrix_world = align_matrix # apply matrix | |||||
| Curve.rotation_euler = props.rotation_euler | |||||
| Curve.select_set(True) | Curve.select_set(True) | ||||
| # turn verts into array | # turn verts into array | ||||
| vertArray = vertsToPoints(verts, splineType) | vertArray = vertsToPoints(verts, splineType) | ||||
| for spline in Curve.data.splines: | for spline in Curve.data.splines: | ||||
| if spline.type == 'BEZIER': | if spline.type == 'BEZIER': | ||||
| for point in spline.bezier_points: | for point in spline.bezier_points: | ||||
| Show All 31 Lines | def draw_curve(props, context): | ||||
| Curve.data.use_path = True | Curve.data.use_path = True | ||||
| if props.shape == '3D': | if props.shape == '3D': | ||||
| Curve.data.fill_mode = 'FULL' | Curve.data.fill_mode = 'FULL' | ||||
| else: | else: | ||||
| Curve.data.fill_mode = 'BOTH' | Curve.data.fill_mode = 'BOTH' | ||||
| # move and rotate spline in edit mode | # move and rotate spline in edit mode | ||||
| if bpy.context.mode == 'EDIT_CURVE': | if bpy.context.mode == 'EDIT_CURVE': | ||||
| bpy.ops.transform.translate(value = props.startlocation) | if props.align == 'WORLD': | ||||
| bpy.ops.transform.rotate(value = props.rotation_euler[0], orient_axis = 'X') | location = props.location - context.active_object.location | ||||
| bpy.ops.transform.rotate(value = props.rotation_euler[1], orient_axis = 'Y') | bpy.ops.transform.translate(value = location, orient_type='GLOBAL') | ||||
| bpy.ops.transform.rotate(value = props.rotation_euler[2], orient_axis = 'Z') | bpy.ops.transform.rotate(value = props.rotation[0], orient_axis = 'X') | ||||
| bpy.ops.transform.rotate(value = props.rotation[1], orient_axis = 'Y') | |||||
| bpy.ops.transform.rotate(value = props.rotation[2], orient_axis = 'Z') | |||||
| elif props.align == "VIEW": | |||||
| bpy.ops.transform.translate(value = props.location) | |||||
| bpy.ops.transform.rotate(value = props.rotation[0], orient_axis = 'X') | |||||
| bpy.ops.transform.rotate(value = props.rotation[1], orient_axis = 'Y') | |||||
| bpy.ops.transform.rotate(value = props.rotation[2], orient_axis = 'Z') | |||||
| elif props.align == "CURSOR": | |||||
| location = context.active_object.location | |||||
| props.location = bpy.context.scene.cursor.location - location | |||||
| props.rotation = bpy.context.scene.cursor.rotation_euler | |||||
| bpy.ops.transform.translate(value = props.location) | |||||
| bpy.ops.transform.rotate(value = props.rotation[0], orient_axis = 'X') | |||||
| bpy.ops.transform.rotate(value = props.rotation[1], orient_axis = 'Y') | |||||
| bpy.ops.transform.rotate(value = props.rotation[2], orient_axis = 'Z') | |||||
| class CURVE_OT_spirals(Operator): | class CURVE_OT_spirals(Operator, object_utils.AddObjectHelper): | ||||
| bl_idname = "curve.spirals" | bl_idname = "curve.spirals" | ||||
| bl_label = "Curve Spirals" | bl_label = "Curve Spirals" | ||||
| bl_description = "Create different types of spirals" | bl_description = "Create different types of spirals" | ||||
| bl_options = {'REGISTER', 'UNDO', 'PRESET'} | bl_options = {'REGISTER', 'UNDO', 'PRESET'} | ||||
| # align_matrix for the invoke | |||||
| align_matrix : Matrix() | |||||
| spiral_type : EnumProperty( | spiral_type : EnumProperty( | ||||
| items=[('ARCH', "Archemedian", "Archemedian"), | items=[('ARCH', "Archemedian", "Archemedian"), | ||||
| ("LOG", "Logarithmic", "Logarithmic"), | ("LOG", "Logarithmic", "Logarithmic"), | ||||
| ("SPHERE", "Spheric", "Spheric"), | ("SPHERE", "Spheric", "Spheric"), | ||||
| ("TORUS", "Torus", "Torus")], | ("TORUS", "Torus", "Torus")], | ||||
| default='ARCH', | default='ARCH', | ||||
| name="Spiral Type", | name="Spiral Type", | ||||
| description="Type of spiral to add" | description="Type of spiral to add" | ||||
| ▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | handleType : EnumProperty( | ||||
| ('VECTOR', "Vector", "Vector type Bezier handles"), | ('VECTOR', "Vector", "Vector type Bezier handles"), | ||||
| ('AUTO', "Auto", "Automatic type Bezier handles")] | ('AUTO', "Auto", "Automatic type Bezier handles")] | ||||
| ) | ) | ||||
| edit_mode : BoolProperty( | edit_mode : BoolProperty( | ||||
| name="Show in edit mode", | name="Show in edit mode", | ||||
| default=True, | default=True, | ||||
| description="Show in edit mode" | description="Show in edit mode" | ||||
| ) | ) | ||||
| startlocation : FloatVectorProperty( | |||||
| name="", | |||||
| description="Start location", | |||||
| default=(0.0, 0.0, 0.0), | |||||
| subtype='TRANSLATION' | |||||
| ) | |||||
| rotation_euler : FloatVectorProperty( | |||||
| name="", | |||||
| description="Rotation", | |||||
| default=(0.0, 0.0, 0.0), | |||||
| subtype='EULER' | |||||
| ) | |||||
| def draw(self, context): | def draw(self, context): | ||||
| layout = self.layout | layout = self.layout | ||||
| col = layout.column_flow(align=True) | col = layout.column_flow(align=True) | ||||
| col.label(text="Presets:") | |||||
| row = col.row(align=True) | |||||
| row.menu("OBJECT_MT_spiral_curve_presets", | |||||
| text=bpy.types.OBJECT_MT_spiral_curve_presets.bl_label) | |||||
| row.operator("curve_extras.spiral_presets", text=" + ") | |||||
| op = row.operator("curve_extras.spiral_presets", text=" - ") | |||||
| op.remove_active = True | |||||
| layout.prop(self, "spiral_type") | layout.prop(self, "spiral_type") | ||||
| layout.prop(self, "spiral_direction") | layout.prop(self, "spiral_direction") | ||||
| col = layout.column(align=True) | col = layout.column(align=True) | ||||
| col.label(text="Spiral Parameters:") | col.label(text="Spiral Parameters:") | ||||
| col.prop(self, "turns", text="Turns") | col.prop(self, "turns", text="Turns") | ||||
| col.prop(self, "steps", text="Steps") | col.prop(self, "steps", text="Steps") | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | def draw(self, context): | ||||
| col.row().prop(self, 'handleType', expand=True) | col.row().prop(self, 'handleType', expand=True) | ||||
| col = layout.column() | col = layout.column() | ||||
| col.row().prop(self, "use_cyclic_u", expand=True) | col.row().prop(self, "use_cyclic_u", expand=True) | ||||
| col = layout.column() | col = layout.column() | ||||
| col.row().prop(self, "edit_mode", expand=True) | col.row().prop(self, "edit_mode", expand=True) | ||||
| box = layout.box() | col = layout.column() | ||||
| box.label(text="Location:") | # AddObjectHelper props | ||||
| box.prop(self, "startlocation") | col.prop(self, "align") | ||||
| box = layout.box() | col.prop(self, "location") | ||||
| box.label(text="Rotation:") | col.prop(self, "rotation") | ||||
| box.prop(self, "rotation_euler") | |||||
| @classmethod | @classmethod | ||||
| def poll(cls, context): | def poll(cls, context): | ||||
| return context.scene is not None | return context.scene is not None | ||||
| def execute(self, context): | def execute(self, context): | ||||
| # turn off 'Enter Edit Mode' | # turn off 'Enter Edit Mode' | ||||
| use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode | use_enter_edit_mode = bpy.context.preferences.edit.use_enter_edit_mode | ||||
| bpy.context.preferences.edit.use_enter_edit_mode = False | bpy.context.preferences.edit.use_enter_edit_mode = False | ||||
| time_start = time.time() | time_start = time.time() | ||||
| self.align_matrix = align_matrix(context, self.startlocation) | draw_curve(self, context) | ||||
| draw_curve(self, context, self.align_matrix) | |||||
| if use_enter_edit_mode: | if use_enter_edit_mode: | ||||
| bpy.ops.object.mode_set(mode = 'EDIT') | bpy.ops.object.mode_set(mode = 'EDIT') | ||||
| # restore pre operator state | # restore pre operator state | ||||
| bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode | bpy.context.preferences.edit.use_enter_edit_mode = use_enter_edit_mode | ||||
| if self.edit_mode: | if self.edit_mode: | ||||
| ▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines | |||||