
    l0j8                     t   d Z ddlZddlZddlmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZmZ ddlmZmZmZmZ  ej        d	          Zd
ej        _         G d de          Z G d d          Z G d de          Z G d de          Z G d de          Z G d de          Z  G d de          Z!dS )z
primitives.py
----------------

Subclasses of Trimesh objects that are parameterized as primitives.

Useful because you can move boxes and spheres around
and then use trimesh operations on them at any point.
    N   )cachingcreationinertiasample	trianglesutil)transformations)Trimesh)logtol)	ArrayLikeIntegerNumberOptional   Fc                        e Zd ZdZdZdZ fdZd Zed             Z	e	j
        d             Z	ed             Zej
        d             Zed	             Zej
        d
             Zed             Zej        d             Zd Zd Zd Zd Z xZS )	Primitivez
    Geometric Primitives which are a subclass of Trimesh.
    Mesh is generated lazily when vertices or faces are requested.
    Nc                     t                                                       | j                                         d| _        d| j        _        d S )NFT)super__init___dataclear	_validate_cacheforce_immutable)self	__class__s    U/home/wildlama/miniconda3/envs/lam/lib/python3.11/site-packages/trimesh/primitives.pyr   zPrimitive.__init__$   sH     	
 '+###    c                 2    dt          |           j         dS )Nz<trimesh.primitives.>)type__name__r   s    r   __repr__zPrimitive.__repr__0   s    <d4jj&9<<<<r    c                     | j         d         }t          j        |d          r|S |                                  | j         d         S )Nfaces   r   r	   is_shape_create_meshr   storeds     r   r(   zPrimitive.faces3   sF    W%=)) 	M{7##r    c                 (    |t          d          d S )Nz+primitive faces are immutable: not setting!
ValueErrorr   valuess     r   r(   zPrimitive.faces;   s    JKKK r    c                     | j         d         }t          j        |d          r|S |                                  | j         d         S )Nverticesr)   r,   r/   s     r   r7   zPrimitive.vertices@   sF    Z(=)) 	M{:&&r    c                 (    |t          d          d S )Nz.primitive vertices are immutable: not setting!r2   r4   s     r   r7   zPrimitive.verticesI   s    MNNN r    c                     | j         d         }t          j        |d          r|S t          j        | j                  \  }}t          j        t          |          df          }|||<   || j         d<   |S )Nface_normalsr)   r+   )r   r	   r-   r   normalsnpzeroslen)r   r0   unitvalidr;   s        r   r:   zPrimitive.face_normalsN   sr     ^,=)) 	M'77e(CJJ?++&-N#r    c                 6    |t          j        d           d S d S )Nz%Primitive face normals are immutable!)r   warningr4   s     r   r:   zPrimitive.face_normals]   s'    K?@@@@@ r    c                     | j         j        S )z
        The transform of the Primitive object.

        Returns
        -------------
        transform : (4, 4) float
          Homogeneous transformation matrix
        	primitive	transformr%   s    r   rF   zPrimitive.transformb   s     ~''r    c                     t                      )z:
        Should be implemented by each primitive.
        )NotImplementedErrorr%   s    r   to_dictzPrimitive.to_dictn   s    
 "###r    c                 R   |                     |                                            |                    d            t          |           di |}| j                                        |_        | j        j                                        D ]\  }}||j        vr
||j        |<   |S )z
        Return a copy of the Primitive object.

        Returns
        -------------
        copied : object
          Copy of current primitive
        kind )	updaterI   popr#   metadatacopyr   dataitems)r   kwargsprimitive_copykvs        r   rP   zPrimitive.copyu   s     	dllnn%%%

