Ë
    £èh9-  ã                  óì  — d dl mZ d dlmZmZ d dlZd dlZd dlZd dl	m
ZmZmZ d dlmZmZmZmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ  G d„ dej@                  «      Z!ejD                  jF                  d z   Z$ejD                  jF                  dz   Z% G d„ de«      Z& G d„ de&«      Z' G d„ de&«      Z( G d„ dejR                  «      Z* G d„ dejV                  «      Z,	 	 	 	 	 	 dd„Z-dd„Z.dd„Z/y)é    )Úannotations)ÚOptionalÚIterableN)ÚQtCoreÚQtGuiÚ	QtWidgets)ÚBackendÚBkPath2dÚ
BkPoints2dÚ	ImageData)ÚConfiguration)ÚColor)ÚBackendProperties)ÚVec2ÚMatrix44)Úto_qpainter_pathc                  óF   ‡ — e Zd ZdZdˆ fd„Z	 d	 	 	 	 	 	 	 dd„Zdd„Zˆ xZS )	Ú_PointzTA dimensionless point which is drawn 'cosmetically' (scale depends on
    view)
    c                ó   •— t         ‰| �  «        t        j                  ||«      | _        d| _        | j                  t        j                  t        j                  j                  «      «       | j                  |«       y )Ng      ð?)ÚsuperÚ__init__ÚqcÚQPointFÚlocationÚradiusÚsetPenÚqgÚQPenÚQtÚNoPenÚsetBrush)ÚselfÚxÚyÚbrushÚ	__class__s       €ú9lib/python3.12/site-packages/ezdxf/addons/drawing/pyqt.pyr   z_Point.__init__   sP   ø€ Ü‰ÑÔÜŸ
™
 1 aÓ(ˆŒØˆŒØ�‰”B—G‘GœBŸE™EŸK™KÓ(Ô)Ø�‰�eÕó    c                ó  — t        |j                  «       «      }| j                  |z  }|j                  | j	                  «       «       |j                  t        j                  j                  «       |j                  | j                  ||«       y ©N)Ú_get_x_scaleÚ	transformr   r!   r%   r   r   r   r    ÚdrawEllipser   )r"   ÚpainterÚoptionÚwidgetÚ
