analitics

Pages

Saturday, October 18, 2025

Blender 3D : ... simple clothing addon.

Today, I created a simple clothing addon with a two-mesh coat. The addon adds everything needed for the simulation including material types for the clothes.

Python Qt6 : tool for cutting images ...

Today I made a script that allows adding custom horizontal and vertical sliders to an image and, depending on the custom distance between them, cuts the image into squares of different sizes.

Python Qt6 : tool for renaming files with creation date .

Since this hacking and the crashes... I've always taken screenshots... Today I created a small script that takes files from a folder and renames them with the creation date in this format...yyyyMMdd_HHmmss .
... obviously artificial intelligence helped me.
This is the source code :
import sys
import os
import shutil
from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QFileDialog, QMessageBox
from PyQt6.QtCore import QDateTime

class FileRenamer(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Redenumire fișiere cu dată și index")
        self.setGeometry(100, 100, 400, 150)

        layout = QVBoxLayout()

        self.button = QPushButton("Selectează folderul și redenumește fișierele")
        self.button.clicked.connect(self.rename_files)
        layout.addWidget(self.button)

        self.setLayout(layout)

    def rename_files(self):
        folder = QFileDialog.getExistingDirectory(self, "Selectează folderul")
        if not folder:
            return

        files = [f for f in os.listdir(folder) if os.path.isfile(os.path.join(folder, f))]
        files.sort()  # Sortează pentru consistență

        for index, filename in enumerate(files, start=1):
            old_path = os.path.join(folder, filename)
            try:
                creation_time = os.path.getctime(old_path)
                dt = QDateTime.fromSecsSinceEpoch(int(creation_time))
                date_str = dt.toString("yyyyMMdd_HHmmss")
                ext = os.path.splitext(filename)[1]
                new_name = f"{date_str}_{index:03d}{ext}"
                new_path = os.path.join(folder, new_name)

                # Evită suprascrierea fișierelor existente
                if not os.path.exists(new_path):
                    shutil.move(old_path, new_path)
            except Exception as e:
                QMessageBox.critical(self, "Eroare", f"Eroare la fișierul {filename}:\n{str(e)}")
                continue

        QMessageBox.information(self, "Succes", "Fișierele au fost redenumite cu succes!")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = FileRenamer()
    window.show()
    sys.exit(app.exec())

Friday, October 17, 2025

Python 3.12.12 : Google colab example of satellite detecting edges .

Simple colab project with google satellite detecting ...
I used these python packages:
%pip install segment-geospatial
%pip install leafmap
%pip install samgeo
%pip install localtileserver
%pip install fiona
This is the result:

Thursday, October 16, 2025

News : Google DeepMind and Google Colab - part 001.

Today I tested Google DeepMind and Google Colab.
You can see my simple test on Suceava area ...

Monday, October 13, 2025

News : What’s new in Python 3.14.

... this news is old from five days ago .
Python 3.14 is the latest stable release of the Python programming language, with a mix of changes to the language, the implementation, and the standard library.

Saturday, October 11, 2025

Python 3.8.5 : ... online python tool

You can found this good online tool for simple python programming. See the result with version and python modules used into this online tool.
Versiunea de Python: 3.8.5 (default, Jul 20 2020, 23:11:29) 
[GCC 9.3.0]

Module instalate:
- webencodings (0.5.1)
- urllib3 (1.25.9)
- toml (0.10.1)
- six (1.15.0)
- setuptools (47.0.0)
- retrying (1.3.3)
- requests (2.23.0)
- pytz (2020.1)
- pytoml (0.1.21)
- python-dateutil (2.8.1)
- pyparsing (2.4.7)
- progress (1.5)
- pip (20.1.1)
- pep517 (0.8.2)
- pandas (1.1.0)
- packaging (20.4)
- ordered-set (4.0.1)
- numpy (1.19.1)
- msgpack (1.0.0)
- lockfile (0.12.2)
- idna (2.9)
- html5lib (1.0.1)
- distro (1.5.0)
- distlib (0.3.0)
- contextlib2 (0.6.0)
- colorama (0.4.3)
- chardet (3.0.4)
- certifi (2020.4.5.1)
- CacheControl (0.12.6)
- appdirs (1.4.4)


** Process exited - Return Code: 0 **

Tuesday, October 7, 2025

Python 3.15 : PEP 810 - Explicit lazy imports

Python’s import system could be in for its biggest change in years.
Lazy imports are controlled, in the sense that deferred loading is only triggered by the importing code itself.
This avoids shifting responsibility onto downstream users and prevents accidental surprises in library behavior.
The new explicit lazy import mechanism enhances security by deferring module initialization until runtime, thereby minimizing the attack surface and preventing premature execution of potentially vulnerable or malicious code during application startup.

Saturday, October 4, 2025

Friday, September 26, 2025

Python Qt6 : tool for game development with PNG images.

Today, I worked with art artificial intelligence, to create tool for my game development.
I used python and PyQt6 and this tool help me to remove border, resize, split, rename and save images as PNG file type for Godot game engine.

Wednesday, September 24, 2025

Python 3.10.7 : Krita and python - part 002.

A simple source code to export PNG file for Godot game engine as Texture2D .
from krita import *
from PyQt5.QtWidgets import QAction, QMessageBox
import os

class ExportGodotPNG(Extension):
    def __init__(self, parent):
        super().__init__(parent)

    def setup(self):
        pass

    def export_png(self):
        # Get the active document
        doc = Krita.instance().activeDocument()
        if not doc:
            QMessageBox.warning(None, "Error", "No document open! Please open a document and try again.")
            return

        # Create an InfoObject for PNG export
        info = InfoObject()
        info.setProperty("alpha", True)  # Keep alpha channel for transparency
        info.setProperty("compression", 0)  # No compression for maximum quality
        info.setProperty("interlaced", False)  # Disable interlacing
        info.setProperty("forceSRGB", True)  # Force sRGB for Godot compatibility

        # Build the output file path
        if doc.fileName():
            base_path = os.path.splitext(doc.fileName())[0]
        else:
            base_path = os.path.join(os.path.expanduser("~"), "export_godot")
        output_file = base_path + "_godot.png"

        # Export the document as PNG
        try:
            doc.exportImage(output_file, info)
            # Show success message with brief usage info
            QMessageBox.information(None, "Success", 
                f"Successfully exported as PNG for Godot: {output_file}\n\n"
                "This PNG has no compression, alpha channel support, and sRGB for Godot compatibility. "
                "To use in Godot, import the PNG and adjust texture settings as needed."
            )
        except Exception as e:
            QMessageBox.critical(None, "Error", f"Export failed: {str(e)}")

    def createActions(self, window):
        # Create only the export action in Tools > Scripts
        action_export = window.createAction("export_godot_png", "Export Godot PNG", "tools/scripts")
        action_export.triggered.connect(self.export_png)

# Register the plugin
Krita.instance().addExtension(ExportGodotPNG(Krita.instance()))

Thursday, September 18, 2025

Blender 3D : ... addon add all materials from folder.

This is a simple addon for Blender 3D version 3.6.x version.
The addon search recursive all blend files from one folder and take all materials.
Let's see the script:
bl_info = {
    "name": "Append Materials from Folder",
    "author": "Grok",
    "version": (1, 2),
    "blender": (3, 0, 0),
    "location": "View3D > Sidebar > Append Materials",
    "description": "Select a folder and append all materials from .blend files recursively",
    "category": "Import-Export",
}

import bpy
import os
from bpy.types import Operator, Panel, PropertyGroup
from bpy.props import StringProperty, PointerProperty

class AppendMaterialsProperties(PropertyGroup):
    folder_path: StringProperty(
        name="Folder Path",
        description="Path to the folder containing .blend files",
        default="",
        maxlen=1024,
        subtype='DIR_PATH'
    )

class APPEND_OT_materials_from_folder(Operator):
    bl_idname = "append.materials_from_folder"
    bl_label = "Append Materials from Folder"
    bl_options = {'REGISTER', 'UNDO'}
    bl_description = "Append all materials from .blend files in the selected folder and subfolders"

    def execute(self, context):
        props = context.scene.append_materials_props
        folder_path = props.folder_path

        # Normalize path to avoid issues with slashes
        folder_path = os.path.normpath(bpy.path.abspath(folder_path))
        if not folder_path or not os.path.isdir(folder_path):
            self.report({'ERROR'}, f"Invalid or no folder selected: {folder_path}")
            return {'CANCELLED'}

        self.report({'INFO'}, f"Scanning folder: {folder_path}")
        blend_files_found = 0
        materials_appended = 0
        errors = []

        # Walk recursively through the folder
        for root, dirs, files in os.walk(folder_path):
            self.report({'INFO'}, f"Checking folder: {root}")
            for file in files:
                if file.lower().endswith('.blend'):
                    blend_files_found += 1
                    blend_path = os.path.join(root, file)
                    self.report({'INFO'}, f"Found .blend file: {blend_path}")
                    try:
                        # Open the .blend file to inspect materials
                        with bpy.data.libraries.load(blend_path, link=False) as (data_from, data_to):
                            if data_from.materials:
                                data_to.materials = data_from.materials
                                materials_appended += len(data_from.materials)
                                self.report({'INFO'}, f"Appended {len(data_from.materials)} materials from: {blend_path}")
                            else:
                                self.report({'WARNING'}, f"No materials found in: {blend_path}")
                    except Exception as e:
                        errors.append(f"Failed to process {blend_path}: {str(e)}")
                        self.report({'WARNING'}, f"Error in {blend_path}: {str(e)}")

        # Final report
        if blend_files_found == 0:
            self.report({'WARNING'}, f"No .blend files found in {folder_path} or its subfolders!")
        else:
            self.report({'INFO'}, f"Found {blend_files_found} .blend files, appended {materials_appended} materials.")
        if errors:
            self.report({'WARNING'}, f"Encountered {len(errors)} errors: {'; '.join(errors)}")

        return {'FINISHED'}

class VIEW3D_PT_append_materials(Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Append Materials"
    bl_label = "Append Materials from Folder"

    def draw(self, context):
        layout = self.layout
        props = context.scene.append_materials_props
        layout.prop(props, "folder_path")
        layout.operator("append.materials_from_folder", text="Append Materials")

def register():
    bpy.utils.register_class(AppendMaterialsProperties)
    bpy.utils.register_class(APPEND_OT_materials_from_folder)
    bpy.utils.register_class(VIEW3D_PT_append_materials)
    bpy.types.Scene.append_materials_props = PointerProperty(type=AppendMaterialsProperties)

def unregister():
    bpy.utils.unregister_class(VIEW3D_PT_append_materials)
    bpy.utils.unregister_class(APPEND_OT_materials_from_folder)
    bpy.utils.unregister_class(AppendMaterialsProperties)
    del bpy.types.Scene.append_materials_props

if __name__ == "__main__":
    register()