Skip to content

DXF export issue #1767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
adam-urbanczyk opened this issue Feb 13, 2025 · 10 comments
Open

DXF export issue #1767

adam-urbanczyk opened this issue Feb 13, 2025 · 10 comments
Labels

Comments

@adam-urbanczyk
Copy link
Member

My use-case has a far smaller work scope: I only need 3D-to-2D projections. Dimensions & annotation are not required. Kind of similar to #1685 except in DXF:

Here is my reduced workflow:

  1. On-demand 3rd angle projections of the same part to three separate DXF files (e.g. top.dxf, left.dxf, front.dxf)

  2. Write a simple (Python/bash) script to embed the DXF files into a ISO titleblock template, e.g. this file

  3. Open the output DXF in the LibreCAD GUI.

  4. Manually draw dimensions on the titleblock with command prompt or with the mouse.

I managed to simulate #1685 with the following code:

def exportDXF3rdAngleProjection(my_part, prefix: str) -> None:
    viewpoint = {
        'top': (0, 0, 1),
        'left': (1, 0, 0),
        'front': (0, 1, 0),
    }
    for name, direction in viewpoint.items():
        cq.exporters.exportDXF(
            mounting_rail.rotateAboutCenter(direction, 90),
            f"{prefix}{name}.dxf",

            # Note: exportDXF is missing the following parameter.
            #opt={
            #    "projectionDir": direction,
            #},
            doc_units=6,
        )

but the issue is cq.exporters.exportDXF messed up the countersunk holes:

Image

Question: is it a known issue in cadquery? Is there a bug report on Github that I can keep track of?

Originally posted by @antonysigma in #122

@adam-urbanczyk
Copy link
Member Author

@antonysigma could you provide a MRE?

@antonysigma
Copy link

antonysigma commented Feb 13, 2025

could you provide a MRE?

@adam-urbanczyk , here you are. Thanks in advance!

Python version: Python 3.9.5
cadquery version: cadquery==2.5.2

import cadquery as cq
from ocp_vscode import (
    set_port,
    show_object,
)

viewpoint = {
    'top': (0, 0, 1),
    'left': (1, 0, 0),
    'front': (0, 1, 0),
}

def exportDXF3rdAngleProjection(my_part, prefix: str) -> None:
    for name, direction in viewpoint.items():
        cq.exporters.exportDXF(
            my_part.rotateAboutCenter(direction, 90),
            f"{prefix}{name}.dxf",

            # Note: exportDXF is missing the following parameter.
            #opt={
            #    "projectionDir": direction,
            #},
            doc_units=6,
        )

def exportSVG3rdAngleProjection(my_part, prefix: str) -> None:
    for name, direction in viewpoint.items():
        cq.exporters.export(
            my_part,
            f'{prefix}{name}.svg',
            opt={
                'projectionDir': direction,
            },
        )

if __name__ == '__main__':
    # Build the part
    width = 10
    depth = 10
    height = 10.0

    # !!! Test projection of fillets to arc segments in DXF. !!!
    baseplate = (
        cq.Workplane("XY")  #
        .box(width, depth, height)
        .edges("|Z")
        .fillet(2.0)
    )

    hole_dia = 3.0

    # !!! Test projection of countersunk to arc segments in DXF. !!!
    drilled = (
        baseplate.faces(">Z")  #
        .workplane()
        .cskHole(hole_dia, hole_dia * 2, 82.0)
    )

    # Expected DXF output to be identical to SVG output
    exportSVG3rdAngleProjection(drilled, "")
    exportDXF3rdAngleProjection(drilled, "")

    # Initialize the ocp_vscode viewer
    if False:
        set_port(3939)
        show_object(drilled)

@antonysigma
Copy link

Hi @adam-urbanczyk ,

Do we need a simplier MRE for debugging? Actually, a side view of a cylinder will also reproduce issue.

Also, whom should I tag here to get more visibility?

-Antony

@adam-urbanczyk
Copy link
Member Author

Good that you poked. I'll take a look.

@adam-urbanczyk
Copy link
Member Author

OK, so DXF export only exports 2D sections and (at least currently) it does not do projections like export SVG (the use case for DXF export so far was generating file for laser cutting). It is mentioned in passing in the docstring. I'll add a note to the docs to make it clearer.

@antonysigma
Copy link

Thank you for the clarifications. Applying UNIX principles (i.e. build one command line app to do one job and do it well), I suppose I will use Cadquery to export STEP, and then write an external script to convert STEP files to 2D projections in DXF format.

Thanks!

@Jopie01
Copy link

Jopie01 commented Mar 26, 2025

Hello, just wanted to chime in here. I have created my own DXF export class to do a lot of particular stuff like adding views, paperspace layouts, scaling, dimensions, hatching and BOMs. I hope I get some free time on my hands to lift the basic stuff out of it and hopefully it will be accepted to be in CadQuery. Exporting a DXF file is becoming a bit more complex because some extra steps are involved.

I will use Cadquery to export STEP, and then write an external script to convert STEP files to 2D projections in DXF format.

The question is, how are you going to convert a 3D STEP file into a 2D DXF? you can write something yourself, but way easier is to use CadQuery and write you own DXF exporter, because you have already your 3D model. Take a look at https://github.com/CadQuery/cadquery/blob/master/cadquery/occ_impl/exporters/dxf.py to see how the "3D lines" are converted into "DXF lines"

@adam-urbanczyk
Copy link
Member Author

@Jopie01 adding dimensions was requested quite some time ago, so if you have something a PR would be nice.

@antonysigma
Copy link

way easier is to use CadQuery and write you own DXF exporter, because you have already your 3D model.

Great! I am not a developer, but I can help review code, especially the _dxf_ellipse function. Do we have a PR at cadquery's github repo?

If there's a PR, I can in turn contribute a simple example code to showcase 2D projections. Similar to the MRE that I posted at the top of this issue.

The question is, how are you going to convert a 3D STEP file into a 2D DXF?

In the past (2010s), I imported the STEP file manually into FreeCAD's TechDraw extension, and then generated 2D projections manually. Now that we are in 2020s, maybe we can I can script the build123d https://build123d.readthedocs.io/en/latest/import_export.html#d-to-2d-projection to process the STEP files.

Take a look at https://github.com/CadQuery/cadquery/blob/master/cadquery/occ_impl/exporters/dxf.py to see how the "3D lines" are converted into "DXF lines"

Again, I am a user, not a developer. I believe what makes Cadquery attractive (over build123d) is the fluentAPI and declarative programming APIs. Paraphrasing Cadquery's Readme, 3D part as a hardware should follow the hardware engineer's logic, not following the (Python idiomatic) software engineer's logic. However, this in turn impacts the developer experience because most users do not speak idiomatic Python, especially compared to Build123d users. So, most of us are unable to contribute imperative software code back to the Cadquery's repo.

@antonysigma
Copy link

@adam-urbanczyk Let us know if we should close this issue, and then move the discussion (baremetal 2D projection support with ellipses and arcs) to elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants