1 # SPDX-License-Identifier: GPL-2.0-or-later
4 # testscreenings, Alejandro Omar Chocano Vasquez, Jimmy Hazevoet, meta-androcto
5 # Cmomoney, Jared Forsyth, Adam Newgas, Spivak Vladimir, Jared Forsyth, Atom
6 # Antonio Osprite, Marius Giurgi (DolphinDream)
9 "name": "Extra Objects",
10 "author": "Multiple Authors",
12 "blender": (2, 93, 0),
13 "location": "View3D > Add > Curve > Extra Objects",
14 "description": "Add extra curve object types",
16 "doc_url": "{BLENDER_MANUAL_URL}/addons/add_curve/extra_objects.html",
17 "category": "Add Curve",
22 importlib
.reload(add_curve_aceous_galore
)
23 importlib
.reload(add_curve_spirals
)
24 importlib
.reload(add_curve_torus_knots
)
25 importlib
.reload(add_surface_plane_cone
)
26 importlib
.reload(add_curve_curly
)
27 importlib
.reload(beveltaper_curve
)
28 importlib
.reload(add_curve_celtic_links
)
29 importlib
.reload(add_curve_braid
)
30 importlib
.reload(add_curve_simple
)
31 importlib
.reload(add_curve_spirofit_bouncespline
)
34 from . import add_curve_aceous_galore
35 from . import add_curve_spirals
36 from . import add_curve_torus_knots
37 from . import add_surface_plane_cone
38 from . import add_curve_curly
39 from . import beveltaper_curve
40 from . import add_curve_celtic_links
41 from . import add_curve_braid
42 from . import add_curve_simple
43 from . import add_curve_spirofit_bouncespline
46 from bpy
.types
import (
50 from bpy
.props
import (
56 def convert_old_presets(data_path
, msg_data_path
, old_preset_subdir
,
57 new_preset_subdir
, fixdic
={}, ext
=".py"):
62 def convert_presets(self
, context
):
63 if not getattr(self
, data_path
, False):
67 target_path
= os
.path
.join("presets", old_preset_subdir
)
68 target_path
= bpy
.utils
.user_resource('SCRIPTS', path
=target_path
)
70 # created an anytype op to run against preset
71 op
= type('', (), {})()
73 files
= [f
for f
in os
.listdir(target_path
) if f
.endswith(ext
)]
75 print("No old presets in %s" % target_path
)
76 setattr(self
, msg_data_path
, "No old presets")
79 new_target_path
= os
.path
.join("presets", new_preset_subdir
)
80 new_target_path
= bpy
.utils
.user_resource('SCRIPTS', path
=new_target_path
, create
=True)
82 file = open(os
.path
.join(target_path
, f
))
84 if line
.startswith("op."):
87 for key
, items
in fixdic
.items():
88 if hasattr(op
, key
) and isinstance(getattr(op
, key
), int):
89 setattr(op
, key
, items
[getattr(op
, key
)])
91 new_file_path
= os
.path
.join(new_target_path
, f
)
92 if os
.path
.isfile(new_file_path
):
94 print("Preset %s already exists, passing..." % f
)
96 file_preset
= open(new_file_path
, 'w')
97 file_preset
.write("import bpy\n")
98 file_preset
.write("op = bpy.context.active_operator\n")
100 for prop
, value
in vars(op
).items():
101 if isinstance(value
, str):
102 file_preset
.write("op.%s = '%s'\n" % (prop
, str(value
)))
104 file_preset
.write("op.%s = %s\n" % (prop
, str(value
)))
106 print("Writing new preset to %s" % new_file_path
)
108 setattr(self
, msg_data_path
, "Converted %d old presets" % len(files
))
111 return convert_presets
116 class CurveExtraObjectsAddonPreferences(AddonPreferences
):
120 "spiral_type": ['ARCH', 'ARCH', 'LOG', 'SPHERE', 'TORUS'],
121 "curve_type": ['POLY', 'NURBS'],
122 "spiral_direction": ['COUNTER_CLOCKWISE', 'CLOCKWISE']
124 update_spiral_presets_msg
: StringProperty(
125 default
="Nothing to do"
127 update_spiral_presets
: BoolProperty(
128 name
="Update Old Presets",
129 description
="Update presets to reflect data changes",
131 update
=convert_old_presets(
132 "update_spiral_presets", # this props name
133 "update_spiral_presets_msg", # message prop
134 "operator/curve.spirals",
135 "curve_extras/curve.spirals",
139 show_menu_list
: BoolProperty(
141 description
="Show/Hide the Add Menu items",
145 def draw(self
, context
):
148 box
.label(text
="Spirals:")
150 if self
.update_spiral_presets
:
151 box
.label(text
=self
.update_spiral_presets_msg
, icon
="FILE_TICK")
153 box
.prop(self
, "update_spiral_presets")
155 icon_1
= "TRIA_RIGHT" if not self
.show_menu_list
else "TRIA_DOWN"
157 box
.prop(self
, "show_menu_list", emboss
=False, icon
=icon_1
)
159 if self
.show_menu_list
:
160 box
.label(text
="Items located in the Add Menu > Curve (default shortcut Ctrl + A):",
162 box
.label(text
="2D Objects:", icon
="LAYER_ACTIVE")
163 box
.label(text
="Angle, Arc, Circle, Distance, Ellipse, Line, Point, Polygon,",
165 box
.label(text
="Polygon ab, Rectangle, Rhomb, Sector, Segment, Trapezoid",
167 box
.label(text
="Curve Profiles:", icon
="LAYER_ACTIVE")
168 box
.label(text
="Arc, Arrow, Cogwheel, Cycloid, Flower, Helix (3D),",
170 box
.label(text
="Noise (3D), Nsided, Profile, Rectangle, Splat, Star",
172 box
.label(text
="Curve Spirals:", icon
="LAYER_ACTIVE")
173 box
.label(text
="Archemedian, Logarithmic, Spheric, Torus",
175 box
.label(text
="Knots:", icon
="LAYER_ACTIVE")
176 box
.label(text
="Torus Knots Plus, Celtic Links, Braid Knot",
178 box
.label(text
="SpiroFit, Bounce Spline, Catenary", icon
="LAYER_USED")
179 box
.label(text
="Curly Curve", icon
="LAYER_ACTIVE")
180 box
.label(text
="Bevel/Taper:", icon
="LAYER_ACTIVE")
181 box
.label(text
="Add Curve as Bevel, Add Curve as Taper",
183 box
.label(text
="Simple Curve:", icon
="LAYER_ACTIVE")
184 box
.label(text
="Available if the Active Object is a Curve was created with 2D Objects",
187 box
.label(text
="Items located in the Add Menu > Surface (default shortcut Ctrl + A):",
189 box
.label(text
="Wedge, Cone, Star, Plane",
193 class INFO_MT_curve_knots_add(Menu
):
194 # Define the "Extras" menu
195 bl_idname
= "INFO_MT_curve_knots_add"
198 def draw(self
, context
):
200 layout
.operator_context
= 'INVOKE_REGION_WIN'
202 layout
.operator("curve.torus_knot_plus", text
="Torus Knot Plus")
203 layout
.operator("curve.celtic_links", text
="Celtic Links")
204 layout
.operator("curve.add_braid", text
="Braid Knot")
205 layout
.operator("object.add_spirofit_spline", icon
="FORCE_MAGNETIC")
206 layout
.operator("object.add_bounce_spline", icon
="FORCE_HARMONIC")
207 layout
.operator("object.add_catenary_curve", icon
="FORCE_CURVE")
210 # Define "Extras" menus
211 def menu_func(self
, context
):
214 layout
.operator_menu_enum("curve.curveaceous_galore", "ProfileType", icon
='CURVE_DATA')
215 layout
.operator_menu_enum("curve.spirals", "spiral_type", icon
='FORCE_VORTEX')
217 layout
.operator("curve.curlycurve", text
="Curly Curve", icon
='GP_ONLY_SELECTED')
218 if context
.mode
!= 'OBJECT':
219 # fix in D2142 will allow to work in EDIT_CURVE
222 layout
.menu(INFO_MT_curve_knots_add
.bl_idname
, text
="Knots", icon
='CURVE_DATA')
224 layout
.operator("curve.bevelcurve")
225 layout
.operator("curve.tapercurve")
226 layout
.operator("curve.simple")
228 def menu_surface(self
, context
):
229 self
.layout
.separator()
230 if context
.mode
== 'EDIT_SURFACE':
231 self
.layout
.operator("curve.smooth_x_times", text
="Special Smooth", icon
="MOD_CURVE")
232 elif context
.mode
== 'OBJECT':
233 self
.layout
.operator("object.add_surface_wedge", text
="Wedge", icon
="SURFACE_DATA")
234 self
.layout
.operator("object.add_surface_cone", text
="Cone", icon
="SURFACE_DATA")
235 self
.layout
.operator("object.add_surface_star", text
="Star", icon
="SURFACE_DATA")
236 self
.layout
.operator("object.add_surface_plane", text
="Plane", icon
="SURFACE_DATA")
240 CurveExtraObjectsAddonPreferences
,
241 INFO_MT_curve_knots_add
245 from bpy
.utils
import register_class
249 add_curve_simple
.register()
250 add_curve_spirals
.register()
251 add_curve_aceous_galore
.register()
252 add_curve_torus_knots
.register()
253 add_curve_braid
.register()
254 add_curve_celtic_links
.register()
255 add_curve_curly
.register()
256 add_curve_spirofit_bouncespline
.register()
257 add_surface_plane_cone
.register()
258 beveltaper_curve
.register()
260 # Add "Extras" menu to the "Add Curve" menu
261 bpy
.types
.VIEW3D_MT_curve_add
.append(menu_func
)
262 # Add "Extras" menu to the "Add Surface" menu
263 bpy
.types
.VIEW3D_MT_surface_add
.append(menu_surface
)
267 # Remove "Extras" menu from the "Add Curve" menu.
268 bpy
.types
.VIEW3D_MT_curve_add
.remove(menu_func
)
269 # Remove "Extras" menu from the "Add Surface" menu.
270 bpy
.types
.VIEW3D_MT_surface_add
.remove(menu_surface
)
272 add_surface_plane_cone
.unregister()
273 add_curve_spirofit_bouncespline
.unregister()
274 add_curve_curly
.unregister()
275 add_curve_celtic_links
.unregister()
276 add_curve_braid
.unregister()
277 add_curve_torus_knots
.unregister()
278 add_curve_aceous_galore
.unregister()
279 add_curve_spirals
.unregister()
280 add_curve_simple
.unregister()
281 beveltaper_curve
.unregister()
283 from bpy
.utils
import unregister_class
284 for cls
in reversed(classes
):
285 unregister_class(cls
)
287 if __name__
== "__main__":