Hi There!
I am working on a script, which imports curves and converts them to a mesh automatically.
It works fine so far, but I am stuck with converting the curve to be of BEZIER typem which is needed to get better UVs.
My code so far:
import bpy
from bpy.props import (StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
EnumProperty,
PointerProperty,
)
from bpy.types import (Panel,
Menu,
Operator,
PropertyGroup,
)
# ------------------------------------------------------------------------
# Scene Properties
# ------------------------------------------------------------------------
class MyProperties(PropertyGroup):
svgSourcePath: StringProperty(
name = "Directory",
description="Choose a directory:",
default="",
maxlen=1024,
subtype='FILE_PATH'
)
fbxExportPath: StringProperty(
name = "Directory",
description="Choose a directory:",
default="",
maxlen=1024,
subtype='DIR_PATH'
)
pictoName: StringProperty(
name = "Pictogramm Name",
description="Choose a directory:",
default="",
maxlen=1024,
#subtype='DIR_PATH'
)
# ------------------------------------------------------------------------
# Operators
# ------------------------------------------------------------------------
class WM_OT_pictomesher(Operator):
bl_label = "~ ~ ~ Mesh it! ~ ~ ~"
bl_idname = "wm.pictomesher"
def execute(self, context):
scene = context.scene
# The following line is pure magic to me, but works?!?
mytool = scene.my_tool
svgfilepath = mytool.svgSourcePath
bpy.ops.import_curve.svg(filepath=svgfilepath)
# Create a Material for Checking/Debugging in Blender
if bpy.data.materials.get('SplineTestMaterial') is None:
testMaterial = bpy.data.materials.new(name="SplineTestMaterial")
testMaterial.use_nodes = True
nodes = testMaterial.node_tree.nodes
tree = testMaterial.node_tree
emission = nodes.new('ShaderNodeEmission')
emission.location = (-200,100)
gradient = nodes.new('ShaderNodeTexGradient')
gradient.location = (-400, 100)
mapping = nodes.new('ShaderNodeMapping')
mapping.location = (-800, 100)
mapping.scale[0] = 100
mapping.translation[0] = -50
coord = nodes.new('ShaderNodeTexCoord')
coord.location = (-1000, 100)
tree.links.new(emission.outputs[0],nodes["Material Output"].inputs[0])
tree.links.new(gradient.outputs[0], emission.inputs[0])
tree.links.new(mapping.outputs[0], gradient.inputs[0])
tree.links.new(coord.outputs[2], mapping.inputs[0])
else:
testMaterial = bpy.data.materials.get('SplineTestMaterial')
curves = []
for obj in bpy.data.objects:
obj.select_set(obj.type == "CURVE")
curves = bpy.context.selected_objects
# Normalize input Curves
dimensionValues = []
for curve in curves:
scale = curve.scale
minx = curve.bound_box[0][0] * scale.x
maxx = curve.bound_box[4][0] * scale.x
miny = curve.bound_box[0][1] * scale.y
maxy = curve.bound_box[2][1] * scale.y
dx = maxx - minx
dy = maxy - miny
dimensionValues.append(dx)
dimensionValues.append(dy)
highestDimensionValue = 0
for value in dimensionValues:
if value > highestDimensionValue:
highestDimensionValue = value
bpy.ops.transform.resize(value=(1/highestDimensionValue, 1/highestDimensionValue, 1/highestDimensionValue))
# Creating Nurbs Curve for sweeping if None exists
if bpy.data.objects.get('NurbsCircle') is None:
nurbs_circle = 0
nurbs_circle_size = 0.00025
nurbs_circle = bpy.ops.curve.primitive_nurbs_circle_add(radius=nurbs_circle_size, enter_editmode=False, location=(0, 0, 0))
print(nurbs_circle)
myNurbs = bpy.data.objects.get('NurbsCircle')
myNurbs.data.resolution_u = 2
# Sweep Curve
for curve in curves:
bpy.context.view_layer.objects.active = curve
bpy.context.object.data.bevel_object = bpy.data.objects["NurbsCircle"]
bpy.context.object.data.resolution_u = 16
bpy.context.object.data.use_uv_as_generated = True
bpy.context.object.data.materials.append(testMaterial)
bpy.context.object.data.dimensions = '2D'
#bpy.context.object.data.type='BEZIER'
# Set HandleType
for curve in curves:
#curve.spline_type_set(type='BEZIER')
#Find the Blender object of interest
crv_obj = curve
#Get access to the curve object data
crv_data = crv_obj.data
#active spline
spline = crv_data.splines.active
#Find the active bezier control point bcp
selected_points = [bcp for bcp in spline.bezier_points if bcp.select_control_point]
for bez_point in selected_points:
#Set Free
bez_point.handle_right_type = 'FREE'
bez_point.handle_left_type = 'FREE'
# Convert Curves to Meshes
for curve in curves:
deg = context.evaluated_depsgraph_get()
me = bpy.data.meshes.new_from_object(curve.evaluated_get(deg), depsgraph=deg)
new_obj = bpy.data.objects.new(curve.name + "_mesh", me)
bpy.context.collection.objects.link(new_obj)
for o in context.selected_objects:
o.select_set(False)
new_obj.matrix_world = curve.matrix_world
new_obj.select_set(True)
context.view_layer.objects.active = new_obj
# Export
exportpath = mytool.fbxExportPath
bpy.ops.export_scene.fbx(filepath=exportpath + mytool.pictoName + ".fbx", check_existing=True,global_scale=1, bake_space_transform=True, use_selection=False,object_types={'EMPTY', 'MESH'}, axis_up='Y')
cont = bpy.context.area.type
print(str(cont))
return {'FINISHED'}
# ------------------------------------------------------------------------
# Panel in Object Mode
# ------------------------------------------------------------------------
class LayoutDemoPanel(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "PictoMesher"
bl_idname = "SCENE_PT_layout3"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool
layout.label(text="SVG Datei:")
layout.prop(mytool, "svgSourcePath")
layout.label(text="Export Ordner:")
layout.prop(mytool, "fbxExportPath")
layout.label(text="Pictogramm Name - muss gesetzt sein!!!")
layout.prop(mytool, "pictoName")
# Big render button
layout.label(text="Big Button:")
row = layout.row()
row.scale_y = 3.0
row.operator("wm.pictomesher")
# ------------------------------------------------------------------------
# Registration
# ------------------------------------------------------------------------
classes = (
MyProperties,
WM_OT_pictomesher,
LayoutDemoPanel
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
bpy.types.Scene.my_tool = PointerProperty(type=MyProperties)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()