Skip to content

fix: DXF export renders arcs as straight lines#296

Merged
spe-ciellt merged 4 commits intogerbv:developfrom
SourceParts:fix/dxf-arc-export
Mar 2, 2026
Merged

fix: DXF export renders arcs as straight lines#296
spe-ciellt merged 4 commits intogerbv:developfrom
SourceParts:fix/dxf-arc-export

Conversation

@rampageservices
Copy link
Copy Markdown
Contributor

Summary

Fixes gerbv/gerbv#229 — DXF export turns arcs into single straight lines.

  • Standalone arcs (GERBV_APERTURE_STATE_ON with circular interpolation) now emit native DXF ARC entities via dxf->writeArc(). CW arcs swap angle1/angle2 since DXF arcs are always CCW.
  • Arcs inside polygon fills (PAREA regions) are tessellated into ~2° increment line vertices using cirseg center/radius/angles, instead of a single straight-line vertex from start to stop.
  • Bundles dxflib 3.26.4.0 (GPL-2+, from QCAD upstream) so DXF export works on distributions that don't package dxflib (Fedora, Ubuntu, Debian). CMake falls back to the bundled copy when pkg_check_modules(DXF ...) fails.

Test plan

  • cmake .. && make gerbv gerbv-app — clean build, zero errors, dxflib_bundled static lib created
  • gerbv --export=dxf -o arc.dxf test/inputs/test-circular-interpolation-1.gbx — output contains 4 ARC entities
  • gerbv --export=dxf -o ccw.dxf test/inputs/test-circular-interpolation-mq-ccw.gbx — output contains ARC entity
  • ctest — 94 pass, same 10 pre-existing mismatches, no regressions

The DXF exporter treated all net segments as straight lines, ignoring
circular interpolation. Standalone arcs now emit native DXF ARC entities
(with CW angle swap since DXF arcs are always CCW), and arcs inside
polygon fills are tessellated into ~2-degree line vertices.

Also bundles dxflib 3.26.4.0 (GPL-2+, from QCAD upstream) so DXF export
works on distributions that don't package dxflib. CMake falls back to the
bundled copy when pkg-config cannot find a system dxflib.

Fixes gerbv#229
Remove unused `ret` variable in DL_Dxf::toReal(). The function
returns directly via atof(), so `ret` was declared but never used,
causing -Werror builds to fail.
@rampageservices
Copy link
Copy Markdown
Contributor Author

Fixes needed for bundled dxflib 3.26.4.0 (from QCAD upstream) to compile clean with -Werror:

  1. Unused variable in dl_dxf.cpp — removed unused local
  2. strcasecmp redefinition in dl_codes.h — MinGW's string.h already defines strcasecmp as _stricmp, so the unconditional #define in dl_codes.h:44 triggers -Werror=macro-redefined on the CI cross-compilation build. Fixed with a !defined(strcasecmp) guard (2eaed7b).

Both should be reported upstream to qcad/qcad.

MinGW defines _WIN32 but uses GCC, so MSVC-specific constructs under
#ifdef _WIN32 cause -Werror failures in cross-compilation:

- strcasecmp macro: MinGW provides native strcasecmp via POSIX compat,
  so the _stricmp redirect is only needed for MSVC. Use _MSC_VER guard.
- #pragma warning(disable : 4800): MSVC-only pragma that GCC doesn't
  recognize, triggering -Werror=unknown-pragmas. Guard with _MSC_VER
  in both dl_codes.h and dl_dxf.h.
@spe-ciellt spe-ciellt added the fix Solution for a potential problem or omission. label Feb 28, 2026
@spe-ciellt spe-ciellt self-assigned this Mar 2, 2026
@spe-ciellt
Copy link
Copy Markdown
Contributor

Thank you for this patch! Do you or I report the DXF lib bugs upstreams?

@spe-ciellt
Copy link
Copy Markdown
Contributor

