discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Semi-automatic dxf to turtle code convertor

YV
yur_vol@yahoo.com
Mon, Mar 16, 2026 11:39 AM

I like to build curves ( reverse engineering) using somthing like biarc interpolation tool I found in MOI3D cad. I import a reference image, then draw with a mouse and export in dxf.
There are onle LINEs and ARCs sequences in dxf now.
I rewrote python example to save the LINE and ARC parameters to turtle code.
I have not enough skills to write fully automatic routine. So you need manually  turn arcs left/right.

I like to build curves ( reverse engineering) using somthing like biarc interpolation tool I found in MOI3D cad. I import a reference image, then draw with a mouse and export in dxf.\ There are onle LINEs and ARCs sequences in dxf now.\ I rewrote python example to save the LINE and ARC parameters to turtle code.\ I have not enough skills to write fully automatic routine. So you need manually turn arcs left/right.
YV
yur_vol@yahoo.com
Mon, Mar 16, 2026 11:40 AM
import ezdxf
import math
def extract_dwg_data(file_path):
    try:
        # Leer el archivo DXF
        doc = ezdxf.readfile(file_path)
    except IOError:
        print(f"No se puede leer el archivo: {file_path}")
        return None
    except ezdxf.DXFStructureError:
        print(f"Archivo DXF no válido: {file_path}")
        return None
    # Obtener el espacio de modelo
    modelspace = doc.modelspace()
    def extract_entities(entities):
        extracted_data = []
        for entity in entities:
            entity_data = {"type": entity.dxftype()}
            if entity.dxftype() == 'LINE':
                entity_data["start_point"] = entity.dxf.start
                entity_data["end_point"] = entity.dxf.end
            elif entity.dxftype() == 'CIRCLE':
                entity_data["center_point"] = entity.dxf.center
                entity_data["radius"] = entity.dxf.radius
            elif entity.dxftype() == 'ARC':
                entity_data["center_point"] = entity.dxf.center
                entity_data["radius"] = entity.dxf.radius
                entity_data["start_angle"] = entity.dxf.start_angle
                entity_data["end_angle"] = entity.dxf.end_angle
            extracted_data.append(entity_data)
        return extracted_data
    def extract_dimension_data(entity):
        dim_data = {
            "dimtype": entity.dimtype,
            "text": entity.dxf.text,
            "insert_point": entity.dxf.insert,
        }
        dim_type = entity.dimtype
        if dim_type == 0:  # Rotated, horizontal, or vertical linear dimension
            dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2]
        elif dim_type == 1:  # Aligned linear dimension
            dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2]
        elif dim_type == 2:  # Angular dimension (2 lines)
            dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2, entity.dxf.defpoint3, entity.dxf.defpoint4]
        elif dim_type == 3:  # Diameter dimension
            dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2]
        elif dim_type == 4:  # Radius dimension
            dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2]
        elif dim_type == 5:  # Angular dimension (3 points)
            dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2, entity.dxf.defpoint3]
        elif dim_type == 6:  # Angular dimension (4 points)
            dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2, entity.dxf.defpoint3, entity.dxf.defpoint4]
        return dim_data
    data = extract_entities(modelspace)
    return data
def create_dwg_file(output_path, data):
    doc = ezdxf.new(dxfversion="R2010")
    modelspace = doc.modelspace()
    lv = 0;
    dv = [0,0];
    print ("path =  turtle3d([")
    for entity in data:
        entity_type = entity.get("type")
        if entity_type == "LINE":
            lv = math.sqrt((entity["end_point"][0] - entity["start_point"][0] )**2 + (entity["end_point"][1] - entity["start_point"][1] )**2)
            dv[0] = (entity["end_point"][0] - entity["start_point"][0] )/lv
            dv[1] = (entity["end_point"][1] - entity["start_point"][1] )/lv
            print ("\"setdir\",[", dv[0],",",dv[1] , "],")
            print ("\"move\",",lv,",")
            modelspace.add_line(entity["start_point"], entity["end_point"])
        elif entity_type == "CIRCLE":
            modelspace.add_circle(entity["center_point"], entity["radius"])
        elif entity_type == "ARC":
            print( "[\"arc\",", entity["radius"], ",\"left\",",  entity["end_angle"]  -  entity["start_angle"],     ", \"steps\", 10 ]," )
 #           modelspace.add_arc(entity["center_point"], entity["radius"], entity["start_angle"], entity["end_angle"])
    print("],transforms=true);")
    print("sweep(circle(1),path);")
    doc.saveas(output_path)
# Uso del script
dwg_file = r"bell1.dxf"
output_file = r"extracted_data.dxf"
extracted_data = extract_dwg_data(dwg_file)
# Guardar los datos extraídos en un nuevo archivo DXF
if extracted_data:
    create_dwg_file(output_file, extracted_data)
# Ejemplo de cómo usar los datos extraídos
if extracted_data:
    output = ",\n".join(str(entity) for entity in extracted_data)