6#d--f--"&-"4"4"6"6JO))++ 	, 	,DAq,,,*+$Q'r    c           
          t          d| j                                        | j                                        | j                                        |                    dd          d|}|S )a,  
        Return a copy of the Primitive object as a Trimesh.

        Parameters
        -----------
        kwargs : dict
          Passed to the Trimesh object constructor.

        Returns
        ------------
        mesh : trimesh.Trimesh
          Tessellated version of the primitive.
        processF)r7   r(   r:   rX   rL   )r   r7   rP   r(   r:   rN   )r   rS   results      r   to_meshzPrimitive.to_mesh   sq      
]''))*//##*//11JJy%00	
 

 
 
 r    c                    t          j        |dt           j                  }|j        dk    rt	          d          t          j        |t          d          r| S | j        }|j	        
                                }t           j                            |ddddf                   dz  }t          t          t          t           f}t#          | |          rt%          |d	z
            dk    rt'          |d
          r|xj        |z  c_        t'          |d          r|xj        |z  c_        t'          |d          r|xj        |z  c_        |dddfxx         |z  cc<   t          j        |t1          j        d	|z            |g          }nt          j        ||          }t1          j        |          st	          d          || j        _	        | S )at  
        Apply a transform to the current primitive by
        applying a new transform on top of existing
        `self.primitive.transform`. If the matrix
        contains scaling it will change parameters
        like `radius` or `height` automatically.

        Parameters
        ------------
        matrix: (4, 4) float
          Homogeneous transformation
        C)orderdtyper   r   zmatrix must be `(4, 4)`!g:0yE>Nr+   gUUUUUU?      ?heightradiusextentsz!Couldn't produce rigid transform!)r<   
asanyarrayfloat64shaper3   r	   allclose	_IDENTITYrE   rF   rP   linalgdetBoxCylinderCapsuleSphere
isinstanceabshasattrra   rb   rc   	multi_dottfscale_matrixdotis_rigid)r   matrixprimcurrentscalekindsupdateds          r   apply_transformzPrimitive.apply_transform   s    vS
CCC<6!!7888=D11 	K~.%%''	fRaR!Vn--)< h0dE"" 	.s53;'7'7$'>'>tX&& %u$tX&& %u$tY'' &%BQBENNNe#NNNnfbocEk.J.JG%TUUGG fVW--G {7## 	B@AAA $+ r    c                      t          d          )Nz'Primitive doesn't define mesh creation!r2   r%   s    r   r.   zPrimitive._create_mesh   s    BCCCr    )r$   
__module____qualname____doc____copy____deepcopy__r   r&   propertyr(   setterr7   r:   rF   abcabstractmethodrI   rP   rZ   r}   r.   __classcell__r   s   @r   r   r      s         HL
+ 
+ 
+ 
+ 
+= = = $ $ X$ \L L \L ' ' X' _O O _O   X A A A 	( 	( X	( 	$ $ $  0  .4 4 4lD D D D D D Dr    r   c                   P     e Zd ZdZddZed             Z fdZ fdZd Z xZ	S )	PrimitiveAttributesz:
    Hold the mutable data which defines a primitive.
    Tc                 D   |j         | _         || _        || _        | j                             |           || _        |                                D ]:\  }}|                    |d          }|t          j        ||          | j         |<   ;| j        sd| j         _	        dS dS )a5  
        Hold the attributes for a Primitive.

        Parameters
        ------------
        parent : Primitive
          Parent object reference.
        defaults : dict
          The default values for this primitive type.
        kwargs : dict
          User-passed values, i.e. {'radius': 10.0}
        NF)
r   	_defaults_parentrM   _mutablerR   getr	   convert_likemutable)r   parentdefaultsrS   r   keydefaultvalues           r   r   zPrimitiveAttributes.__init__   s     \
!
(### %NN,, 	D 	DLCJJsD))E "&"3E7"C"C
3} 	'!&DJ	' 	'r    c                     dd l }d                    | j        j        j        |                    | j        d          dd                   }|S )Nr   a'  Store the attributes of a {name} object.

When these values are changed, the mesh geometry will 
automatically be updated to reflect the new values.

Available properties and their default values are:
 {defaults}

Example
---------------
p = trimesh.primitives.{name}()
p.primitive.radius = 10

r*   )widthr   )namer   )pprintformatr   r   r$   pformatr   )r   r   docs      r   r   zPrimitiveAttributes.__doc__  s]    
 	 &'0^^DN"^==adC  
 
 	 