Minor comments that can be solved by another PR:

  • It would be great if the patches you applied are documented in the thirdparty/dxflib/VERSION file or in a separate thirdparty/dxflib/PATCHES.md file.
  • Redundant guard in tessellation
  int steps = (int)(fabs(angle2 - angle1) / 2.0) + 1;
  if (steps < 1)
      steps = 1;

The + 1 already guarantees steps >= 1, so the if is dead code. Harmless, but worth removing.

Else great idea with external thirdparty directory. I will merge this.

@spe-ciellt spe-ciellt merged commit 4810258 into gerbv:develop Mar 2, 2026
2 checks passed
rampageservices added a commit to SourceParts/gerbv that referenced this pull request Mar 5, 2026
Move vendored TinyScheme 1.35 from src/ into thirdparty/tinyscheme/
for consistency with the dxflib bundling approach introduced in gerbv#296.

Files moved:
  src/{scheme.c,scheme.h,scheme-private.h,opdefines.h} -> thirdparty/tinyscheme/
  src/{dynload.c,dynload.h,init.scm}                   -> thirdparty/tinyscheme/
  COPYING.tinyscheme                                    -> thirdparty/tinyscheme/COPYING

CMake changes:
  - Add tinyscheme_bundled static library target (mirrors dxflib_bundled)
  - Remove tinyscheme sources from gerbv-app, link tinyscheme_bundled instead
  - Install init.scm via install(FILES) since it moved out of src/

Also updates locale/CMakeLists.txt (gettext source path), package.sh
(Windows packaging paths), and README.md (license link).

Closes gerbv#350
spe-ciellt pushed a commit that referenced this pull request Mar 5, 2026
* refactor: move tinyscheme to thirdparty/ directory

Move vendored TinyScheme 1.35 from src/ into thirdparty/tinyscheme/
for consistency with the dxflib bundling approach introduced in #296.

Files moved:
  src/{scheme.c,scheme.h,scheme-private.h,opdefines.h} -> thirdparty/tinyscheme/
  src/{dynload.c,dynload.h,init.scm}                   -> thirdparty/tinyscheme/
  COPYING.tinyscheme                                    -> thirdparty/tinyscheme/COPYING

CMake changes:
  - Add tinyscheme_bundled static library target (mirrors dxflib_bundled)
  - Remove tinyscheme sources from gerbv-app, link tinyscheme_bundled instead
  - Install init.scm via install(FILES) since it moved out of src/

Also updates locale/CMakeLists.txt (gettext source path), package.sh
(Windows packaging paths), and README.md (license link).

Closes #350

* fix: resolve dynload.c build failure after tinyscheme move

dynload.c included two gerbv headers that broke after moving to
thirdparty/:

- gerb_file.h: completely unused, removed the dead include
- common.h: provides the _() gettext macro used in error messages;
  add src/ as a PRIVATE include directory for tinyscheme_bundled so
  common.h (and its transitive gettext.h/locale.h) can be found

* fix: link Intl for tinyscheme_bundled on macOS

dynload.c includes common.h which includes gettext.h which includes
libintl.h. On macOS, libintl.h is provided by the Intl package and
requires its include path. Move the tinyscheme block after
find_package(Intl) and conditionally link Intl::Intl.

* fix: update GERBV_SCHEMEINIT path for test suite

Point GERBV_SCHEMEINIT to thirdparty/tinyscheme where init.scm
now lives after the tinyscheme directory move.
spe-ciellt added a commit that referenced this pull request Mar 7, 2026
When building in the pipline we don't need to include dxflib-dev
in those distributions that have it.

All platforms now include DXF support thanks to @rampageservices in #296.
spe-ciellt added a commit that referenced this pull request Mar 7, 2026
When building in the pipline we don't need to include dxflib-dev
in those distributions that have it available.

All platforms now include DXF support thanks to @rampageservices in #296.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Solution for a potential problem or omission.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DXF Export Turns Arcs into Lines

2 participants