Python library for automated DXF file marking and manipulation
Project description
SnapMark
SnapMark is a Python library for applying customizable and intelligent text markings to DXF (AutoCAD) files.
Built on top of ezdxf, it provides a simple but powerful API for batch processing, automatic alignment, and sequence-based text generation.
It gives you full control over:
- Marking position — choose exact coordinates or automatic placement based on geometry
- Mark size and scaling — adjust text size dynamically or with fixed scale factors
- Smart collision avoidance — automatically avoids internal contours, holes, and cutouts
- Flexible automation — process entire folders, subfolders, or single DXF files with custom pipelines
Whether you’re marking parts for manufacturing, numbering drawings for CNC cutting, or adding production info automatically, SnapMark helps you make your workflow faster and more consistent.
Installation
pip install snapmark
Quick Start
import snapmark as sm
# Mark all DXF files with their filename
sm.mark_by_name("path/to/drawings")
# Custom sequence: filename + folder name
seq = (sm.SequenceBuilder()
.file_name()
.folder(num_chars=2) # firts 2 chars of folder name
.build())
sm.mark_with_sequence("path/to/drawings", seq, scale_factor=100)
Features
- ✅ Simple API - Mark files in one line
- ✅ Custom sequences - Build complex marking logic with SequenceBuilder
- ✅ Batch operations - Process entire folders with IterationManager
- ✅ Built-in backup - Automatic .bak files before modifications
- ✅ Hole counting - Count and analyze circles in drawings
- ✅ Extensible - Easy to add custom operations
Use Cases
- Manufacturing: Add part numbers and quantities to production drawings
- CAM workflows: Automatically mark drawings before CNC processing
- Quality control: Count holes and verify drawing specifications
- Batch processing: Apply consistent markings across large drawing sets
Examples
Basic Marking
import snapmark as sm
# Mark with filename (simplest)
sm.mark_by_name("drawings/")
# Mark with first part of filename (e.g., "PART" from "PART_123_Q5.dxf")
sm.mark_by_splitted_text("drawings/", separator='_', part_index=0)
Custom Sequences
import snapmark as sm
# Extract part number from filename like "S532_P5_SP4_Q2.dxf"
def extract_part_number(folder, filename):
import re
match = re.search(r'P(\d+)', filename)
return f"P{match.group(1)}" if match else ""
seq = (sm.SequenceBuilder()
.file_part(separator='_', part_index=0) # "S532"
.custom(extract_part_number) # "P5"
.build())
sm.mark_with_sequence("drawings/", seq)
# Result: "S532-P5"
Count Holes
import snapmark as sm
# Simple count
stats = sm.quick_count_holes("drawings/", min_diam=5, max_diam=10)
print(f"Total holes: {stats['total_count']}")
# With multiplier (extract quantity from filename, e.g. S532_P1_S235JR_SP4_Q2 where Q determines the number of identical pieces to cut)
def get_quantity(filename):
import re
match = re.search(r'Q(\d+)', filename)
return int(match.group(1)) if match else 1
stats = sm.quick_count_holes(
"drawings/",
min_diam=5,
max_diam=10,
multiplier=get_quantity
)
print(f"Total holes (with qty): {stats['total_count']}")
Advanced Pipeline
import snapmark as sm
# Multiple operations in sequence
seq = sm.SequenceBuilder().file_name().build()
manager = sm.IterationManager("drawings/", use_backup_system=True)
manager.add_operation(
sm.Aligner(), # Align drawing
sm.AddMark(seq, scale_factor=100), # Add marking
sm.CountHoles(sm.find_circle_by_radius(5, 10)) # Count holes
)
manager.execute()
Recursive Marking (Batch Mode)
import snapmark as sm
# Build a sequence: filename + first 2 chars of folder name
seq = (sm.SequenceBuilder()
.file_name()
.folder(num_chars=2)
.build())
# Apply marking recursively on all DXF files in subfolders
manager = sm.IterationManager("dxfs", use_backup_system=True)
manager.add_operation(sm.AddMark(seq, scale_factor=100))
manager.execute(recursive=True)
Quick pipeline on a single file
import snapmark as sm
seq = sm.SequenceBuilder().file_name().build()
sm.single_file_pipeline(
"drawing.dxf",
sm.Aligner(),
sm.AddMark(seq, scale_factor=100),
sm.AddX(sm.find_circle_by_radius(5, 10), x_size=8), # Replaces 5–10mm holes with X marks for manual drilling
use_backup=True
)
Restore Backups
import snapmark as sm
# Undo all changes
sm.restore_backup("drawings/")
# Restore recursively in subfolders
sm.restore_backup("drawings/", recursive=True)
# Restore but keep .bak files
sm.restore_backup("drawings/", delete_backups=False)
API Overview
Shortcuts (Simple Usage)
mark_by_name(folder)- Mark with filenamemark_by_splitted_text(folder, separator, part_index)- Mark with filename partmark_with_sequence(folder, sequence)- Mark with custom sequencequick_count_holes(folder, min_diam, max_diam)- Count holesrestore_backup(folder)- Restore from backupsprocess_single_file(file, *operations)- Pipeline on single file
SequenceBuilder (Custom Sequences)
seq = (sm.SequenceBuilder()
.file_name() # Full filename
.file_part(separator, index) # Split filename
.folder(num_chars) # Folder name
.literal("text") # Fixed text
.custom(function) # Custom function
.set_separator("-") # Join character
.build())
Operations (Advanced)
AddMark(sequence)- Add text markingAligner()- Aligns the drawing along its longest side in the X direction.CountHoles(find_func)- Count circlesAddX(find_func, x_size)- Add X marksRemoveCircle(find_func)- Remove circlesSubstituteCircle(find_func, new_radius)- Replace circles
IterationManager (Batch Processing)
manager = sm.IterationManager(folder, use_backup_system=True)
manager.add_operation(operation1, operation2, ...)
manager.execute(recursive=False)
Requirements
- Python 3.8+
- ezdxf >= 1.0.0
Documentation
For detailed documentation and more examples, visit the GitHub repository.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details.
Author
Federico Sidraschi
LinkedIn | GitHub
Acknowledgments
Built with ezdxf - the excellent DXF library for Python.
Keywords: DXF, CAD, AutoCAD, marking, automation, batch processing, manufacturing, CNC, CAM
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file snapmark-2.0.3.tar.gz.
File metadata
- Download URL: snapmark-2.0.3.tar.gz
- Upload date:
- Size: 33.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c34bc0464c95f39fd87ca493e3daa86d895bf1463987d46be2f71a9ed717e671
|
|
| MD5 |
537c25df6431fc794aacedcff48b75fe
|
|
| BLAKE2b-256 |
828ee0bede277fda1029812735da0d988907189945a06392f7bf32c66a285408
|
File details
Details for the file snapmark-2.0.3-py3-none-any.whl.
File metadata
- Download URL: snapmark-2.0.3-py3-none-any.whl
- Upload date:
- Size: 36.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
679196039f6987e166b6bf130649b9fbccaecdc7a79661c38c5140e6449cb257
|
|
| MD5 |
b72625550c91a982e0203164fb24416e
|
|
| BLAKE2b-256 |
66e7b52062c286d9489fd9445e777ffccd807e48fabd00e8b389f876e4fefd06
|