Sun Position: replace DMS label by the Enter Coordinates field
[blender-addons.git] / add_curve_extra_objects / __init__.py
blob1e8406b8f0282068eb5871982aecd660db665723
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # Contributed to by:
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)
8 bl_info = {
9 "name": "Extra Objects",
10 "author": "Multiple Authors",
11 "version": (0, 1, 5),
12 "blender": (2, 93, 0),
13 "location": "View3D > Add > Curve > Extra Objects",
14 "description": "Add extra curve object types",
15 "warning": "",
16 "doc_url": "{BLENDER_MANUAL_URL}/addons/add_curve/extra_objects.html",
17 "category": "Add Curve",
20 if "bpy" in locals():
21 import importlib
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)
33 else:
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
45 import bpy
46 from bpy.types import (
47 Menu,
48 AddonPreferences,
50 from bpy.props import (
51 StringProperty,
52 BoolProperty,
56 def convert_old_presets(data_path, msg_data_path, old_preset_subdir,
57 new_preset_subdir, fixdic={}, ext=".py"):
58 """
59 convert old presets
60 """
62 def convert_presets(self, context):
63 if not getattr(self, data_path, False):
64 return None
65 import os
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)]
74 if not files:
75 print("No old presets in %s" % target_path)
76 setattr(self, msg_data_path, "No old presets")
77 return None
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)
81 for f in files:
82 file = open(os.path.join(target_path, f))
83 for line in file:
84 if line.startswith("op."):
85 exec(line)
86 file.close()
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)])
90 # create a new one
91 new_file_path = os.path.join(new_target_path, f)
92 if os.path.isfile(new_file_path):
93 # do nothing
94 print("Preset %s already exists, passing..." % f)
95 continue
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)))
103 else:
104 file_preset.write("op.%s = %s\n" % (prop, str(value)))
105 file_preset.close()
106 print("Writing new preset to %s" % new_file_path)
108 setattr(self, msg_data_path, "Converted %d old presets" % len(files))
109 return None
111 return convert_presets
114 # Addons Preferences
116 class CurveExtraObjectsAddonPreferences(AddonPreferences):
117 bl_idname = __name__
119 spiral_fixdic = {
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",
130 default=False,
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",
136 fixdic=spiral_fixdic
139 show_menu_list : BoolProperty(
140 name="Menu List",
141 description="Show/Hide the Add Menu items",
142 default=False
145 def draw(self, context):
146 layout = self.layout
147 box = layout.box()
148 box.label(text="Spirals:")
150 if self.update_spiral_presets:
151 box.label(text=self.update_spiral_presets_msg, icon="FILE_TICK")
152 else:
153 box.prop(self, "update_spiral_presets")
155 icon_1 = "TRIA_RIGHT" if not self.show_menu_list else "TRIA_DOWN"
156 box = layout.box()
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):",
161 icon="LAYER_USED")
162 box.label(text="2D Objects:", icon="LAYER_ACTIVE")
163 box.label(text="Angle, Arc, Circle, Distance, Ellipse, Line, Point, Polygon,",
164 icon="LAYER_USED")
165 box.label(text="Polygon ab, Rectangle, Rhomb, Sector, Segment, Trapezoid",
166 icon="LAYER_USED")
167 box.label(text="Curve Profiles:", icon="LAYER_ACTIVE")
168 box.label(text="Arc, Arrow, Cogwheel, Cycloid, Flower, Helix (3D),",
169 icon="LAYER_USED")
170 box.label(text="Noise (3D), Nsided, Profile, Rectangle, Splat, Star",
171 icon="LAYER_USED")
172 box.label(text="Curve Spirals:", icon="LAYER_ACTIVE")
173 box.label(text="Archemedian, Logarithmic, Spheric, Torus",
174 icon="LAYER_USED")
175 box.label(text="Knots:", icon="LAYER_ACTIVE")
176 box.label(text="Torus Knots Plus, Celtic Links, Braid Knot",
177 icon="LAYER_USED")
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",
182 icon="LAYER_USED")
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",
185 icon="LAYER_USED")
187 box.label(text="Items located in the Add Menu > Surface (default shortcut Ctrl + A):",
188 icon="LAYER_USED")
189 box.label(text="Wedge, Cone, Star, Plane",
190 icon="LAYER_ACTIVE")
193 class INFO_MT_curve_knots_add(Menu):
194 # Define the "Extras" menu
195 bl_idname = "INFO_MT_curve_knots_add"
196 bl_label = "Plants"
198 def draw(self, context):
199 layout = self.layout
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):
212 layout = self.layout
214 layout.operator_menu_enum("curve.curveaceous_galore", "ProfileType", icon='CURVE_DATA')
215 layout.operator_menu_enum("curve.spirals", "spiral_type", icon='FORCE_VORTEX')
216 layout.separator()
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
220 return None
221 layout.separator()
222 layout.menu(INFO_MT_curve_knots_add.bl_idname, text="Knots", icon='CURVE_DATA')
223 layout.separator()
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")
238 # Register
239 classes = [
240 CurveExtraObjectsAddonPreferences,
241 INFO_MT_curve_knots_add
244 def register():
245 from bpy.utils import register_class
246 for cls in classes:
247 register_class(cls)
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)
266 def unregister():
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__":
288 register()