r    c                 8   |                     d          r!t                                          |          S |dk    r| j        d         d ddf         S || j        v r+t          j        | j        |         | j        |                   S t          d| d          )N_centerrF   r+   z#primitive object has no attribute 'z' )
startswithr   __getattr__r   r   r	   r   AttributeError)r   r   r   s     r   r   zPrimitiveAttributes.__getattr__  s    >># 	K77&&s+++H__:k*2A2q511DN""$TZ_dnS6IJJJJ3JJJKKKr    c                    |                     d          r"t                                          ||          S |dk    rIt          j        |t          j                  }t          j        d          }||d ddf<   || j        d<   d S || j        v r@| j	        r*t          j        || j        |                   | j        |<   d S t          d          t          | j                                                  }t          d| d	          )
Nr   r   r^   r   r+   rF   z;Primitive is configured as immutable! Cannot set attribute!zOnly default attributes z can be set!)r   r   __setattr__r<   arrayre   eyer   r   r   r	   r   r3   listkeys)r   r   r   rF   r   r   s        r   r   zPrimitiveAttributes.__setattr__%  s   >># 	L77&&sE222H__HU"*555Eq		I$Ibqb!e&/DJ{#FDN""} "&"3E4>#;N"O"O
3 Q   ++--..DJJJJKKKr    c                     t          t          t          |                     t          | j                                                  z             }|S N)sorteddirr#   r   r   r   )r   rY   s     r   __dir__zPrimitiveAttributes.__dir__9  s;    DJJ$t~/B/B/D/D*E*EEFFr    )T)
r$   r   r   r   r   r   r   r   r   r   r   s   @r   r   r      s          '  '  '  'D   X*L L L L LL L L L L(      r    r   c                        e Zd Zd fd	Zej        d             Zej        d             Zej        d             Ze	d	             Z
d
 Zd Zd Z xZS )rl   r`   N    Tc           	          t                                                       ddt          j        d          dd}t	          | |||||d|          | _        dS )a  
        Create a Cylinder Primitive, a subclass of Trimesh.

        Parameters
        -------------
        radius : float
          Radius of cylinder
        height : float
          Height of cylinder
        transform : (4, 4) float
          Homogeneous transformation matrix
        sections : int
          Number of facets in circle.
        mutable : bool
          Are extents and transform mutable after creation.
              $@r`   r   r   ra   rb   rF   sectionsr   rS   r   Nr   r   r<   r   r   rE   r   rb   ra   rF   r   r   r   r   s          r   r   zCylinder.__init__?  sp    " 	"cq		WYZZ,  &$	  

 

 

r    c                 X    t           j        | j        j        dz  z  | j        j        z  }|S )z
        The analytic volume of the cylinder primitive.

        Returns
        ---------
        volume : float
          Volume of the cylinder
           )r<   pirE   rb   ra   r   volumes     r   r   zCylinder.volume_  s)     %$./22dn6KKr    c                 |    t          j        | j        | j        j        | j        j        | j        j                  }|S )z
        The analytic inertia tensor of the cylinder primitive.

        Returns
        ----------
        tensor: (3, 3) float
          3D inertia tensor
        )massrb   ra   rF   )r   cylinder_inertiar   rE   rb   ra   rF   )r   tensors     r   moment_inertiazCylinder.moment_inertial  s?     )>(>(n.	
 
 
 r    c                 X    t          j        | j        j        g d          dd         }|S )z
        The direction of the cylinder's axis.

        Returns
        --------
        axis: (3,) float, vector along the cylinder axis
        r   r   r   r   Nr+   r<   ru   rE   rF   r   axiss     r   	directionzCylinder.direction  s,     vdn.==bqbAr    c           
          | j         j        dz  }t          j        | j         j        t          j        dd| dgdd|dgg                    j        ddddf         }|S )z
        A line segment which if inflated by cylinder radius
        would represent the cylinder primitive.

        Returns
        -------------
        segment : (2, 3) float
          Points representing a single line segment
               @r   r   Nr+   )rE   ra   r<   ru   rF   	transposeT)r   halfpointss      r   segmentzCylinder.segment  sn     ~$s*N$blQD5!4Dq!TSTo3V&W&W
 

