<commit_before>.. _dxf units:

.. module:: ezdxf.units

DXF Units
=========

The `DXF reference`_ has no explicit information how to handle units in DXF, any
information in this section is based on experiments with BricsCAD and may differ
in other CAD application, BricsCAD tries to be as compatible with AutoCAD as
possible. Therefore, this information should also apply to AutoCAD.

Please open an issue on `github`_ if you have any corrections or additional
information about this topic.

Length Units
------------

Any length or coordinate value in DXF is unitless in the first place, there is
no unit information attached to the value. The unit information comes from the
context where a DXF entity is used. The document/modelspace get the unit
information from the header variable $INSUNITS, paperspace and block layouts get
their unit information form the attribute :attr:`~ezdxf.layouts.BaseLayout.units`.
The modelspace object has also a :attr:`units` property, but this value do not
represent the modelspace units, this value is always set to 0 "unitless".

Get and set  document/modelspace units as enum by the
:class:`~ezdxf.document.Drawing` property :attr:`units`:

.. code-block:: python

    import ezdxf
    from ezdxf import units

    doc = ezdxf.new()
    # Set centimeter as document/modelspace units
    doc.units = units.CM
    # which is a shortcut (including validation) for
    doc.header['$INSUNITS'] = units.CM

Block Units
-----------

As said each block definition can have independent units, but there is no
implicit unit conversion applied, not in CAD applications and not in ezdxf.

When inserting a block reference (INSERT) into the modelspace or another block
layout with different units, the scaling factor between these units **must** be
applied explicit as scaling DXF attributes (:attr:`xscale`, ...) of the
:class:`~ezdxf.entities.Insert` entity, e.g. modelspace in meters and block in
centimeters, x-, y- and z-scaling has to be 0.01:

.. code-block:: python

    doc.units = units.M
    my_block = doc.blocks.new('MYBLOCK')
    my_block.units = units.CM
    block_ref = msp.add_block_ref('MYBLOCK')
    # Set uniform scaling for x-, y- and z-axis
    block_ref.set_scale(0.01)

Use helper function :func:`conversion_factor` to calculate the
scaling factor between units:

.. code-block:: python

    factor = units.conversion_factor(doc.units, my_block.units)
    # factor = 100 for 1m is 100cm
    # scaling factor = 1 / factor
    block_ref.set_scale(1.0/factor)


Angle Units
-----------

Angles are always in degrees (360 deg = full circle) and in counter clockwise
orientation, unless stated explicit otherwise.
<commit_msg>add docs<commit_after>.. _dxf units:

.. module:: ezdxf.units

DXF Units
=========

The `DXF reference`_ has no explicit information how to handle units in DXF, any
information in this section is based on experiments with BricsCAD and may differ
in other CAD application, BricsCAD tries to be as compatible with AutoCAD as
possible. Therefore, this information should also apply to AutoCAD.

Please open an issue on `github`_ if you have any corrections or additional
information about this topic.

Length Units
------------

Any length or coordinate value in DXF is unitless in the first place, there is
no unit information attached to the value. The unit information comes from the
context where a DXF entity is used. The document/modelspace get the unit
information from the header variable $INSUNITS, paperspace and block layouts get
their unit information form the attribute :attr:`~ezdxf.layouts.BaseLayout.units`.
The modelspace object has also a :attr:`units` property, but this value do not
represent the modelspace units, this value is always set to 0 "unitless".

Get and set  document/modelspace units as enum by the
:class:`~ezdxf.document.Drawing` property :attr:`units`:

.. code-block:: python

    import ezdxf
    from ezdxf import units

    doc = ezdxf.new()
    # Set centimeter as document/modelspace units
    doc.units = units.CM
    # which is a shortcut (including validation) for
    doc.header['$INSUNITS'] = units.CM

Block Units
-----------

As said each block definition can have independent units, but there is no
implicit unit conversion applied, not in CAD applications and not in ezdxf.

When inserting a block reference (INSERT) into the modelspace or another block
layout with different units, the scaling factor between these units **must** be
applied explicit as scaling DXF attributes (:attr:`xscale`, ...) of the
:class:`~ezdxf.entities.Insert` entity, e.g. modelspace in meters and block in
centimeters, x-, y- and z-scaling has to be 0.01:

.. code-block:: python

    doc.units = units.M
    my_block = doc.blocks.new('MYBLOCK')
    my_block.units = units.CM
    block_ref = msp.add_block_ref('MYBLOCK')
    # Set uniform scaling for x-, y- and z-axis
    block_ref.set_scale(0.01)

Use helper function :func:`conversion_factor` to calculate the
scaling factor between units:

.. code-block:: python

    factor = units.conversion_factor(doc.units, my_block.units)
    # factor = 100 for 1m is 100cm
    # scaling factor = 1 / factor
    block_ref.set_scale(1.0/factor)

.. hint::

    It is never a good idea to use different measurement system in one
    document, ask the NASA about their Mars Climate Orbiter from 1999.
    The same applies for units of the same measurement system, just use one unit
    like meters or inches.


Angle Units
-----------

Angles are always in degrees (360 deg = full circle) and in counter clockwise
orientation, unless stated explicit otherwise.

{'fraction_non_alphanumeric': 0.08287194141811037, 'fraction_numerical': 0.007858546168958742, 'mean_word_length': 3.7457627118644066, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1439705', 'n_tokens_mistral': 1616, 'n_tokens_neox': 1518, 'n_words': 724}