
    OgJ<                        d dl mZ d dlmZ d dlmZmZmZ d dlm	Z	m
Z
mZ dgZd ZdZdZdZd	Z G d
 d      Z G d d      Z G d d      Z G d d      Zy)    )annotations)Optional)Vec3best_fit_normalnormal_vector_3p)MeshVertexMergerMeshBuilderMeshTransformerCSG         gh㈵>c                  f    e Zd ZdZdZd
dZedd       ZddZddZ	ddZ
	 	 	 	 	 	 	 	 	 	 	 	 ddZy	)PlanezRepresents a plane in 3D space.normalwc                     || _         || _        y Nr   )selfr   r   s      W/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/addons/pycsg.py__init__zPlane.__init__6   s        c                R    t        |||      }t        ||j                  |            S r   )r   r   dot)clsabcns        r   from_pointszPlane.from_points;   s%    Q1%Qa!!r   c                B    t        | j                  | j                        S r   )r   r   r   r   s    r   clonezPlane.clone@   s    T[[$&&))r   c                L    | j                    | _         | j                   | _        y r   r   r#   s    r   flipz
Plane.flipC   s    {{l&&r   c                <    d| j                    d| j                   dS )NzPlane(, )r   r#   s    r   __repr__zPlane.__repr__G   s    }Btvvha00r   c                   d}g }|j                   }|j                  }	|D ]g  }
| j                  j                  |
      | j                  z
  }|t
         k  rt        }n|t
        kD  rt        }nt        }||z  }|j                  |       i |t        k(  rV| j                  j                  |j                  j                        dkD  r|j                  |       y|j                  |       y|t        k(  r|j                  |       y|t        k(  r|j                  |       y|t        k(  rMg }g }t        |      }t        |      D ]  }|dz   |z  }||   }||   }||   }