AAArrE r    c                     d| j         j                                        t          | j         j                  t          | j         j                  dS )a   
        Get a copy of the current Cylinder primitive as
        a JSON-serializable dict that matches the schema
        in `trimesh/resources/schema/cylinder.schema.json`

        Returns
        ----------
        as_dict : dict
          Serializable data for this primitive.
        cylinder)rK   rF   rb   ra   )rE   rF   tolistfloatrb   ra   r%   s    r   rI   zCylinder.to_dict  sJ     188::DN122DN122	
 
 	
r    c                     t          |          }t          | j        j        |dz  z   | j        j        |z   | j        j                                                  }|S )a  
        Return a cylinder primitive which covers the source
        cylinder by distance: radius is inflated by distance
        height by twice the distance.

        Parameters
        ------------
        distance : float
          Distance to inflate cylinder radius and height

        Returns
        -------------
        buffered : Cylinder
         Cylinder primitive inflated by distance
        r   )ra   rb   rF   )r   rl   rE   ra   rb   rF   rP   )r   distancebuffereds      r   bufferzCylinder.buffer  s\      ??>(8a<7>(83n.3355
 
 

 r    c                    t          j        d           t          j        | j        j        | j        j        | j        j        | j        j                  }|j	        | j
        d<   |j        | j
        d<   |j        | j
        d<   d S )Nz$creating mesh for Cylinder primitive)rb   ra   r   rF   r7   r(   r:   )r   debugr   r   rE   rb   ra   r   rF   r7   r   r(   r:   r   meshs     r   r.   zCylinder._create_mesh  s}    	8999 >(>(^,n.	
 
 
 #'-J#zG&*&7N###r    )r`   r`   Nr   T)r$   r   r   r   r   cache_decoratorr   r   r   r   r   rI   r   r.   r   r   s   @r   rl   rl   >  s        
 
 
 
 
 
@ 
 
 
   $ 	 	 	   X$
 
 
$  08 8 8 8 8 8 8r    rl   c                   d     e Zd Z	 d fd	Zed             Zd Zej        d	             Z	d
 Z
 xZS )rm   r`   r   Nr   Tc           	          t                                                       ddt          j        d          dd}t	          | |||||d|          | _        dS )a  
        Create a Capsule Primitive, a subclass of Trimesh.

        Parameters
        ----------
        radius : float
          Radius of cylinder
        height : float
          Height of cylinder
        transform : (4, 4) float
          Transformation matrix
        sections : int
          Number of facets in circle
        mutable : bool
          Are extents and transform mutable after creation.
        r`   r   r   r   r   Nr   r   s          r   r   zCapsule.__init__  sp    & 	!SrvayyVXYY,  &$	  

 

 

r    c                     | j         j        S r   rD   r%   s    r   rF   zCapsule.transform      ~''r    c                     d| j         j                                        t          | j         j                  t          | j         j                  dS )a  
        Get a copy of the current Capsule primitive as
        a JSON-serializable dict that matches the schema
        in `trimesh/resources/schema/capsule.schema.json`

        Returns
        ----------
        as_dict : dict
          Serializable data for this primitive.
        capsule)rK   rF   ra   rb   )rE   rF   r   r   ra   rb   r%   s    r   rI   zCapsule.to_dict  sJ     188::DN122DN122	
 
 	