#    print(output)
``` import ezdxf ``` ``` import math ``` ``` def extract_dwg_data(file_path): ``` ``` try: ``` ``` # Leer el archivo DXF ``` ``` doc = ezdxf.readfile(file_path) ``` ``` except IOError: ``` ``` print(f"No se puede leer el archivo: {file_path}") ``` ``` return None ``` ``` except ezdxf.DXFStructureError: ``` ``` print(f"Archivo DXF no válido: {file_path}") ``` ``` return None ``` ``` # Obtener el espacio de modelo ``` ``` modelspace = doc.modelspace() ``` ``` def extract_entities(entities): ``` ``` extracted_data = [] ``` ``` for entity in entities: ``` ``` entity_data = {"type": entity.dxftype()} ``` ``` if entity.dxftype() == 'LINE': ``` ``` entity_data["start_point"] = entity.dxf.start ``` ``` entity_data["end_point"] = entity.dxf.end ``` ``` elif entity.dxftype() == 'CIRCLE': ``` ``` entity_data["center_point"] = entity.dxf.center ``` ``` entity_data["radius"] = entity.dxf.radius ``` ``` elif entity.dxftype() == 'ARC': ``` ``` entity_data["center_point"] = entity.dxf.center ``` ``` entity_data["radius"] = entity.dxf.radius ``` ``` entity_data["start_angle"] = entity.dxf.start_angle ``` ``` entity_data["end_angle"] = entity.dxf.end_angle ``` ``` extracted_data.append(entity_data) ``` ``` return extracted_data ``` ``` def extract_dimension_data(entity): ``` ``` dim_data = { ``` ``` "dimtype": entity.dimtype, ``` ``` "text": entity.dxf.text, ``` ``` "insert_point": entity.dxf.insert, ``` ``` } ``` ``` dim_type = entity.dimtype ``` ``` if dim_type == 0: # Rotated, horizontal, or vertical linear dimension ``` ``` dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2] ``` ``` elif dim_type == 1: # Aligned linear dimension ``` ``` dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2] ``` ``` elif dim_type == 2: # Angular dimension (2 lines) ``` ``` dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2, entity.dxf.defpoint3, entity.dxf.defpoint4] ``` ``` elif dim_type == 3: # Diameter dimension ``` ``` dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2] ``` ``` elif dim_type == 4: # Radius dimension ``` ``` dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2] ``` ``` elif dim_type == 5: # Angular dimension (3 points) ``` ``` dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2, entity.dxf.defpoint3] ``` ``` elif dim_type == 6: # Angular dimension (4 points) ``` ``` dim_data["defpoints"] = [entity.dxf.defpoint, entity.dxf.defpoint2, entity.dxf.defpoint3, entity.dxf.defpoint4] ``` ``` return dim_data ``` ``` data = extract_entities(modelspace) ``` ``` return data ``` ``` def create_dwg_file(output_path, data): ``` ``` doc = ezdxf.new(dxfversion="R2010") ``` ``` modelspace = doc.modelspace() ``` ``` lv = 0; ``` ``` dv = [0,0]; ``` ``` print ("path = turtle3d([") ``` ``` for entity in data: ``` ``` entity_type = entity.get("type") ``` ``` if entity_type == "LINE": ``` ``` lv = math.sqrt((entity["end_point"][0] - entity["start_point"][0] )**2 + (entity["end_point"][1] - entity["start_point"][1] )**2) ``` ``` dv[0] = (entity["end_point"][0] - entity["start_point"][0] )/lv ``` ``` dv[1] = (entity["end_point"][1] - entity["start_point"][1] )/lv ``` ``` print ("\"setdir\",[", dv[0],",",dv[1] , "],") ``` ``` print ("\"move\",",lv,",") ``` ``` modelspace.add_line(entity["start_point"], entity["end_point"]) ``` ``` elif entity_type == "CIRCLE": ``` ``` modelspace.add_circle(entity["center_point"], entity["radius"]) ``` ``` elif entity_type == "ARC": ``` ``` print( "[\"arc\",", entity["radius"], ",\"left\",", entity["end_angle"] - entity["start_angle"], ", \"steps\", 10 ]," ) ``` ``` # modelspace.add_arc(entity["center_point"], entity["radius"], entity["start_angle"], entity["end_angle"]) ``` ``` print("],transforms=true);") ``` ``` print("sweep(circle(1),path);") ``` ``` doc.saveas(output_path) ``` ``` # Uso del script ``` ``` dwg_file = r"bell1.dxf" ``` ``` output_file = r"extracted_data.dxf" ``` ``` extracted_data = extract_dwg_data(dwg_file) ``` ``` # Guardar los datos extraídos en un nuevo archivo DXF ``` ``` if extracted_data: ``` ``` create_dwg_file(output_file, extracted_data) ``` ``` # Ejemplo de cómo usar los datos extraídos ``` ``` if extracted_data: ``` ``` output = ",\n".join(str(entity) for entity in extracted_data) ``` ``` # print(output) ```
YV
yur_vol@yahoo.com
Mon, Mar 16, 2026 11:44 AM
YV
yur_vol@yahoo.com
Mon, Mar 16, 2026 11:47 AM

the above example is closed path. The result turtle code needs to be edited.

python code attached

the above example is closed path. The result turtle code needs to be edited.\ \ python code attached