[Python] Integrating a text input to blender

Discussão em 'Python' iniciado por Stack, Agosto 5, 2025.

  1. Stack

    Stack Membro Participativo

    I am implementing an .bpy for an input module to blender using pycharm and am running into an issue with the .bpy not installing properly. I'll be bashing this for a bit, but wanted to start a thread involving font requirements in the system transposer while using a custom font install.

    There is an issue with they .bpy not initiating and I will post my updates in my progress.

    Used Junie to construct the passthrough for the base interface to input 2 lines of text.
    Utilized a custom font installed in a general location.
    Import text from UI to a base layer as objects converted to meshes.
    Create: Curve a ( 0, 0)
    Curve: Align text to curve.
    Text_1: Set rotation to X90
    Text_2: Set Rotation to x90

    Junie script compiled for module || output in blender compiler

    classes = (
    TextImporterProperties,
    TEXT_PT_importer_panel,
    TEXT_OT_import_to_blender,
    )

    # Registration
    def register():
    for cls in classes:
    bpy.utils.register_class(cls)
    bpy.types.Scene.text_importer_props = bpy.props.PointerProperty(type=TextImporterProperties)

    def unregister():
    for cls in reversed(classes):
    bpy.utils.unregister_class(cls)
    del bpy.types.Scene.text_importer_props

    import bpy.ops.curve.primitive_bezier_circle_add
    (radius=1, enter_editmode+False, align_'WORLD', location=(0, 0, 0), scale=(1, 1, 1)) as bpy
    import os
    from bpy.props import StringProperty

    # Custom properties to store the text field values
    class TextImporterProperties(bpy.types.PropertyGroup):
    text_field_1: StringProperty(
    name="Text Field 1",
    description="Enter text for field 1",
    default=""
    )

    text_field_2: StringProperty(
    name="Text Field 2",
    description="Enter text for field 2",
    default=""
    )

    # Panel to display the text fields
    class TEXT_PT_importer_panel(bpy.types.Panel):
    bl_label = "Text Importer"
    bl_idname = "TEXT_PT_importer"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Text Importer'

    def draw(self, context):
    layout = self.layout
    scene = context.scene
    text_props = scene.text_importer_props

    # Text Field 1
    layout.label(text="Text Field 1:")
    layout.prop(text_props, "text_field_1", text="")

    # Text Field 2
    layout.label(text="Text Field 2:")
    layout.prop(text_props, "text_field_2", text="")

    # Import button
    layout.separator()
    layout.operator("text.import_to_blender", text="Import Text")

    # Operator to handle the import action
    class TEXT_OT_import_to_blender(bpy.types.Operator):
    bl_idname = "text.import_to_blender"
    bl_label = "Import Text to Blender"
    bl_description = "Import the text from both fields into Blender"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
    scene = context.scene
    text_props = scene.text_importer_props

    text1 = text_props.text_field_1
    text2 = text_props.text_field_2

    # Process text from Field 1
    if text1:
    self.process_field1_text(context, text1)

    # Process text from Field 2
    if text2:
    self.process_field2_text(context, text2)

    self.report({'INFO'}, "Text imported and processed successfully")
    return {'FINISHED'}

    def create_text_object(self, context, text_content, name, location):
    # Create a new text curve data block
    text_curve = bpy.data.curves.new(type="FONT", name=name)
    text_curve.body = text_content

    # Create a new object with the text curve
    text_obj = bpy.data.objects.new(name, text_curve)
    text_obj.location = location

    # Link the object to the current collection
    context.collection.objects.link(text_obj)

    return text_obj

    def create_cylinder(self, context, name):
    # Add a cylinder
    bpy.ops.mesh.primitive_cylinder_add(vertices=146, radius=2.5, depth=4.0)
    cylinder = context.active_object
    cylinder.name = name

    # Set cap fill type to "Nothing"
    bpy.ops.object.mode_set(mode='EDIT')
    bpy.ops.mesh.select_all(action='SELECT')
    bpy.ops.mesh.delete(type='ONLY_FACE')
    bpy.ops.object.mode_set(mode='OBJECT')

    # Set location X to 0 - Test set for offset if needed
    cylinder.location.x = 0.0


    def process_field1_text(self, context, text_content):
    # Create text object
    text_obj = self.create_text_object(context, text_content, "Field1Text", (0, 0, 0))

    # Select the text object
    bpy.ops.object.select_all(action='DESELECT')
    text_obj.select_set(True)
    context.view_layer.objects.active = text_obj

    -------

    # Convert text to curve
    bpy.ops.object.convert(target='CURVE')

    # Create cylinder for text deformation
    cylinder = self.create_cylinder(context, "Field1Cylinder")

    # Select the text again
    bpy.ops.object.select_all(action='DESELECT')
    text_obj.select_set(True)
    context.view_layer.objects.active = text_obj

    # Set geometry taper object to cylinder
    text_obj.data.taper_object = cylinder

    # Add curve modifier
    curve_modifier = text_obj.modifiers.new(name="Curve", type='CURVE')
    curve_modifier.object = cylinder

    # Set rotation X to -90 degrees
    text_obj.rotation_euler.x = -1.5708 # -90 degrees in radians

    return text_obj

    def process_field2_text(self, context, text_content):
    # Create text object
    text_obj = self.create_text_object(context, text_content, "Field2Text", (0, 0, 0))

    # Select the text object
    bpy.ops.object.select_all(action='DESELECT')
    text_obj.select_set(True)
    context.view_layer.objects.active = text_obj

    -------

    # Convert text to curve
    bpy.ops.object.convert(target='CURVE')

    # Create cylinder for text deformation
    cylinder = self.create_cylinder(context, "Field2Cylinder")

    # Select the text again
    bpy.ops.object.select_all(action='DESELECT')
    text_obj.select_set(True)
    context.view_layer.objects.active = text_obj

    # Set geometry taper object to cylinder
    text_obj.data.taper_object = cylinder

    # Add curve modifier
    curve_modifier = text_obj.modifiers.new(name="Curve", type='CURVE')
    curve_modifier.object = cylinder

    # Set deform axis to -X
    curve_modifier.deform_axis = 'NEG_X'

    return text_obj

    if __name__ == "__main__":
    register()


    Python: Traceback (most recent call last):
    File "C:\
    Foundation\Blender\4.1\scripts\addons\_init4_.py", line 75, in execute
    self.process_field1_text(context, text1)
    File "C:\
    Foundation\Blender\4.1\scripts\addons\_init4_.py", line 132, in process_field1_text
    font_path = os.path.join(bpy.utils.user_resource('FONTS'), "My decorative font.ttf")
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "C:
    4.1\4.1\scripts\modules\bpy\utils\__init__.py", line 749, in user_resource
    target_path = _user_resource(resource_type, path=path)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ValueError: expected a string in ('DATAFILES', 'CONFIG', 'SCRIPTS', 'AUTOSAVE'), got 'FONTS'

    Continue reading...

Compartilhe esta Página