r    c                 X    t          j        | j        j        g d          dd         }|S )z
        The direction of the capsule's axis.

        Returns
        --------
        axis : (3,) float
          Vector along the cylinder axis
        r   Nr+   r   r   s     r   r   zCapsule.direction  s,     vdn.==bqbAr    c                    t          j        d           t          j        | j        j        | j        j                  }|                    | j        j                   |j	        | j
        d<   |j        | j
        d<   |j        | j
        d<   d S )Nz%creating mesh for `Capsule` primitive)rb   ra   r7   r(   r:   )r   r   r   r   rE   rb   ra   r}   rF   r7   r   r(   r:   r   s     r   r.   zCapsule._create_mesh  s    	9:::>(1F
 
 
 	T^5666"&-J#zG&*&7N###r    )r`   r   Nr   T)r$   r   r   r   r   rF   rI   r   r   r   r.   r   r   s   @r   rm   rm     s        LP 
  
  
  
  
  
D ( ( X(
 
 
$ 
 
 

8 
8 
8 
8 
8 
8 
8r    rm   c                   &    e Zd Z	 	 	 	 	 ddedee         dee         ded	ef
 fd
Ze	d             Z
e
j        d             Z
d Ze	d             Ze	d             Zej        d             Zej        d             Zej        d             Zd Z xZS )rn   r`   Nr+   Trb   r   rF   subdivisionsr   c                 \   t                                                       t          |          t          |          d}|4|t	          d          t          j        d          }||dddf<   ||d<   n|||d<   t          | dt          j        d          dd||	          | _        dS )
a  
        Create a Sphere Primitive, a subclass of Trimesh.

        Parameters
        ----------
        radius
          Radius of sphere
        center : None or (3,) float
          Center of sphere.
        transform : None or (4, 4) float
          Full homogeneous transform. Pass `center` OR `transform.
        subdivisions
          Number of subdivisions for icosphere.
        mutable
          Are extents and transform mutable after creation.
        )rb   r   Nz3only one of `center` and `transform` may be passed!r   r+   rF   r`   )rb   rF   r   r   )	r   r   r   intr3   r<   r   r   rE   )	r   rb   r   rF   r   r   constructor	translater   s	           r   r   zSphere.__init__*  s    2 	!&vL@Q@QRR $ !VWWWq		I%Ibqb!e'0K$$"'0K$ - #"&))QOO	
 
 
r    c                     | j         j        S r   rE   r   r%   s    r   r   zSphere.centerY  s    ~$$r    c                     || j         _        d S r   r   )r   r   s     r   r   zSphere.center]  s     %r    c                 t    d| j         j                                        t          | j         j                  dS )a  
        Get a copy of the current Sphere primitive as
        a JSON-serializable dict that matches the schema
        in `trimesh/resources/schema/sphere.schema.json`

        Returns
        ----------
        as_dict : dict
          Serializable data for this primitive.
        sphere)rK   rF   rb   )rE   rF   r   r   rb   r%   s    r   rI   zSphere.to_dicta  s:     188::DN122
 
 	
r    c                     t          j        | j        j        | j        j        z
  | j        j        | j        j        z   g          }|S r   )r<   r   rE   r   rb   )r   boundss     r   r   zSphere.boundsr  sE    
 %(==%(==
 
 r    c                     | j         S r   )bounding_boxr%   s    r   bounding_box_orientedzSphere.bounding_box_oriented  s       r    c                 D    dt           j        z  | j        j        dz  z  }|S )z
        Surface area of the current sphere primitive.

        Returns
        --------
        area: float, surface area of the sphere Primitive
              @r   r<   r   rE   rb   r   areas     r   r   zSphere.area  s#     RU{dn3Q67r    c                 J    dt           j        z  | j        j        dz  z  dz  }|S )z
        Volume of the current sphere primitive.

        Returns
        --------
        volume: float, volume of the sphere Primitive
        r   r+   g      @r   r   s     r   r   zSphere.volume  s(     +!6!9:cAr    c                 L    t          j        | j        | j        j                  S )z
        The analytic inertia tensor of the sphere primitive.

        Returns
        ----------
        tensor: (3, 3) float
          3D inertia tensor.
        )r   rb   )r   sphere_inertiar   rE   rb   r%   s    r   r   zSphere.moment_inertia  s!     %4;t~?TUUUUr    c                     t          j        d           t          j        | j        j        | j        j                  }|j        | j        j        z   | j	        d<   |j
        | j	        d<   |j        | j	        d<   d S )Nz"creating mesh for Sphere primitive)r   rb   r7   r(   r:   )r   r   r   	icosphererE   r   rb   r7   r   r   r(   r:   )r   r?   s     r   r.   zSphere._create_mesh  sv    	6777!4T^=R
 
 

 #'-$.2G"GJ#zG&*&7N###r    )r`   NNr+   T)r$   r   r   r   r   r   r   boolr   r   r   r   rI   r   r   r   r   r   r   r   r.   r   r   s   @r   rn   rn   )  sz        &*)- !-
 -
