Skip to content

Commit

Permalink
finish edgeminer/-smith tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
mozman committed Jan 5, 2025
1 parent d505eba commit bd074ad
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 7 deletions.
4 changes: 4 additions & 0 deletions docs/source/edgeminer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ High Level Functions
Low Level Functions
-------------------

.. autofunction:: filter_coincident_edges

.. autofunction:: flatten

.. autofunction:: is_chain
Expand Down Expand Up @@ -181,6 +183,8 @@ Classes

.. automethod:: __eq__

.. automethod:: __hash__

.. automethod:: reversed

.. autoclass:: Deposit
Expand Down
69 changes: 63 additions & 6 deletions docs/source/tutorials/edges.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
.. _tut_edges:

Tutorial for Finding Geometries
===============================
Tutorial for Finding Chains and Loops
=====================================

.. versionadded:: 1.4

This tutorial shows how to find connected structures like open or closed polylines
by the :mod:`ezdxf.edgeminer` and the :mod:`ezdxf.edgesmith` modules.

Introduction
------------
Expand Down Expand Up @@ -462,9 +467,61 @@ intersects this line.
I am not convinced that this is the best solution or that this solution works for all
use cases, therefore this is not (yet) a helper function in the :mod:`edgesmith` module.

TODO
----
Gaps and Design Inaccuracies
----------------------------

Most real-world DXF drawings have design inaccuracies, that means, there are gaps between
the endpoints of entities.

All search and test functions have an optional argument :attr:`gap_tol` or the gap
tolerance is stored in the :class:`Deposit` class.
The gap tolerance is the maximum distance between two edge vertices to consider them
as connected. It is important to use the same tolerance throughout a task, from creating
the edges til building new DXF entities from chains and loops.

Specialty Edge Paths
~~~~~~~~~~~~~~~~~~~~

AutoCAD is very picky about edge paths in HATCH entities when it comes to considering
them as closed. Therefore the :func:`edge_path_from_chain` function adds additional line
segments between edges when the gap is larger than ``LEN_TOL``, ``LEN_TOL`` is a constant
value of 1e-9.

Coincident Edges
----------------

Coincident edges in the context of :mod:`edgeminer` are edges where the start- and the end vertex
are coincident, remember: the shape of the edge is not known. This is the reason why such
edges are not removed automatically, e.g. two arcs can create a closed loop as coincident
edges:

.. image:: gfx/edges_07_loop_from_arcs.png

Coincident edges are a major nuisance and should be avoided at all costs. They create
ambiguity and can be the reason why the expected results are not found.

The :func:`~ezdxf.edgeminer.filter_coincident_edges` function removes coincident edges.
It takes a function to test if two edges are coincident and the default function tests
only if the end points are coincident, but you can pass a more sophisticated function.


Set Operations
--------------

The :class:`ezdxf.edgeminer.Edge` class implements the :meth:`__hash__` method and can be
used in sets, this allows set operations like subtracting a found loop from the source
edges:

.. code-block:: Python
edges = list(edgesmith.edges_from_entities_2d(lines))
deposit = edgeminer.Deposit(edges)
# returns the first loop found
first_loop = edgeminer.find_loop(deposit)
edges = list(set(edges) - set(first_loop))
- Coincident edges
- Gaps and drawing imprecision
# or use this helper function:
edges = edgeminer.subtract_edges(edges, first_loop)
The :class:`Deposit` has to be recreated for the new list of edges!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/ezdxf/edgeminer.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@ def __repr__(self) -> str:
return f"Edge({content})"

def __hash__(self) -> int:
# edge and its reversed edge must have the same hash value!
"""The edge :attr:`id` is used as hash value.
An Edge and its reversed edge have the same hash value and cannot both
exist in the same :class:`set`.
"""
return self.id

def reversed(self) -> Self:
Expand Down

0 comments on commit bd074ad

Please sign in to comment.