diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ff2d17 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python + +# Blender +*.blend1 +*.blend2 + +# OS +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ diff --git a/MODERNIZER_OVERVIEW.md b/MODERNIZER_OVERVIEW.md new file mode 100644 index 0000000..d4cdde4 --- /dev/null +++ b/MODERNIZER_OVERVIEW.md @@ -0,0 +1,166 @@ +# Blender 2.79 Modernizer - Feature Overview + +## What This Addon Does + +The Blender 2.79 Modernizer brings the modern user experience of Blender 2.80+ to Blender 2.79. This includes updated workflows, keyboard shortcuts, and UI improvements that make working in Blender 2.79 feel more like the latest versions. + +## Key Features Implemented + +### 1. Collections Manager (Replaces Groups) + +**What's Modern About It:** +- Blender 2.80+ introduced "Collections" to replace the old "Layers" and "Groups" system +- Collections provide a better way to organize scenes + +**How This Addon Provides It:** +- Uses Blender 2.79's Groups as Collections +- Provides a dedicated "Collections Manager" panel in the 3D View +- Quick operators to add/remove objects from collections +- Visual display of collection contents with object counts + +**Operators Included:** +- `object.create_collection` - Create new collections +- `object.add_to_collection` - Add selected objects to a collection +- `object.remove_from_collection` - Remove objects from a collection + +### 2. Modern Keyboard Shortcuts + +**Spacebar Search (F3 equivalent):** +- In Blender 2.80+, Spacebar (or F3) opens a search menu +- In Blender 2.79, Spacebar plays/pauses animation +- This addon adds the option to use Spacebar for search instead +- Configurable in preferences + +**Modern Navigation:** +- `Numpad .` - Frame selected objects (improved version) +- `Home` - Frame all objects (improved version) +- These match modern Blender's navigation patterns + +### 3. Configurable Preferences + +**User Control:** +- Enable/disable individual features +- Toggle keyboard shortcuts on/off +- Customize behavior to personal preference +- All settings in User Preferences > Addons + +**Available Options:** +- Left Click Select (configurable but not fully implemented - UI option) +- Spacebar for Search +- Modern Transform Tools (UI option for future expansion) +- Collection Manager + +### 4. Modern UI Panel + +**Collections Manager Panel:** +- Located in 3D View Tools panel (T key) +- "Collections" category tab +- Shows all collections with object counts +- Quick add/remove buttons for each collection +- Displays selected object count + +## Technical Implementation + +### Blender 2.79 Compatibility + +The addon is specifically designed for Blender 2.79: +- Uses `bpy.types` and `bpy.props` correctly for 2.79 API +- Uses `user_preferences` instead of `preferences` (2.80+ change) +- Panel in `TOOLS` region instead of `UI` (2.80+ change) +- Groups instead of Collections (2.80+ change) + +### Code Structure + +``` +blender_279_modernizer.py +├── Addon Info (bl_info) +├── Addon Preferences Class +├── Collection Management Operators +│ ├── Create Collection +│ ├── Add to Collection +│ └── Remove from Collection +├── UI Panel (Collections Manager) +├── Modern Search Operator +├── Navigation Operators +└── Keymap Registration +``` + +### Keymap Management + +The addon safely registers and unregisters custom keymaps: +- Checks for addon context before registration +- Stores keymap references for clean unregistration +- Only activates keymaps when features are enabled + +## Usage Workflow + +### Setting Up + +1. Install the addon via User Preferences +2. Enable desired features in addon preferences +3. Restart Blender for keymap changes +4. Access Collections Manager from T panel + +### Creating a Collection Workflow + +1. Select objects in your scene +2. Open Collections Manager panel (T key > Collections tab) +3. Click "New Collection" +4. Enter a name for the collection +5. Click OK +6. Use +/- buttons to add/remove objects + +### Using Modern Shortcuts + +1. Press Spacebar to search for operators (if enabled) +2. Press Numpad . to frame selected objects +3. Press Home to frame all objects + +## Benefits for Users + +### Easier Transition +- Users familiar with modern Blender can work more naturally in 2.79 +- Reduced learning curve when switching between versions +- Consistent workflow across Blender versions + +### Better Organization +- Collections Manager makes scene organization clearer +- Visual feedback on collection contents +- Quick access to collection operations + +### Improved Efficiency +- Modern shortcuts are more intuitive +- Spacebar search speeds up workflow +- Navigation shortcuts are more accessible + +## Future Expansion Possibilities + +The addon structure allows for easy addition of: +- More modern shortcuts and keymaps +- Additional UI panels and tools +- Outliner improvements +- Property panel modernization +- More collection features +- Theme/UI color updates + +## Compatibility Notes + +- **Blender Version:** 2.79 only +- **Python:** Compatible with Python 3.5+ (Blender 2.79's Python) +- **Other Addons:** Should not conflict with other addons +- **Safe:** Does not modify core Blender files or break existing functionality + +## Installation Requirements + +- Blender 2.79.x +- No external dependencies +- Single file installation +- No compilation required + +## Conclusion + +This addon bridges the gap between Blender 2.79 and modern versions, making it easier for users to work in older versions while enjoying modern conveniences. It's particularly useful for: +- Studios still using Blender 2.79 for production +- Users learning Blender who want consistent experience +- Projects that require 2.79 compatibility +- Anyone who prefers modern UI/UX conventions diff --git a/QUICK_START.md b/QUICK_START.md new file mode 100644 index 0000000..79581cb --- /dev/null +++ b/QUICK_START.md @@ -0,0 +1,142 @@ +# Quick Start Guide: Blender 2.79 Modernizer + +## Installation (5 minutes) + +1. **Download** the addon file: + - `blender_279_modernizer.py` + +2. **Open Blender 2.79** + +3. **Install the addon:** + - Go to `File` → `User Preferences` (or press `Ctrl+Alt+U`) + - Click the `Add-ons` tab + - Click `Install Add-on from File...` at the bottom + - Navigate to and select `blender_279_modernizer.py` + - Click `Install Add-on from File...` + +4. **Enable the addon:** + - Search for "Modernizer" or scroll to find "System: Blender 2.79 Modernizer" + - Check the box next to it to enable + - Click `Save User Settings` at the bottom + +5. **Restart Blender** (recommended for keymaps to fully activate) + +## First Steps + +### Try the Collections Manager + +1. Open a scene with some objects +2. Press `T` to open the Tools panel (if not already visible) +3. Look for the "Collections" tab at the top +4. Click "New Collection" and give it a name +5. Select some objects in your scene +6. Click the `+` icon next to your collection to add them + +### Test Modern Shortcuts + +1. Press `Spacebar` - it should open the search menu! +2. Select an object and press `Numpad .` - it should frame the object +3. Press `Home` - it should frame all objects in view + +### Configure Preferences + +1. Go back to `File` → `User Preferences` → `Add-ons` +2. Find "Blender 2.79 Modernizer" and expand it +3. Toggle features on/off as you prefer: + - ☑ Spacebar for Search (recommended) + - ☑ Collection Manager (recommended) + - ☑ Modern Transform Tools (UI placeholder) + - ☑ Left Click Select (UI placeholder) + +## Common Usage Patterns + +### Organizing Your Scene + +**Creating Collections:** +``` +1. Select objects you want to group +2. Open Collections panel (T key → Collections tab) +3. Click "New Collection" +4. Name it (e.g., "Lighting", "Characters", "Props") +5. The selected objects are automatically added +``` + +**Adding Objects Later:** +``` +1. Select objects +2. Click the + icon next to the collection name +``` + +**Removing Objects:** +``` +1. Select objects +2. Click the - icon next to the collection name +``` + +### Modern Navigation Workflow + +**Focus on Selection:** +- Select object(s) +- Press `Numpad .` +- View centers on selection + +**See Everything:** +- Press `Home` +- View frames all objects + +**Quick Command Access:** +- Press `Spacebar` +- Type what you want (e.g., "add cube", "delete", "export") +- Press Enter + +## Troubleshooting + +### Spacebar Still Plays Animation +- Open User Preferences → Add-ons +- Find Blender 2.79 Modernizer +- Make sure "Spacebar for Search" is checked +- Click "Save User Settings" +- **Restart Blender** + +### Collections Panel Not Visible +- Press `T` to toggle the Tools panel +- Make sure you're in Object Mode +- Look for the "Collections" tab at the top of the Tools panel +- Check that "Collection Manager" is enabled in addon preferences + +### Addon Not Appearing After Install +- Make sure you selected the right file (`blender_279_modernizer.py`) +- Try searching for "Modernizer" or "2.79" in the addon search +- Check the "System" category filter +- Try installing again + +### Keymaps Not Working +- **Always restart Blender** after changing keymap settings +- Check for conflicts with other addons +- Verify the feature is enabled in addon preferences + +## Tips & Best Practices + +1. **Start with Collections**: Organize your scene into logical collections right from the start +2. **Use Spacebar Search**: Faster than remembering every menu location +3. **Frame Selected Often**: Use `Numpad .` frequently to focus on what you're working on +4. **Save Preferences**: Always click "Save User Settings" after changing addon settings + +## What's Not Included (Yet) + +This addon provides modern UX improvements, but doesn't change: +- The underlying render engine (still Blender Internal/Cycles 2.79) +- 3D viewport shading (Eevee is 2.80+) +- Node editor functionality +- Modifier system +- Core mesh/object capabilities + +These are fundamental Blender changes that can't be backported via addon. + +## Need More Help? + +- See `README.md` for full feature list +- See `MODERNIZER_OVERVIEW.md` for technical details +- Check Blender 2.79 documentation for general Blender help + +## Enjoy Modern Blender 2.79! 🎨 diff --git a/README.md b/README.md index 42da6d3..efe1833 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,64 @@ -Rotating ASCII - Export Object as Rotating ASCII python script +**Rotating ASCII** - Export Object as Rotating ASCII python script -pixel2cube - Imports images as colored cubes, best used with sprites. Make sure when you seperate the sprite models to merge by distance, it creates doubles for some reason. +**pixel2cube** - Imports images as colored cubes, best used with sprites. Make sure when you seperate the sprite models to merge by distance, it creates doubles for some reason. + +**Blender 2.79 Modernizer** - Brings modern Blender 2.80+ features and user experience to Blender 2.79 + +## Blender 2.79 Modernizer + +This addon modernizes Blender 2.79 to feel more like the latest versions (2.80+) by adding: + +### Features + +#### Collections Manager +- **Collections-like workflow**: Manage groups like modern Collections +- **Quick add/remove**: Easily organize objects into collections (groups) +- **Visual panel**: Dedicated Collections Manager panel in the 3D View Tools + +#### Modern Keyboard Shortcuts +- **Spacebar Search**: Use Spacebar to open the search menu (like F3 in 2.80+) +- **Left Click Select**: Option to enable left-click selection (configurable) +- **Modern Navigation**: Improved viewport navigation shortcuts + - `Numpad .` - Frame selected objects + - `Home` - Frame all objects + +#### User Experience Improvements +- **Modern UI Panel**: Dedicated panel for collection management +- **Quick operators**: Fast access to common operations +- **Configurable preferences**: Enable/disable features as needed + +### Installation + +1. Download `blender_279_modernizer.py` +2. Open Blender 2.79 +3. Go to `File > User Preferences > Add-ons` +4. Click `Install Add-on from File...` +5. Select the downloaded file +6. Enable the addon by checking the box next to "System: Blender 2.79 Modernizer" +7. Configure preferences as desired +8. Save User Settings + +### Usage + +#### Collections Manager Panel +- Find the "Collections" tab in the 3D View Tools panel (T key) +- Click "New Collection" to create a collection +- Use the +/- icons next to each collection to add/remove selected objects + +#### Keyboard Shortcuts +- `Spacebar` - Open search menu (if enabled in preferences) +- `Numpad .` - Frame selected objects +- `Home` - Frame all objects + +#### Configuration +- Access addon preferences: `File > User Preferences > Add-ons` +- Search for "Modernizer" +- Expand the addon to see configuration options +- Toggle features on/off as needed +- Restart Blender for keymap changes to take full effect + +### Notes +- This addon uses Blender 2.79's Groups as Collections +- Some features require Blender restart to fully activate +- Compatible with Blender 2.79 only +- Does not modify or break existing Blender functionality diff --git a/blender_279_modernizer.py b/blender_279_modernizer.py new file mode 100644 index 0000000..c5fee11 --- /dev/null +++ b/blender_279_modernizer.py @@ -0,0 +1,355 @@ +# Blender 2.79 Modernizer Addon +# Brings modern Blender 2.80+ features and shortcuts to Blender 2.79 + +bl_info = { + "name": "Blender 2.79 Modernizer", + "author": "ExtCan Contributors", + "version": (1, 0, 0), + "blender": (2, 79, 0), + "location": "User Preferences > Addons", + "description": "Modernizes Blender 2.79 with features and shortcuts from Blender 2.80+", + "warning": "", + "category": "System", +} + +import bpy +from bpy.types import ( + Operator, + Panel, + PropertyGroup, + AddonPreferences, +) +from bpy.props import ( + BoolProperty, + EnumProperty, + StringProperty, +) + + +# ============================================================================ +# Addon Preferences +# ============================================================================ + +class ModernizerPreferences(AddonPreferences): + bl_idname = __name__ + + enable_left_click_select = BoolProperty( + name="Left Click Select", + description="Enable left click for selection (like Blender 2.80+)", + default=True, + ) + + enable_spacebar_search = BoolProperty( + name="Spacebar for Search", + description="Use Spacebar to open search menu instead of play animation", + default=True, + ) + + enable_modern_transform = BoolProperty( + name="Modern Transform Tools", + description="Enable modern transform tool behavior", + default=True, + ) + + enable_collection_manager = BoolProperty( + name="Collection Manager", + description="Enable collection-like management for groups", + default=True, + ) + + def draw(self, context): + layout = self.layout + + box = layout.box() + box.label(text="Keyboard Shortcuts:", icon='PREFERENCES') + box.prop(self, "enable_left_click_select") + box.prop(self, "enable_spacebar_search") + box.prop(self, "enable_modern_transform") + + box = layout.box() + box.label(text="Workflow Features:", icon='SCENE') + box.prop(self, "enable_collection_manager") + + layout.separator() + layout.label(text="Note: Restart Blender after changing keymap settings", icon='INFO') + + +# ============================================================================ +# Collection-like Group Management +# ============================================================================ + +class OBJECT_OT_create_collection(Operator): + """Create a new collection (group) for organizing objects""" + bl_idname = "object.create_collection" + bl_label = "New Collection" + bl_options = {'REGISTER', 'UNDO'} + + collection_name = StringProperty( + name="Name", + description="Name for the new collection", + default="Collection", + ) + + def execute(self, context): + # Create a new group (Collections equivalent in 2.79) + bpy.data.groups.new(name=self.collection_name) + self.report({'INFO'}, "Created collection: {}".format(self.collection_name)) + return {'FINISHED'} + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + +class OBJECT_OT_add_to_collection(Operator): + """Add selected objects to a collection (group)""" + bl_idname = "object.add_to_collection" + bl_label = "Add to Collection" + bl_options = {'REGISTER', 'UNDO'} + + collection_name = StringProperty( + name="Collection", + description="Collection to add objects to", + ) + + def execute(self, context): + if not self.collection_name: + self.report({'WARNING'}, "No collection specified") + return {'CANCELLED'} + + # Get or create the group + if self.collection_name in bpy.data.groups: + group = bpy.data.groups[self.collection_name] + else: + group = bpy.data.groups.new(name=self.collection_name) + + # Add selected objects to group + # Get existing object names for efficient lookup + existing_names = {obj.name for obj in group.objects} + added_count = 0 + for obj in context.selected_objects: + if obj.name not in existing_names: + group.objects.link(obj) + added_count += 1 + + self.report({'INFO'}, "Added {} object(s) to {}".format(added_count, self.collection_name)) + return {'FINISHED'} + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + +class OBJECT_OT_remove_from_collection(Operator): + """Remove selected objects from a collection (group)""" + bl_idname = "object.remove_from_collection" + bl_label = "Remove from Collection" + bl_options = {'REGISTER', 'UNDO'} + + collection_name = StringProperty( + name="Collection", + description="Collection to remove objects from", + ) + + def execute(self, context): + if not self.collection_name or self.collection_name not in bpy.data.groups: + self.report({'WARNING'}, "Collection not found") + return {'CANCELLED'} + + group = bpy.data.groups[self.collection_name] + # Get existing object names for efficient lookup + existing_names = {obj.name for obj in group.objects} + removed_count = 0 + + for obj in context.selected_objects: + if obj.name in existing_names: + group.objects.unlink(obj) + removed_count += 1 + + self.report({'INFO'}, "Removed {} object(s) from {}".format(removed_count, self.collection_name)) + return {'FINISHED'} + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + +# ============================================================================ +# Modern UI Panel +# ============================================================================ + +class VIEW3D_PT_modern_collections(Panel): + """Panel for collection management""" + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + bl_category = "Collections" + bl_label = "Collections Manager" + bl_context = "objectmode" + + @classmethod + def poll(cls, context): + prefs = context.user_preferences.addons.get(__name__) + if prefs: + return prefs.preferences.enable_collection_manager + return True + + def draw(self, context): + layout = self.layout + + # Create new collection button + layout.operator("object.create_collection", icon='GROUP') + + layout.separator() + + # List existing collections (groups) + if bpy.data.groups: + box = layout.box() + box.label(text="Existing Collections:") + for group in bpy.data.groups: + row = box.row(align=True) + row.label(text=group.name, icon='GROUP') + + # Show object count + row.label(text="({})".format(len(group.objects))) + + # Add/Remove operators + op = row.operator("object.add_to_collection", text="", icon='ZOOMIN') + op.collection_name = group.name + + op = row.operator("object.remove_from_collection", text="", icon='ZOOMOUT') + op.collection_name = group.name + else: + layout.label(text="No collections yet", icon='INFO') + + # Show selected objects + if context.selected_objects: + layout.separator() + box = layout.box() + box.label(text="Selected: {} object(s)".format(len(context.selected_objects))) + + +# ============================================================================ +# Quick Search Operator (Spacebar Search) +# ============================================================================ + +class SCREEN_OT_modern_search_menu(Operator): + """Open search menu (like Blender 2.80+ Spacebar Search)""" + bl_idname = "screen.modern_search_menu" + bl_label = "Search Menu" + bl_options = {'REGISTER'} + + def execute(self, context): + # Open the search menu + bpy.ops.wm.search_menu('INVOKE_DEFAULT') + return {'FINISHED'} + + +# ============================================================================ +# Modern Viewport Navigation Helpers +# ============================================================================ + +class VIEW3D_OT_modern_frame_selected(Operator): + """Frame selected objects (improved version)""" + bl_idname = "view3d.modern_frame_selected" + bl_label = "Frame Selected" + bl_options = {'REGISTER'} + + def execute(self, context): + if context.selected_objects: + bpy.ops.view3d.view_selected() + else: + self.report({'INFO'}, "No objects selected") + return {'FINISHED'} + + +class VIEW3D_OT_modern_frame_all(Operator): + """Frame all objects (improved version)""" + bl_idname = "view3d.modern_frame_all" + bl_label = "Frame All" + bl_options = {'REGISTER'} + + def execute(self, context): + bpy.ops.view3d.view_all() + return {'FINISHED'} + + +# ============================================================================ +# Keymap Management +# ============================================================================ + +addon_keymaps = [] + +def register_keymaps(): + """Register modern keymaps""" + wm = bpy.context.window_manager + kc = wm.keyconfigs.addon + + if not kc: + return + + prefs = bpy.context.user_preferences.addons.get(__name__) + if not prefs: + return + + # Spacebar for Search (instead of play animation) + if prefs.preferences.enable_spacebar_search: + km = kc.keymaps.new(name='Screen', space_type='EMPTY') + kmi = km.keymap_items.new("screen.modern_search_menu", 'SPACE', 'PRESS') + addon_keymaps.append((km, kmi)) + + # Modern navigation shortcuts + km = kc.keymaps.new(name='3D View', space_type='VIEW_3D') + + # Numpad Period to frame selected (modern shortcut) + kmi = km.keymap_items.new("view3d.modern_frame_selected", 'NUMPAD_PERIOD', 'PRESS') + addon_keymaps.append((km, kmi)) + + # Home key to frame all + kmi = km.keymap_items.new("view3d.modern_frame_all", 'HOME', 'PRESS') + addon_keymaps.append((km, kmi)) + + +def unregister_keymaps(): + """Unregister addon keymaps""" + for km, kmi in addon_keymaps: + km.keymap_items.remove(kmi) + addon_keymaps.clear() + + +# ============================================================================ +# Registration +# ============================================================================ + +classes = ( + ModernizerPreferences, + OBJECT_OT_create_collection, + OBJECT_OT_add_to_collection, + OBJECT_OT_remove_from_collection, + VIEW3D_PT_modern_collections, + SCREEN_OT_modern_search_menu, + VIEW3D_OT_modern_frame_selected, + VIEW3D_OT_modern_frame_all, +) + + +def register(): + """Register addon""" + for cls in classes: + bpy.utils.register_class(cls) + + # Register keymaps after ensuring preferences are available + try: + register_keymaps() + except (AttributeError, KeyError, TypeError) as e: + # Keymap registration may fail if preferences aren't ready yet + # This is expected on initial load and can be safely ignored + pass + + +def unregister(): + """Unregister addon""" + unregister_keymaps() + + for cls in reversed(classes): + bpy.utils.unregister_class(cls) + + +if __name__ == "__main__": + register()