-
 #-
 I&	-

 -
 -
 -
 -
 -
 -
 -
^ % % X% ]& & ]&
 
 
" 
 
 X
 ! ! X! 
 
 
 
 
 
 	V 	V 	V	8 	8 	8 	8 	8 	8 	8r    rn   c                        e Zd Zd fd	Zd Zed             Zd ZddZed             Z	e
j        d	             Zd
 Zd Z xZS )rk   NTc                    t                                                       t          j        d          t          j        d          d}|||t          d          t          j        |t          j                  }|j        dk    rt          d          t          j	        |d	
          }t          j        d          }|d	         |dz  z   |dddf<   t          | |||d|          | _        dS )a   
        Create a Box Primitive as a subclass of Trimesh

        Parameters
        ----------
        extents : Optional[ndarray] (3,) float
          Length of each side of the 3D box.
        transform : Optional[ndarray] (4, 4) float
          Homogeneous transformation matrix for box center.
        bounds : Optional[ndarray] (2, 3) float
          Axis aligned bounding box, if passed extents and
          transform will be derived from this.
        mutable : bool
          Are extents and transform mutable after creation.
        r   r+   )rF   rc   Nz<if `bounds` is passed `extents` and `transform` must not be!r   r   r+   z`bounds` must be (2, 3) floatr   )r   r   rc   rF   r   )r   r   r<   r   onesr3   r   re   rf   ptpr   rE   )r   rc   rF   r   r   r   r   s         r   r   zBox.__init__  s      	!#rwqzzBB"i&; R   XfBJ777F|v%% !@AAAfV!,,,Gq		I%ay7S=8Ibqb!e,&Y??	
 
 
r    c                 ~    d| j         j                                        | j         j                                        dS )a  
        Get a copy of the current Box primitive as
        a JSON-serializable dict that matches the schema
        in `trimesh/resources/schema/box.schema.json`

        Returns
        ----------
        as_dict : dict
          Serializable data for this primitive.
        box)rK   rF   rc   )rE   rF   r   rc   r%   s    r   rI   zBox.to_dict  s>     188::~-4466
 
 	
r    c                     | j         j        S r   rD   r%   s    r   rF   zBox.transform  r   r    c                 \    t          j        | j        j        || j        j                  }|S )a  
        Return random samples from inside the volume of the box.

        Parameters
        -------------
        count : int
          Number of samples to return

        Returns
        ----------
        samples : (count, 3) float
          Points inside the volume
        )rc   countrF   )r   volume_rectangularrE   rc   rF   )r   r  sampless      r   sample_volumezBox.sample_volume  s5     +N*n.
 
 

 r    c                 J   ||t          d          t          j        | j        j         | j        j        g          dz  }|t          j        ||          }n(|t          j        ||          }nt          d          t          j	        || j        j
                  }|S )a  
        Return a 3D grid which is contained by the box.
        Samples are either 'step' distance apart, or there are
        'count' samples per box side.

        Parameters
        -----------
        count : int or (3,) int
          If specified samples are spaced with np.linspace
        step : float or (3,) float
          If specified samples are spaced with np.arange

        Returns
        -----------
        grid : (n, 3) float
          Points inside the box
        Nz$only step OR count can be specified!g      ?)step)r  z'either count or step must be specified!)rw   )r3   r<   r   rE   rc   r	   grid_arangegrid_linspacers   transform_pointsrF   )r   r  r  r   gridtransformeds         r   sample_gridzBox.sample_grid  s    & !1CDDD DN22DN4JKLLsR#F666DD%fE:::DDFGGG)$t~7OPPPr    c                     t          j        | j        j        d          r>t	          j        | j        j        ddddf         t	          j        d                     S dS )zK
        Returns whether or not the current box is rotated at all.
        r_   r   r+   F)r	   r-   rE   rF   r<   rg   r   r%   s    r   is_orientedzBox.is_oriented0  sU    
 =16:: 	{4>#;AaC1H#ErvayyQQQQ5r    c                 \    t          t          j        | j        j                            }|S )z
        Volume of the box Primitive.

        Returns
        --------
        volume : float
          Volume of box.
        )r   r<   prodrE   rc   r   s     r   r   z