||   }|t        k7  r|j                  |
       |t        k7  r|j                  |
       ||z  t        k(  s`| j                  | j                  j                  |
      z
  | j                  j                  ||
z
        z  }|
j                  ||      }|j                  |       |j                  |        t        |      dk\  r|j                  t        ||	             t        |      dk\  r|j                  t        ||	             yyy)ah  
        Split `polygon` by this plane if needed, then put the polygon or polygon
        fragments in the appropriate lists. Coplanar polygons go into either
        `coplanarFront` or `coplanarBack` depending on their orientation with
        respect to this plane. Polygons in front or in back of this plane go into
        either `front` or `back`
        r   r   r   meshidN)verticesr-   r   r   r   PLANE_EPSILONBACKFRONTCOPLANARappendplaneSPANNINGlenrangelerpPolygon)r   polygoncoplanar_frontcoplanar_backfrontbackpolygon_typevertex_typesr.   r-   vertexdistancevertex_typefront_verticesback_verticeslen_verticesindex
next_indexnext_vertex_typenext_vertexinterpolation_weightplane_intersection_points                         r   split_polygonzPlane.split_polygonJ   sN    ##  		-F{{v.7H=.("M)#&K'L,		- 8#{{w}}334q8%%g.$$W-U"LL!T!KK X%NMx=L|, C#ai<7
*51#/
#; !%&z2$&"))&1%'!((0"22x?!88f(<=,>( 06{{#%90, #))*BC!(()AB%C& >"a'W^FCD=!Q&GM&AB '3 &r   N)r   r   r   float)r   r   r   r   r   r   returnr   )rO   r   rO   NonerO   str)r:   z	'Polygon'r;   list[Polygon]r<   rT   r=   rT   r>   rT   rO   rQ   )__name__
__module____qualname____doc__	__slots__r   classmethodr!   r$   r&   r*   rM    r   r   r   r   1   s    )I
 " "*1ECEC &EC %	EC
 EC EC 
ECr   r   c                  6    e Zd ZdZdZdd	dZd
dZddZddZy)r9   a"  
    Represents a convex polygon. The vertices used to initialize a polygon must
    be coplanar and form a convex loop, the `meshid` argument associates a polygon
    to a mesh.

    Args:
        vertices: polygon vertices as :class:`Vec3` objects
        meshid: id associated mesh

    )r.   r4   r-   c                    || _         	 t        |d   |d   |d         }t	        ||j                  |d               | _        || _        y # t        $ r t        |      }Y Aw xY w)Nr   r   r   )r.   r   ZeroDivisionErrorr   r   r   r4   r-   )r   r.   r-   r   s       r   r   zPolygon.__init__   sg     	/%hqk8A;LF 66::hqk#:;
	 ! 	/$X.F	/s   A
 
A! A!c                V    t        t        | j                        | j                        S )Nr,   )r9   listr.   r-   r#   s    r   r$   zPolygon.clone   s    tDMM*4;;??r   c                l    | j                   j                          | j                  j                          y r   )r.   reverser4   r&   r#   s    r   r&   zPolygon.flip   s     

r   c                l    dj                  d | j                  D              }d| d| j                   dS )Nr(   c              3  2   K   | ]  }t        |        y wr   )repr).0vs     r   	<genexpr>z#Polygon.__repr__.<locals>.<genexpr>   s     5!d1g5s   z	Polygon([z], mesh=r)   )joinr.   r-   )r   rg   s     r   r*   zPolygon.__repr__   s3    II5t}}551#Xdkk]!44r   Nr   )r.   z
list[Vec3]r-   int)rO   r9   rP   rR   )	rU   rV   rW   rX   rY   r   r$   r&   r*   r[   r   r   r9   r9      s#    	 0I@5r   r9   c                  N    e Zd ZdZdZdddZddZddZddZddZ	dd	Z
dd
Zy)BSPNodea{  
    Holds a node in a BSP tree. A BSP tree is built from a collection of polygons
    by picking a polygon to split along. That polygon (and all other coplanar
    polygons) are added directly to that node and the other polygons are added to
    the front and/or back subtrees. This is not a leafy BSP tree since there is
    no distinction between internal and leaf nodes.
    )r4   r=   r>   polygonsNc                d    d | _         d | _        d | _        g | _        |r| j	                  |       y y r   )r4   r=   r>   rn   buildr   rn   s     r   r   zBSPNode.__init__   s2    &*
(,
'+	')JJx  r   c                   t               }| j                  r| j                  j                         |_        | j                  r| j                  j                         |_        | j                  r| j                  j                         |_        | j
                  D cg c]  }|j                          c}|_        |S c c}w r   )rm   r4   r$   r=   r>   rn   )r   nodeps      r   r$   zBSPNode.clone   s~    y::))+DJ::))+DJ99		)DI,0MM:q: ;s   B;c                t   | j                   D ]  }|j                           | j                  J | j                  j                          | j                  r| j                  j	                          | j
                  r| j
                  j	                          | j
                  | j                  c| _        | _        y)zBConvert solid space to empty space and empty space to solid space.N)rn   r&   r4   r=   invertr>   )r   polys     r   rv   zBSPNode.invert   s    MM 	DIIK	zz%%%

::JJ99II $		4::
DIr   c                @   | j                   |dd S g }g }|D ]!  }| j                   j                  |||||       # | j                  r| j                  j                  |      }| j                  r| j                  j                  |      }ng }|j                  |       |S )z^Recursively remove all polygons in `polygons` that are inside this
        BSP tree.

        N)r4   rM   r=   clip_polygonsr>   extend)r   rn   r=   r>   r:   s        r   ry   zBSPNode.clip_polygons   s    
 ::A;!  	HGJJ$$WeT5$G	H ::JJ,,U3E9999**40DDTr   c                    |j                  | j                        | _        | j                  r| j                  j                  |       | j                  r| j                  j                  |       yy)z_Remove all polygons in this BSP tree that are inside the other BSP
        tree `bsp`.
        N)ry   rn   r=   clip_tor>   )r   bsps     r   r|   zBSPNode.clip_to   sQ     ))$--8::JJs#99IIc" r   c                    | j                   dd }| j                  r)|j                  | j                  j                                | j                  r)|j                  | j                  j                                |S )z/Return a list of all polygons in this BSP tree.N)rn   r=   rz   all_polygonsr>   rq   s     r   r   zBSPNode.all_polygons  sU    ==#::OODJJ335699OODII2245r   c                N   t        |      dk(  ry| j                  "|d   j                  j                         | _        | j                  j	                  |d          g }g }|dd D ]5  }| j                  j                  || j                  | j                  ||       7 t        |      dkD  r6| j                  t               | _        | j                  j                  |       t        |      dkD  r7| j                  t               | _	        | j                  j                  |       yy)a0  
        Build a BSP tree out of `polygons`. When called on an existing tree, the
        new polygons are filtered down to the bottom of the tree and become new
        nodes there. Each set of polygons is partitioned using the first polygon
        (no heuristic is used to pick a good split).
        r   Nr   )
r6   r4   r$   rn   r3   rM   r=   rm   rp   r>   )r   rn   r=   r>   rw   s        r   rp   zBSPNode.build  s     x=A::!!**002DJXa[)! QRL 	DJJ$$dmmT]]E4	 u:>zz!$Y
JJU#t9q=yy #I	IIOOD! r   r   )rn   zOptional[list[Polygon]])rO   rm   rP   )rn   rT   rO   rT   )r}   rm   rO   rQ   )rO   rT   )rn   rT   rO   rQ   )rU   rV   rW   rX   rY   r   r$   rv   ry   r|   r   rp   r[   r   r   rm   rm      s1     7I!	
60#"r   rm   c                  j    e Zd ZdZdddZedd       ZdddZddZddZ	e	Z
ddZeZdd	ZeZdd
Zy)r   a1  
    Constructive Solid Geometry (CSG) is a modeling technique that uses Boolean
    operations like union and intersection to combine 3D solids. This class
    implements CSG operations on meshes.

    New 3D solids are created from :class:`~ezdxf.render.MeshBuilder` objects
    and results can be exported as :class:`~ezdxf.render.MeshTransformer` objects
    to `ezdxf` by method :meth:`mesh`.

    Args:
        mesh: :class:`ezdxf.render.MeshBuilder` or inherited object
        meshid: individual mesh ID to separate result meshes, ``0`` is default

    Nc                    |g | _         y |j                         }|j                          |j                         D cg c]  }t	        ||       c}| _         y c c}w r   )rn   copynormalize_facesfaces_as_verticesr9   )r   meshr-   	mesh_copyfaces        r   r   zCSG.__init__<  sQ    <+-DM		I%%'2;2M2M2O*.f%DM s   Ac                (    t               }||_        |S r   )r   rn   )r   rn   csgs      r   from_polygonszCSG.from_polygonsF  s    e
r   c                    t               }| j                  D ]-  }||j                  k(  s|j                  |j                         / t        j                  |      S )z
        Returns a :class:`ezdxf.render.MeshTransformer` object.

        Args:
             meshid: individual mesh ID, ``0`` is default

        )r   rn   r-   add_facer.   r
   from_builder)r   r-   r   r   s       r   r   zCSG.meshL  sN      !MM 	-D$dmm,	- ++D11r   c                z    | j                  | j                  D cg c]  }|j                          c}      S c c}w r   )r   rn   r$   )r   rt   s     r   r$   z	CSG.cloneZ  s+    !!dmm"D1779"DEE"Ds   8c                   t        | j                         j                        }t        |j                         j                        }|j                  |       |j                  |       |j	                          |j                  |       |j	                          |j                  |j                                t        j                  |j                               S )a3  
        Return a new CSG solid representing space in either this solid or in the
        solid `other`. Neither this solid nor the solid `other` are modified::

            A.union(B)

            +-------+            +-------+
            |       |            |       |
            |   A   |            |       |
            |    +--+----+   =   |       +----+
            +----+--+    |       +----+       |
                 |   B   |            |       |
                 |       |            |       |
                 +-------+            +-------+
        )	rm   r$   rn   r|   rv   rp   r   r   r   r   otherr   r   s       r   unionz	CSG.union]  s      DJJL))*EKKM**+			!			!	
			!	
	 !  !122r   c                   t        | j                         j                        }t        |j                         j                        }|j                          |j	                  |       |j	                  |       |j                          |j	                  |       |j                          |j                  |j                                |j                          t        j                  |j                               S )a  
        Return a new CSG solid representing space in this solid but not in the
        solid `other`. Neither this solid nor the solid `other` are modified::

            A.subtract(B)

            +-------+            +-------+
            |       |            |       |
            |   A   |            |       |
            |    +--+----+   =   |    +--+
            +----+--+    |       +----+
                 |   B   |
                 |       |
                 +-------+
        	rm   r$   rn   rv   r|   rp   r   r   r   r   s       r   subtractzCSG.subtracty  s      DJJL))*EKKM**+	
			!			!	
			!	
	 !	
  !122r   c                   t        | j                         j                        }t        |j                         j                        }|j                          |j	                  |       |j                          |j	                  |       |j	                  |       |j                  |j                                |j                          t        j                  |j                               S )a  
        Return a new CSG solid representing space both this solid and in the
        solid `other`. Neither this solid nor the solid `other` are modified::

            A.intersect(B)

            +-------+
            |       |
            |   A   |
            |    +--+----+   =   +--+
            +----+--+    |       +--+
                 |   B   |
                 |       |
                 +-------+
        r   r   s       r   	intersectzCSG.intersect  s      DJJL))*EKKM**+	
			!	
			!			!	 !	
  !122r   c                h    | j                         }|j                  D ]  }|j                           |S )zq
        Return a new CSG solid with solid and empty space switched. This solid is
        not modified.
        )r$   rn   r&   )r   r   rt   s      r   inversezCSG.inverse  s0    
 jjl 	AFFH	
r   )Nr   )r   zOptional[MeshBuilder]r-   rk   )rn   rT   rO   r   rj   )r-   rk   rO   r
   )rO   r   )r   r   rO   r   )rU   rV   rW   rX   r   rZ   r   r   r$   r   __add__r   __sub__r   __mul__r   r[   r   r   r   r   ,  sT      
2F34 G38 G36 Gr   N)
__future__r   typingr   
ezdxf.mathr   r   r   ezdxf.renderr   r	   r
   __all__r2   r1   r0   r5   r/   r   r9   rm   r   r[   r   r   <module>r      sn    #  > > G G> '	^C ^CB!5 !5Hs" s"lP Pr   