Skip to content
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

DXF multilayer support #1267

Merged
merged 6 commits into from
Mar 16, 2023
Merged

Conversation

sethfischer
Copy link
Contributor

@sethfischer sethfischer commented Feb 10, 2023

A proposed approach to #1171.

Also supports:

Closes #1171
Closes #1188
Closes #1259

Todo

  • documentation
  • tests

Notes

  • The ezdxf document object is available via the public API so most features of ezdxf are accessible.
  • cadquery.occ_impl.exporters.dxf.exportDXF has be refactored but there is no change to the public API.
  • Methods _dxf_* have been refactored to better facilitate unit testing. There is no change to algorithm of these methods.

Example use

"""DXF multilayer demo."""

import cadquery as cq
from cadquery.occ_impl.exporters.dxf import DxfDocument

spline_points = [(90, 50), (83, 60), (65, 50), (50, 33), (33, 40), (15, 35), (0, 35)]
spline = (
    cq.Workplane("XY")
    .lineTo(100, 0)
    .lineTo(100, 35)
    .spline(spline_points, includeCurrent=True)
    .close()
)

circle = cq.Workplane().moveTo(15, 15).circle(10)
ellipse = cq.Workplane().moveTo(45, 15).ellipse(15, 10, 0)
rectangle = cq.Workplane().moveTo(70, 15).rect(10, 20)
fold_line = cq.Workplane().moveTo(80, -5).line(0, 70)

# create the DXF document

dxf = DxfDocument(setup=True)

dxf = (
    dxf.add_layer("layer_cut", color=2)
    .add_layer("layer_line_engrave", color=3)
    .add_layer("layer_area_engrave", color=4)
    .add_layer("layer_fold", color=5, linetype="DASHED")
    .add_shape(spline, "layer_cut")
    .add_shape(ellipse, "layer_cut")
    .add_shape(circle, "layer_line_engrave")
    .add_shape(rectangle, "layer_area_engrave")
    .add_shape(fold_line, "layer_fold")
)

dxf.document.saveas("multilayer-demo.dxf")

Screenshot of resulting multilayer-demo.dxf viewed in LibreCAD:

1267-librecad-screenshot_2023-02-10

This still works as expected but is refactored to call DxfDocument and DXF document units are mm:

import cadquery as cq
from cadquery import exporters

result = cq.Workplane().box(10, 10, 10)

exporters.export(result, "export.dxf")

Export DXF with document units other then the default:

exporters.export(
    result,
    "export.dxf",
    opt={"doc_units": 6},  # set DXF document units to meters
)

exporters.exportDXF(
    result,
    "export.dxf",
    doc_units=6,  # set DXF document units to meters
)

@adam-urbanczyk
Copy link
Member

You might to want to wait with this until #1226 is merged.

@sethfischer
Copy link
Contributor Author

You might to want to wait with this until #1226 is merged.

@adam-urbanczyk Will do. Once merged I'll rebase this work on master

@sethfischer sethfischer force-pushed the dxf-multilayer branch 5 times, most recently from 6130774 to 9efdc6c Compare February 11, 2023 00:23
@codecov
Copy link

codecov bot commented Feb 11, 2023

Codecov Report

Merging #1267 (758c64b) into master (0aa889c) will increase coverage by 0.07%.
The diff coverage is 97.50%.

❗ Current head 758c64b differs from pull request most recent head ea6acb5. Consider uploading reports for the commit ea6acb5 to get more accurate results

@@            Coverage Diff             @@
##           master    #1267      +/-   ##
==========================================
+ Coverage   94.17%   94.24%   +0.07%     
==========================================
  Files          26       26              
  Lines        5455     5495      +40     
  Branches      926      932       +6     
==========================================
+ Hits         5137     5179      +42     
+ Misses        188      187       -1     
+ Partials      130      129       -1     
Impacted Files Coverage Δ
cadquery/occ_impl/exporters/dxf.py 97.00% <96.93%> (+4.57%) ⬆️
cadquery/cq.py 92.23% <100.00%> (+0.04%) ⬆️
cadquery/occ_impl/assembly.py 98.60% <100.00%> (ø)
cadquery/occ_impl/exporters/__init__.py 94.11% <100.00%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@sethfischer
Copy link
Contributor Author

I've rebased this on master pulling in #1226 which introduced parameters approx and tolerance.

Should approx and tolerance be:

  1. properties of the DXF document? or,
  2. properties of the shape being added?, or
  3. properties of both the DXF document and the shape?

1. Properties of the DXF document

Properties of the DXF document applying to all shapes added with add_shape.

dxf = DxfDocument(approx: Optional[Literal["spline", "arc"]] = None, tolerance: float = 1e-3)
dxf.add_shape(shape)

2. Properties of the shape being added

Property of the shape added with add_shape.

dxf = DxfDocument()
dxf.add_shape(shape, approx: Optional[Literal["spline", "arc"]] = None, tolerance: float = 1e-3)

3. Properties of both the DXF document and the shape

Properties of the DXF document applying to all shapes added with add_shape. But specific shapes can have their own approx and tolerance values.

dxf = DxfDocument(approx: Optional[Literal["spline", "arc"]] = None, tolerance: float = 1e-3)
dxf.add_shape(shape, approx: Optional[Literal["spline", "arc"]] = None, tolerance: float = 1e-3)

@adam-urbanczyk
Copy link
Member

Definitely a property of the document. You might also add an option to override on per-shape basis, but I personally don't have such a use case.

@sethfischer sethfischer force-pushed the dxf-multilayer branch 18 times, most recently from d4d5a28 to 263364c Compare February 26, 2023 09:25
@adam-urbanczyk
Copy link
Member

@lorenzncode you might want to integrate #1278 into this PR

@sethfischer
Copy link
Contributor Author

@adam-urbanczyk back to you for review.

Copy link
Member

@adam-urbanczyk adam-urbanczyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, last two remarks regarding diff coverage. Could you extend the tests?

cadquery/occ_impl/exporters/dxf.py Show resolved Hide resolved
cadquery/occ_impl/exporters/dxf.py Show resolved Hide resolved
@sethfischer sethfischer requested review from adam-urbanczyk and removed request for lorenzncode March 10, 2023 23:59
doc/importexport.rst Outdated Show resolved Hide resolved
* Set DXF layer color to ezdxf default white/black
* Add exporters DxfDocument import
* DXF units, colors doc udpate
@lorenzncode
Copy link
Member

I've added the fix from #1278. Thanks @sethfischer!

@adam-urbanczyk
Copy link
Member

Thanks @sethfischer

@adam-urbanczyk adam-urbanczyk merged commit 2d35517 into CadQuery:master Mar 16, 2023
This was referenced Mar 16, 2023
@sethfischer
Copy link
Contributor Author

Thank you @adam-urbanczyk and @lorenzncode

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