Box.volume:  s%     rwt~56677r    c                 .   t          j        d           t          j        | j        j        | j        j                  }| j        j        	                    |j        j                   |j
        | j        d<   |j        | j        d<   |j        | j        d<   d S )Nzcreating mesh for Box primitiver  r7   r(   r:   )r   r   r   r  rE   rc   rF   r   cacherM   r7   r(   r:   )r   r  s     r   r.   zBox._create_meshG  s    	3444lN*dn6N
 
 
 	  !1222"%,J"yG&)&6N###r    c                 P    ddl m}  || j        j        | j        j                  S )z
        Return a Path3D containing the outline of the box.

        Returns
        -----------
        outline : trimesh.path.Path3D
          Outline of box primitive
        r   )box_outliner  )path.creationr  rE   rc   rF   )r   r  s     r   
as_outlinezBox.as_outlineR  s@     	/..... {N*dn6N
 
 
 	
r    )NNNT)NN)r$   r   r   r   rI   r   rF   r  r  r  r   r   r   r.   r   r   r   s   @r   rk   rk     s        '
 '
 '
 '
 '
 '
R
 
 
" ( ( X(  *! ! ! !F   X 
 
 
	7 	7 	7
 
 
 
 
 
 
r    rk   c                        e Zd Zd fd	Zej        d             Zej        d             Zej        d             Ze	d             Z
e	d	             Zej        d
             Zd ZddZd Zd Z xZS )	ExtrusionNr`   Tc                     ddl m} t                                                        |ddg                              d          t          j        d          dd}t          | ||||d|          | _        dS )	a  
        Create an Extrusion primitive, which
        is a subclass of Trimesh.

        Parameters
        ----------
        polygon : shapely.geometry.Polygon
          Polygon to extrude
        transform : (4, 4) float
          Transform to apply after extrusion
        height : float
          Height to extrude polygon by
        mutable : bool
          Are extents and transform mutable after creation.
        r   )Pointr`   r   )polygonrF   ra   rF   r%  ra   r   N)	shapely.geometryr$  r   r   r   r<   r   r   rE   )r   r%  rF   ra   r   r$  r   r   s          r   r   zExtrusion.__init__e  s    " 	+***** 	 uaV}}++C00
 
 -!*w&QQ	
 
 
r    c                     t          | j        j        | j        j        j        z            }|| j        j        j        dz  z  }|S )z
        The surface area of the primitive extrusion.

        Calculated from polygon and height to avoid mesh creation.

        Returns
        ----------
        area: float
          Surface area of 3D extrusion
        r   )rp   rE   ra   r%  lengthr   r   s     r   r   zExtrusion.area  s?     4>(4>+A+HHII&+a//r    c                 \    t          | j        j        j        | j        j        z            }|S )z
        The volume of the Extrusion primitive.
        Calculated from polygon and height to avoid mesh creation.

        Returns
        ----------
        volume : float
          Volume of 3D extrusion
        )rp   rE   r%  r   ra   r   s     r   r   zExtrusion.volume  s(     T^+04>3HHIIr    c                     t          j        | j        j        ddddf         ddt          j        | j        j                  g          }|S )z
        Based on the extrudes transform what is the
        vector along which the polygon will be extruded.

        Returns
        ---------
        direction : (3,) float
          Unit direction vector
        Nr+           )r<   ru   rE   rF   signra   )r   r   s     r   r   zExtrusion.direction  sN     FN$RaR!V,sCAV9W9W.X
 
	 r    c                 .    | j         j        dddf         S )z
        Based on the extrude transform what is the
        origin of the plane it is extruded from.

        Returns
        -----------
        origin : (3,) float
          Origin of extrusion plane
        Nr+   rD   r%   s    r   originzExtrusion.origin  s     ~'A..r    c                     | j         j        S r   rD   r%   s    r   rF   zExtrusion.transform  r   r    c                    ddl m} |                    | j        j        j        j                  \  }}t          j        |t          | j        j
                            }t          j                            t          j        |                    }| j        j
        dz  |d<   t          j        | j        j        |          }t#          ||d          }|S )Nr   )r   r   r  F)rF   rc   r   ) r   oriented_bounds_2DrE   r%  exteriorcoordsr<   appendrp   ra   ri   invrs   planar_matrix_to_3Dru   rF   rk   )r   r   	to_originr  rc   