view_scaler   s         r'   Úpaintz_Point.paint    sc   € ô " '×"3Ñ"3Ó"5Ó6ˆ
Ø—‘˜zÑ)ˆØ×Ñ˜Ÿ™›Ô&Ø�‰”r—u‘u—{‘{Ô#Ø×Ñ˜DŸM™M¨6°6Õ:r(   c                ój   — t        j                  | j                  t        j                  dd«      «      S )Né   )r   ÚQRectFr   ÚQSizeF©r"   s    r'   ÚboundingRectz_Point.boundingRect,   s!   € Ü�y‰y˜Ÿ™¬¯	©	°!°Q«Ó8Ð8r(   )r#   Úfloatr$   r9   r%   ú	qg.QBrushr*   ©r.   úqg.QPainterr/   zqw.QStyleOptionGraphicsItemr0   zOptional[qw.QWidget]ÚreturnÚNone)r=   z	qc.QRectF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r2   r8   Ú__classcell__©r&   s   @r'   r   r      sB   ø„ ñõð (,ð	
;àð
;ð ,ð
;ð %ð	
;ð
 
ó
;÷9r(   r   r4   c                  óò   ‡ — e Zd ZdZdˆ fd„Zdˆ fd„Zdd„Zdd„Zej                  dd„«       Z
dd„Zdd„Zdd	„Zdd
„Zdd„Zdd„Z	 	 	 	 dd„Zdd„Z	 	 	 	 	 	 d d„Z	 	 	 	 	 	 d!d„Zd"d„Zd#d„Zd#ˆ fd„Zˆ xZS )$Ú_PyQtBackendzÒ
    Abstract PyQt backend which uses the :mod:`PySide6` package to implement an
    interactive viewer. The :mod:`PyQt5` package can be used as fallback if the
    :mod:`PySide6` package is not available.
    c                ó  •— t         ‰| �  «        || _        i | _        t	        j
                  t        j                  j                  «      | _	        t	        j                  t        j                  j                  «      | _        y r*   )r   r   Ú_sceneÚ_color_cacher   r   r   r   r    Ú_no_lineÚQBrushÚNoBrushÚ_no_fill©r"   Úscener&   s     €r'   r   z_PyQtBackend.__init__<   sM   ø€ Ü‰ÑÔØˆŒØ46ˆÔÜŸ™¤§¡§¡Ó,ˆŒÜŸ	™	¤"§%¡%§-¡-Ó0ˆ�r(   c                ó`   •— |j                   €|j                  d¬«      }t        ‰| �  |«       y )Ng¸…ëQ¸Î?)Úmin_lineweight)rQ   Úwith_changesr   Ú	configure)r"   Úconfigr&   s     €r'   rS   z_PyQtBackend.configureC   s/   ø€ Ø× Ñ Ð(Ø×(Ñ(¸Ð(Ó=ˆFÜ‰Ñ˜&Õ!r(   c                ó   — || _         y r*   )rH   )r"   rO   s     r'   Ú	set_scenez_PyQtBackend.set_sceneH   s	   € Øˆ�r(   c                ó^   — | j                  ||«       | j                  j                  |«       y r*   )Úset_item_datarH   ÚaddItem©r"   ÚitemÚentity_handles      r'   Ú	_add_itemz_PyQtBackend._add_itemK   s$   € Ø×Ñ˜4 Ô/Ø�‰×Ñ˜DÕ!r(   c                 ó   — y r*   © rZ   s      r'   rX   z_PyQtBackend.set_item_dataO   s   € àr(   c                ó&  — 	 | j                   |   S # t        $ r Y nw xY wt        |«      dk(  rt        j                  |«      }n>t        |«      dk(  r%|dd }|dd }t        j                  d|› |› �«      }nt        |«      ‚|| j                   |<   |S )Né   é	   r4   Ú#)rI   ÚKeyErrorÚlenr   ÚQColorÚ	TypeError)r"   ÚcolorÚqt_colorÚrgbÚalphas        r'   Ú
_get_colorz_PyQtBackend._get_colorS   s�   € ð	Ø×$Ñ$ UÑ+Ð+øÜò 	Ùð	úäˆu‹:˜Š?Ü—y‘y Ó'‰HÜ�‹Z˜1Š_Ø˜˜!�*ˆCØ˜!˜A�JˆEÜ—y‘y 1 U G¨C¨5Ð!1Ó2‰Hä˜EÓ"Ð"à#+ˆ×Ñ˜%Ñ Øˆs   ‚ ‘	œc                ó$  — |j                   dz  | j                  j                  z  }t        j                  | j                  |j                  «      |«      }|j                  d«       |j                  t        j                  j                  «       |S )z^Returns a cosmetic pen with applied lineweight but without line type
        support.
        g&S£’Ö?T)Ú
lineweightrT   Úlineweight_scalingr   r   rl   rh   ÚsetCosmeticÚsetJoinStyler   r   Ú	RoundJoin)r"   Ú
propertiesÚpxÚpens       r'   Ú_get_penz_PyQtBackend._get_pend   si   € ð ×"Ñ" VÑ+¨d¯k©k×.LÑ.LÑLˆÜ�g‰g�d—o‘o j×&6Ñ&6Ó7¸Ó<ˆà�‰˜ÔØ×ÑœŸ™Ÿ™Ô)Øˆ
r(   c                ó|   — t        j                  | j                  |«      t        j                  j
                  «      S r*   )r   rK   rl   r   r   ÚSolidPattern©r"   rh   s     r'   Ú_get_fill_brushz_PyQtBackend._get_fill_brusho   s&   € Ü�y‰y˜Ÿ™¨Ó/´·±×1CÑ1CÓDÐDr(   c                ó~   — | j                   j                  t        j                  | j	                  |«      «      «       y r*   )rH   ÚsetBackgroundBrushr   rK   rl   ry   s     r'   Úset_backgroundz_PyQtBackend.set_backgroundr   s&   € Ø�‰×&Ñ&¤r§y¡y°·±ÀÓ1GÓ'HÕIr(   c                ó´   — | j                  |j                  «      }t        |j                  |j                  |«      }| j                  ||j                  «       y)z Draw a real dimensionless point.N)rz   rh   r   r#   r$   r]   Úhandle)r"   Úposrs   r%   r[   s        r'   Ú
draw_pointz_PyQtBackend.draw_pointu   sB   € à×$Ñ$ Z×%5Ñ%5Ó6ˆÜ�c—e‘e˜SŸU™U EÓ*ˆØ�‰�t˜Z×.Ñ.Õ/r(   c                óD  — |j                  |«      r| j                  ||«       y t        j                  |j                  |j
                  |j                  |j
                  «      }|j                  | j                  |«      «       | j                  ||j                  «       y r*   )
Úiscloser�   ÚqwÚQGraphicsLineItemr#   r$   r   rv   r]   r   )r"   ÚstartÚendrs   r[   s        r'   Ú	draw_linez_PyQtBackend.draw_line{   sk   € à�=‰=˜ÔØ�O‰O˜E :Õ.ä×'Ñ'¨¯©°·±¸#¿%¹%ÀÇÁÓGˆDØ�K‰K˜Ÿ™ jÓ1Ô2Ø�N‰N˜4 ×!2Ñ!2Õ3r(   c                ób  — | j                  |«      }| j                  }|D ]�  \  }}|j                  |«      r| j                  ||«       Œ*t	        j
                  |j                  |j                  |j                  |j                  «      }|j                  |«        |||j                  «       Œ� y)zDFast method to draw a bunch of solid lines with the same properties.N)
rv   r]   rƒ   r�   r„   r…   r#   r$   r   r   )r"   Úlinesrs   ru   Úadd_lineÚsÚer[   s           r'   Údraw_solid_linesz_PyQtBackend.draw_solid_lines„   s„   € ð �m‰m˜JÓ'ˆØ—>‘>ˆÛ‰DˆAˆqØ�y‰y˜Œ|Ø—‘  :Õ.ä×+Ñ+¨A¯C©C°·±°a·c±c¸1¿3¹3Ó?�Ø—‘˜CÔ Ù˜˜z×0Ñ0Õ1ñ r(   c                ó  — t        |«      dk(  ry t        j                  t        |g«      «      }|j	                  | j                  |«      «       |j                  | j                  «       | j                  ||j                  «       y ©Nr   )
re   r„   ÚQGraphicsPathItemr   r   rv   r!   rM   r]   r   )r"   Úpathrs   r[   s       r'   Ú	draw_pathz_PyQtBackend.draw_path”   sa   € Üˆt‹9˜Š>ØÜ×#Ñ#Ô$4°d°VÓ$<Ó=ˆØ�‰�D—M‘M *Ó-Ô.Ø�‰�d—m‘mÔ$Ø�‰�t˜Z×.Ñ.Õ/r(   c                ó,  — t        |«      }t        |«      dk(  ry t        t        |«      «      }|j	                  | j                  |«      «       |j                  | j                  |j                  «      «       | j                  ||j                  «       y r�   )Úlistre   Ú_CosmeticPathr   r   rv   r!   rz   rh   r]   r   )r"   Úpathsrs   Ú_pathsr[   s        r'   Údraw_filled_pathsz_PyQtBackend.draw_filled_pathsœ   sr   € ô
 �e“ˆÜˆv‹;˜!ÒØÜÔ-¨fÓ5Ó6ˆØ�‰�D—M‘M *Ó-Ô.Ø�‰�d×*Ñ*¨:×+;Ñ+;Ó<Ô=Ø�‰�t˜Z×.Ñ.Õ/r(   c                ó¤  — | j                  |j                  «      }t        j                  «       }|j	                  «       D ];  }|j                  t        j                  |j                  |j                  «      «       Œ= t        |«      }|j                  | j                  «       |j                  |«       | j                  ||j                  «       y r*   )rz   rh   r   Ú	QPolygonFÚverticesÚappendr   r   r#   r$   Ú_CosmeticPolygonr   rJ   r!   r]   r   )r"   Úpointsrs   r%   ÚpolygonÚpr[   s          r'   Údraw_filled_polygonz _PyQtBackend.draw_filled_polygon©   s�   € ð ×$Ñ$ Z×%5Ñ%5Ó6ˆÜ—,‘,“.ˆØ—‘Ö"ˆAØ�N‰Nœ2Ÿ:™: a§c¡c¨1¯3©3Ó/Õ0ð #ä Ó(ˆØ�‰�D—M‘MÔ"Ø�‰�eÔØ�‰�t˜Z×.Ñ.Õ/r(   c           	     óŒ  — |j                   }|j                  }|j                  \  }}}|dk(  sJ ‚||z  }t        j                  t        j
                  |d¬«      «      }t        j                  t        j                  |j                  |||t        j                  j                  j                  «      «      }	t        j                  «       }
|
j                  |	«       |
j                  t         j"                  j$                  j&                  «       |
j)                  t+        |«      «       | j-                  |
|j.                  «       y )Né   r   )Úaxis)Úimager,   ÚshapeÚnpÚascontiguousarrayÚflipr   ÚQPixmapÚQImageÚdataÚFormatÚFormat_RGBA8888r„   ÚQGraphicsPixmapItemÚ	setPixmapÚsetTransformationModer   r   ÚTransformationModeÚSmoothTransformationÚsetTransformÚ_matrix_to_qtransformr]   r   )r"   Ú
image_datars   r¦   r,   ÚheightÚwidthÚdepthÚbytes_per_rowÚpixmapr[   s              r'   Ú
draw_imagez_PyQtBackend.draw_imageµ   s÷   € Ø× Ñ ˆØ×(Ñ(ˆ	Ø$Ÿ{™{Ñˆ��uØ˜ŠzÐˆzØ ™ˆÜ×$Ñ$¤R§W¡W¨U¸Ô%;Ó<ˆÜ—‘Ü�I‰IØ—
‘
ØØØÜ—	‘	× Ñ ×0Ñ0óó
ˆô ×%Ñ%Ó'ˆØ�‰�vÔØ×"Ñ"¤2§5¡5×#;Ñ#;×#PÑ#PÔQØ×ÑÔ/°	Ó:Ô;Ø�‰�t˜Z×.Ñ.Õ/r(   c                ó8   — | j                   j                  «        y r*   )rH   Úclearr7   s    r'   r¿   z_PyQtBackend.clearË   s   € Ø�‰×ÑÕr(   c                óˆ   •— t         ‰| �  «        | j                  j                  | j                  j	                  «       «       y r*   )r   ÚfinalizerH   ÚsetSceneRectÚitemsBoundingRect)r"   r&   s    €r'   rÁ   z_PyQtBackend.finalizeÎ   s-   ø€ Ü‰ÑÔØ�‰× Ñ  §¡×!>Ñ!>Ó!@ÕAr(   )rO   úqw.QGraphicsScene)rT   r   r=   r>   )rO   rÄ   r=   r>   ©r[   zqw.QGraphicsItemr\   Ústrr=   r>   )rh   r   r=   z	qg.QColor)rs   r   r=   zqg.QPen)rh   r   r=   r:   )rh   r   )r€   r   rs   r   r=   r>   )r†   r   r‡   r   rs   r   r=   r>   )rŠ   zIterable[tuple[Vec2, Vec2]]rs   r   )r’   r
   rs   r   r=   r>   )r—   zIterable[BkPath2d]rs   r   r=   r>   )rŸ   r   rs   r   r=   r>   )r·   r   rs   r   r=   r>   )r=   r>   )r?   r@   rA   rB   r   rS   rV   r]   ÚabcÚabstractmethodrX   rl   rv   rz   r}   r�   rˆ   rŽ   r“   r™   r¢   r½   r¿   rÁ   rC   rD   s   @r'   rF   rF   5   sÂ   ø„ ñõ1õ"ó
ó"ð 	×Ñòó ðóó"	óEóJó0ó4ð2à*ð2ð &ó2ó 0ð0Ø'ð0Ø5Fð0à	ó0ð
0Ø ð
0Ø.?ð
0à	ó
0ó0ó,÷Bñ Br(   rF   c                  ó2   ‡ — e Zd ZdZ	 d	 dˆ fd„Zdd„Zˆ xZS )ÚPyQtBackendaM  
    Backend which uses the :mod:`PySide6` package to implement an interactive
    viewer. The :mod:`PyQt5` package can be used as fallback if the :mod:`PySide6`
    package is not available.

    Args:
        scene: drawing canvas of type :class:`QtWidgets.QGraphicsScene`,
            if ``None`` a new canvas will be created
    c                óP   •— t         ‰| �  |xs t        j                  «       «       y r*   ©r   r   r„   ÚQGraphicsScenerN   s     €r'   r   zPyQtBackend.__init__Þ   ó    ø€ ô 	‰Ñ˜Ò5¤"×"3Ñ"3Ó"5Õ6r(   c                ó²   — t        d„ | j                  d d D «       «      }| j                  }|j                  t        |«       |j                  t
        |«       y )Nc              3  ó&   K  — | ]	  \  }}|–— Œ y ­wr*   r_   )Ú.0r�   Úpropss      r'   Ú	<genexpr>z,PyQtBackend.set_item_data.<locals>.<genexpr>è   s   è ø€ ÐFÑ/E¡8 1 eœQÑ/Eùs   ‚éÿÿÿÿ)ÚtupleÚentity_stackÚcurrent_entityÚsetDataÚCorrespondingDXFEntityÚCorrespondingDXFParentStack)r"   r[   r\   Úparent_stackr×   s        r'   rX   zPyQtBackend.set_item_dataç   sH   € ÜÑF¨t×/@Ñ/@ÀÀ"Ñ/EÓFÓFˆØ×,Ñ,ˆØ�‰Ô+¨^Ô<Ø�‰Ô0°,Õ?r(   r*   ©rO   zOptional[qw.QGraphicsScene]rÅ   ©r?   r@   rA   rB   r   rX   rC   rD   s   @r'   rÊ   rÊ   Ó   s    ø„ ñð .2ð7à*õ7÷@r(   rÊ   c                  ó2   ‡ — e Zd ZdZ	 d	 dˆ fd„Zdd„Zˆ xZS )ÚPyQtPlaybackBackenda½  
    Backend which uses the :mod:`PySide6` package to implement an interactive
    viewer. The :mod:`PyQt5` package can be used as fallback if the :mod:`PySide6`
    package is not available.

    This backend can be used a playback backend for the :meth:`replay` method of the
    :class:`Player` class

    Args:
        scene: drawing canvas of type :class:`QtWidgets.QGraphicsScene`,
            if ``None`` a new canvas will be created
    c                óP   •— t         ‰| �  |xs t        j                  «       «       y r*   rÌ   rN   s     €r'   r   zPyQtPlaybackBackend.__init__ü   rÎ   r(   c                ó0   — |j                  t        |«       y r*   )rØ   rÙ   rZ   s      r'   rX   z!PyQtPlaybackBackend.set_item_data  s   € Ø�‰Ô+¨]Õ;r(   r*   rÜ   rÅ   rÝ   rD   s   @r'   rß   rß   î   s   ø„ ñð .2ð7à*õ7÷<r(   rß   c                  ó2   ‡ — e Zd Z	 d	 	 	 	 	 	 	 dˆ fd„Zˆ xZS )r–   c                ó@   •— t        | |«       t        ‰| �	  |||«       y r*   ©Ú_set_cosmetic_brushr   r2   ©r"   r.   r/   r0   r&   s       €r'   r2   z_CosmeticPath.paint  ó   ø€ ô 	˜D 'Ô*Ü‰‰�g˜v vÕ.r(   r*   r;   ©r?   r@   rA   r2   rC   rD   s   @r'   r–   r–     ó8   ø„ ð
 (,ð	/àð/ð ,ð/ð %ð	/ð
 
÷/ñ /r(   r–   c                  ó2   ‡ — e Zd Z	 d	 	 	 	 	 	 	 dˆ fd„Zˆ xZS )rž   c                ó@   •— t        | |«       t        ‰| �	  |||«       y r*   rä   ræ   s       €r'   r2   z_CosmeticPolygon.paint  rç   r(   r*   r;   rè   rD   s   @r'   rž   rž     ré   r(   rž   c                óÆ   — | j                  «       }|j                  |j                  «       j                  «       d   j	                  dd«      «       | j                  |«       y)z[like a cosmetic pen, this sets the brush pattern to appear the same independent of the viewr   r4   rÔ   N)r%   rµ   r,   ÚinvertedÚscaler!   )r[   r.   r%   s      r'   rå   rå   !  sO   € ð �J‰J‹L€Eð 
×Ñ�w×(Ñ(Ó*×3Ñ3Ó5°aÑ8×>Ñ>¸qÀ"ÓEÔFØ‡M�M�%Õr(   c                ó®   — t        j                  | j                  «       | j                  «       z  | j                  «       | j                  «       z  z   «      S r*   )ÚmathÚsqrtÚm11Úm21)Úts    r'   r+   r+   ,  s8   € Ü�9‰9�Q—U‘U“W˜qŸu™u›wÑ&¨¯©«°1·5±5³7Ñ):Ñ:Ó;Ð;r(   c                óB   — t        j                  | j                  «       Ž S )at  Qt also uses row-vectors so the translation elements are placed in the
    bottom row.

    This is only a simple conversion which assumes that although the
    transformation is 4x4,it does not involve the z axis.

    A more correct transformation could be implemented like so:
    https://stackoverflow.com/questions/10629737/convert-3d-4x4-rotation-matrix-into-2d
    )r   Ú
QTransformÚget_2d_transformation)Úmatrixs    r'   r¶   r¶   0  s   € ô �=‰=˜&×6Ñ6Ó8Ð9Ð9r(   )r[   zqw.QAbstractGraphicsShapeItemr.   r<   r=   r>   )rô   úqg.QTransformr=   r9   )rø   r   r=   rù   )0Ú
__future__r   Útypingr   r   rÇ   rð   Únumpyr¨   Úezdxf.addons.xqtr   r   r   r   r   r„   Úezdxf.addons.drawing.backendr	   r
   r   r   Úezdxf.addons.drawing.configr   Úezdxf.addons.drawing.type_hintsr   Úezdxf.addons.drawing.propertiesr   Ú
ezdxf.mathr   r   Úezdxf.npshapesr   ÚQAbstractGraphicsShapeItemr   r   ÚUserRolerÙ   rÚ   rF   rÊ   rß   r‘   r–   ÚQGraphicsPolygonItemrž   rå   r+   r¶   r_   r(   r'   Ú<module>r     sá   ðõ #ß %Û 
Û ã ç GÑ Gß QÓ QÝ 5Ý 1Ý =ß %Ý +ô9ˆR×*Ñ*ô 9ð: Ÿ™Ÿ™¨!Ñ+Ð Ø Ÿe™eŸn™n¨qÑ0Ð ô[B�7ô [Bô|@�,ô @ô6<˜,ô <ô:/�B×(Ñ(ô /ô/�r×.Ñ.ô /ðØ
'ðØ2=ðà	óó<ô
:r(   