rotation_Zto_3Dobbs           r   r   zExtrusion.bounding_box_oriented  s     	  224>3I3R3YZZ	3)CT^%:!;!;<<Y]]2#9)#D#DEE
>036
4t~/<<E7EBBB
r    c                     t          |          }t          j        d          }||d<   t          j        | j        j                                        |                                          }|| j        _        dS )z
        Alter the transform of the current extrusion to slide it
        along its extrude_direction vector

        Parameters
        -----------
        distance : float
          Distance along self.extrude_direction to move
        r   r  N)r   r<   r   ru   rE   rF   rP   )r   r   translationnew_transforms       r   slidezExtrusion.slide  sd     ??fQii$Dt~7<<>>@P@P@R@RSS#0   r    c                 x   t          |          }||}| j        j        }|t          j        |          dz  |z  z  } t          |           d| j        j                                        | j        j        	                    |          |d|}|
                    t          j        |           |z             |S )a  
        Return a new Extrusion object which is expanded in profile
        and in height by a specified distance.

        Parameters
        --------------
        distance : float
          Distance to buffer polygon
        distance_height : float
          Distance to buffer above and below extrusion
        kwargs : dict
          Passed to Extrusion constructor

        Returns
        ----------
        buffered : primitives.Extrusion
          Extrusion object with new values
        Nr   r&  rL   )r   rE   ra   r<   r-  r#   rF   rP   r%  r   r@  )r   r   distance_heightrS   ra   r   s         r   r   zExtrusion.buffer  s    & ??"&O &"'&//C'/99 4:: 
n.3355N*11(;;
 
 	
 
 	'/9:::r    c                     d| j         j        j        | j         j                                        t          | j         j                  dS )a"  
        Get a copy of the current Extrusion primitive as
        a JSON-serializable dict that matches the schema
        in `trimesh/resources/schema/extrusion.schema.json`

        Returns
        ----------
        as_dict : dict
          Serializable data for this primitive.
        	extrusion)rK   r%  rF   ra   )rE   r%  wktrF   r   r   ra   r%   s    r   rI   zExtrusion.to_dict  sE      ~-1188::DN122	
 
 	
r    c                     t          j        d           t          j        | j        j        | j        j        | j        j                  }t          j	        r|j
        dk     rt          d          |j        | j        d<   |j        | j        d<   d S )Nz%creating mesh for Extrusion primitive)r%  ra   rF   r,  zmatrix inverted mesh!r7   r(   )r   r   r   extrude_polygonrE   r%  ra   rF   r   strictr   r3   r7   r   r(   r   s     r   r.   zExtrusion._create_mesh*  s    	9:::'N*>(n.
 
 
 : 	6$+++4555 #'-J#zGr    )NNr`   Tr   )r$   r   r   r   r   r   r   r   r   r   r/  rF   r   r@  r   rI   r.   r   r   s   @r   r"  r"  d  s2       !
 !
 !
 !
 !
 !
F   "        
/ 
/ X
/ ( ( X(   "1 1 1 ) ) ) )V
 
 
$* * * * * * *r    r"  )"r   r   numpyr<   r2  r   r   r   r   r   r	   r
   rs   baser   	constantsr   r   typedr   r   r   r   r   rh   flags	writeabler   r   rl   rm   rn   rk   r"  rL   r    r   <module>rO     sG    


     A A A A A A A A A A A A A A A A # # # # # #               7 7 7 7 7 7 7 7 7 7 7 7 BF1II	!	 AD AD AD AD AD AD AD ADH] ] ] ] ] ] ] ]@U8 U8 U8 U8 U8y U8 U8 U8pP8 P8 P8 P8 P8i P8 P8 P8fM8 M8 M8 M8 M8Y M8 M8 M8`h
 h
 h
 h
 h
) h
 h
 h
VU* U* U* U* U*	 U* U* U* U* U*r    