
    j                     ^   d Z ddlZddlZddl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 ddlmZmZ dd	lmZmZmZmZ  ej0                  d
      Zdej4                  _         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"y)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   )creationinertiasample	trianglesutil)transformations)Trimesh)cache_decorator)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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                  j                          d| _        d| j
                  _        y )NFT)super__init___dataclear	_validate_cacheforce_immutable)self	__class__s    ?/DATA/.local/lib/python3.12/site-packages/trimesh/primitives.pyr   zPrimitive.__init__%   s5     	

 '+#    c                 4    dt        |       j                   dS )Nz<trimesh.primitives.>)type__name__r   s    r   __repr__zPrimitive.__repr__1   s    %d4j&9&9%:!<<r    c                     | j                   d   }t        j                  |d      r|S | j                          | j                   d   S )Nfaces   r   r   is_shape_create_meshr   storeds     r   r(   zPrimitive.faces4   s>    W%==)M{{7##r    c                     |t        d      y )Nz+primitive faces are immutable: not setting!
ValueErrorr   valuess     r   r(   zPrimitive.faces<   s    JKK r    c                     | j                   d   }t        j                  |d      r|S | j                          | j                   d   S )Nverticesr)   r,   r/   s     r   r7   zPrimitive.verticesA   s>    Z(==)M{{:&&r    c                     |t        d      y )Nz.primitive vertices are immutable: not setting!r2   r4   s     r   r7   zPrimitive.verticesJ   s    MNN r    c                 <   d| j                   vr| j                          | j                   d   }t        j                  |d      r|S t	        j
                  | j                        \  }}t        j                  t        |      df      }|||<   || j                   d<   |S )Nr7   face_normalsr)   r+   )	r   r.   r   r-   r   normalsnpzeroslen)r   r0   unitvalidr;   s        r   r:   zPrimitive.face_normalsO   s    
 T[[( ^,==)M  ''7e((CJ?+&-N#r    c                 4    |t        j                  d       y y )Nz%Primitive face normals are immutable!)r   warningr4   s     r   r:   zPrimitive.face_normalsf   s    KK?@ 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.transformk   s     ~~'''r    c                     t               )z:
        Should be implemented by each primitive.
        )NotImplementedErrorr%   s    r   to_dictzPrimitive.to_dictw   s    
 "##r    c                    |j                  | j                                |j                  d        t        |       di |}|r| j                  j                         |_        | j                  j                         |_        | j                  j                  j                         D ]#  \  }}||j                  vs||j                  |<   % |S )z
        Return a copy of the Primitive object.

        Returns
        -------------
        copied : object
          Copy of current primitive
        kind )
updaterI   popr#   visualcopymetadatar   dataitems)r   include_visualkwargsprimitive_copykvs         r   rP   zPrimitive.copy~   s     	dlln%

6#d-f-$(KK$4$4$6N! #'--"4"4"6JJOO))+DAq,,,*+$$Q' , r    c           
          t        d| j                  j                         | j                  j                         | 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:   rZ   rL   )r
   r7   rP   r(   r:   rN   )r   rU   results      r   to_meshzPrimitive.to_mesh   sb      
]]'')**//#**//1JJy%0	

 
 r    c                    t        j                  |dt         j                        }|j                  dk7  rt	        d      t        j                  |t        d      r| S | j                  }|j                  j                         }t         j                  j                  |ddddf         dz  }t        t        t        t         f}t#        | |      rt%        |d	z
        dkD  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        j2                  d	|z        |g      }nt        j4                  ||      }t1        j6                  |      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hasattrrc   rd   re   	multi_dottfscale_matrixdotis_rigid)r   matrixprimcurrentscalekindsupdateds          r   apply_transformzPrimitive.apply_transform   sr    vS

C<<6!788==D1K~~..%%'		fRaR!Vn-)< h0dE"s53;'7$'>tX&u$tX&u$tY'%BQBENe#NnnfboocEk.JG%TUG ffVW-G {{7#@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Cr    T)r$   
__module____qualname____doc____copy____deepcopy__r   r&   propertyr(   setterr7   r:   rF   abcabstractmethodrI   rP   r\   r   r.   __classcell__r   s   @r   r   r      s     HL
+= $ $ \\L L ' ' __O O  , A A 	( 	( 	$ $:.4lDr    r   c                   J     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.
    c                 b   |j                   | _         || _        || _        | j                   j                  |       || _        |j                         D ]=  \  }}|j                  |d      }|t        j                  ||      | j                   |<   ? | j                  sd| j                   _	        yy)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   _mutablerS   getr   convert_likemutable)r   parentdefaultsrU   r   keydefaultvalues           r   r   zPrimitiveAttributes.__init__   s     \\
!

(# %NN,LCJJsD)E "&"3"3E7"C

3	 - }}!&DJJ r    c                     dd l }dj                  | j                  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__  sW    
 	 &''00^^DNN"^=aC  
 	 
r    c                    |j                  d      rt        | 	  |      S |dk(  r| j                  d   d ddf   S || j                  v r0t        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    >>#7&s++H_::k*2A2q511DNN"$$TZZ_dnnS6IJJB3%rJKKr    c                    |j                  d      rt        | 	  ||      S |dk(  rSt        j                  |t        j
                        }t        j                  d      }||d ddf<   || j                  d<   y || j                  v rH| j                  r1t        j                  || j                  |         | j                  |<   y t        d      t        | j                  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<   arrayrg   eyer   r   r   r   r   r3   listkeys)r   r   r   rF   r   r   s        r   r   zPrimitiveAttributes.__setattr__3  s    >>#7&sE22H_HHU"**5Eq	I$Ibqb!e&/DJJ{#DNN"}}"&"3"3E4>>#;N"O

3 Q  ++-.D7v\JKKr    c                     t        t        t        |             t        | j                  j                               z         }|S N)sorteddirr#   r   r   r   )r   r[   s     r   __dir__zPrimitiveAttributes.__dir__G  s0    DJ$t~~/B/B/D*EEFr    r   )
r$   r   r   r   r   r   r   r   r   r   r   s   @r   r   r      s3     'D  *LL(r    r   c                        e Zd Zd fd	Zed        Zedefd       Zed        Zed        Z	e
d        Zd Zd	 Zd
 Z xZS )rn   c           	          t         |           ddt        j                  d      dd}t	        | |||||d|      | _        y)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.
              $@rb   r       rc   rd   rF   sectionsr   rU   r   Nr   r   r<   r   r   rE   r   rd   rc   rF   r   r   r   r   s          r   r   zCylinder.__init__M  sO    " 	"cq	WYZ,  &$	 

r    c                     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   rd   rc   r%   s    r   volumezCylinder.volumem  s1     --q00DNN4I4IIIr    returnc                     | j                   j                  | j                   j                  }}t        j                  dz  |z  |z  dt        j                  z  |dz  z  z   S )z?
        The analytical area of the cylinder primitive
        r   rE   rd   rc   r<   r   r   rd   rc   s      r   areazCylinder.areay  sO     ..0E0E	F"V+BEE	FAI0EFFr    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
        )massrd   rc   rF   )r   cylinder_inertiar   rE   rd   rc   rF   )r   tensors     r   moment_inertiazCylinder.moment_inertia  sI     ))>>((>>((nn..	
 r    c                 d    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<   rw   rE   rF   r   axiss     r   	directionzCylinder.direction  s*     vvdnn..=bq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   rc   r<   rw   rF   	transposeT)r   halfpointss      r   segmentzCylinder.segment  sr     ~~$$s*NN$$bllQD5!4Dq!TSTo3V&W

!ArrE r    c                     d| j                   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   rd   rc   )rE   rF   tolistfloatrd   rc   r%   s    r   rI   zCylinder.to_dict  sK     1188:DNN112DNN112	
 	
r    c                     t        |      }t        | j                  j                  |dz  z   | j                  j                  |z   | j                  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   )rc   rd   rF   )r   rn   rE   rc   rd   rF   rP   )r   distancebuffereds      r   bufferzCylinder.buffer  s\      ?>>((8a<7>>((83nn..33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<   y )Nz$creating mesh for Cylinder primitive)rd   rc   r   rF   r7   r(   r:   )r   debugr   r   rE   rd   rc   r   rF   r7   r   r(   r:   r   meshs     r   r.   zCylinder._create_mesh  s    		89  >>((>>((^^,,nn..	
 #'--J#zzG&*&7&7N#r    )rb   rb   Nr   T)r$   r   r   r   r   r   r   r   r   r   r   r   rI   r   r.   r   r   s   @r   rn   rn   L  s    
@ 	J 	J Ge G G  $ 	 	  $
$08r    rn   c                   z     e Zd Z	 d	 fd	Zed        Zedefd       Zedefd       Z	d Z
ed        Zd Z xZS )
ro   c           	          t         |           ddt        j                  d      dd}t	        | |||||d|      | _        y)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.
        rb   r   r   r   r   Nr   r   s          r   r   zCapsule.__init__  sO    & 	!SrvvayVXY,  &$	 

r    c                 .    | j                   j                  S r   rD   r%   s    r   rF   zCapsule.transform      ~~'''r    r   c                     | j                   j                  | j                   j                  }}t        j                  |dz  z  d|z  |z   z  S )z
        The analytic volume of the capsule primitive.

        Returns
        ---------
        volume : float
          Volume of the capsule
        r   gUUUUUU?r   r   s      r   r   zCapsule.volume  sC     ..0E0E	!yF&:V&CDDr    c                     | j                   j                  | j                   j                  }}dt        j                  z  |z  |z  dt        j                  z  |dz  z  z   S )z
        The analytic area of the capsule primitive.

        Returns
        ---------
        area : float
          Area of the capsule
        r   r   r   r   s      r   r   zCapsule.area   sO     ..0E0EBEE	F"V+BEE	FAI0EFFr    c                     d| j                   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   rc   rd   )rE   rF   r   r   rc   rd   r%   s    r   rI   zCapsule.to_dict-  sK     1188:DNN112DNN112	
 	
r    c                 d    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*     vvdnn..=bqAr    c                    t        j                  d       t        j                  | j                  j
                  | j                  j                        }|j                  | j                  j                         |j                  | j                  d<   |j                  | j                  d<   |j                  | j                  d<   y )Nz%creating mesh for `Capsule` primitive)rd   rc   r7   r(   r:   )r   r   r   r   rE   rd   rc   r   rF   r7   r   r(   r:   r   s     r   r.   zCapsule._create_meshL  s    		9:>>((1F1F
 	T^^556"&--J#zzG&*&7&7N#r    )rb   r   Nr   T)r$   r   r   r   r   rF   r   r   r   r   rI   r   r.   r   r   s   @r   ro   ro     sz    LP 
D ( ( 
E 
E 
E 
Ge 
G 
G
$ 
 

8r    ro   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d        Zed        Zed        Zd Z xZS )rp   rd   r   rF   subdivisionsr   c                    t         |           t        |      t        |      d}|1|t	        d      t        j                  d      }||dddf<   ||d<   n|||d<   t        | dt        j                  d      dd||	      | _        y)
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.
        )rd   r   Nz3only one of `center` and `transform` may be passed!r   r+   rF   rb   )rd   rF   r   r   )	r   r   r   intr3   r<   r   r   rE   )	r   rd   r   rF   r   r   constructor	translater   s	           r   r   zSphere.__init__Z  s    2 	!&vL@QR $ !VWWq	I%Ibqb!e'0K$"'0K$ - #"&&)QO	
r    c                 .    | j                   j                  S r   rE   r   r%   s    r   r   zSphere.center  s    ~~$$$r    c                 &    || j                   _        y r   r   )r   r   s     r   r   zSphere.center  s     %r    c                     d| j                   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   rd   )rE   rF   r   r   rd   r%   s    r   rI   zSphere.to_dict  s9     1188:DNN112
 	
r    c                     t        j                  | j                  j                  | j                  j                  z
  | j                  j                  | j                  j                  z   g      }|S r   )r<   r   rE   r   rd   )r   boundss     r   r   zSphere.bounds  sV    
 %%(=(==%%(=(==
 r    c                     | j                   S r   )bounding_boxr%   s    r   bounding_box_orientedzSphere.bounding_box_oriented  s        r    c                 `    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   rd   r   r   s     r   r   zSphere.area  s*     RUU{dnn33Q67r    c                 f    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   r   s     r   r   zSphere.volume  s/     +!6!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   rd   )r   sphere_inertiar   rE   rd   r%   s    r   r   zSphere.moment_inertia  s%     %%4;;t~~?T?TUUr    c                 p   t        j                  d       t        j                  | j                  j
                  | j                  j                        }|j                  | j                  j                  z   | j                  d<   |j                  | j                  d<   |j                  | j                  d<   y )Nz"creating mesh for Sphere primitive)r   rd   r7   r(   r:   )r   r   r   	icosphererE   r   rd   r7   r   r   r(   r:   )r   r?   s     r   r.   zSphere._create_mesh  s    		67!!44T^^=R=R

 #'--$..2G2G"GJ#zzG&*&7&7N#r    )rb   NNr+   T)r$   r   r   r   r   r   r   boolr   r   r   r   rI   r   r   r   r   r   r   r.   r   r   s   @r   rp   rp   Y  s     &*)- !-
-
 #-
 I&	-

 -
 -
^ % % ]]& &
" 
 
 ! ! 
 
 
 
 	V 	V	8r    rp   c                   p     e Zd Zd
 fd	Zd Zed        Zd ZddZed        Z	e
d        Zd Zd	 Z xZS )rm   c                    t         |           t        j                  d      t        j                  d      d}|||t        d      t        j                  |t        j                        }|j                  dk7  rt        d      t        j                  |d	
      }t        j                  d      }|d	   |dz  z   |dddf<   t        | |||d|      | _        y)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   re   Nz<if `bounds` is passed `extents` and `transform` must not be!r   r   r+   z`bounds` must be (2, 3) floatr   )r   r   re   rF   r   )r   r   r<   r   onesr3   r   rg   rh   ptpr   rE   )r   re   rF   r   r   r   r   s         r   r   zBox.__init__  s      	!#rwwqzB"i&; R  XXfBJJ7F||v% !@AAffV!,Gq	I%ay7S=8Ibqb!e,&Y?	
r    c                     d| j                   j                  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   re   )rE   rF   r   re   r%   s    r   rI   zBox.to_dict  s=     1188:~~--44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
        )re   countrF   )r   volume_rectangularrE   re   rF   )r   r  sampless      r   sample_volumezBox.sample_volume(  s8     ++NN**nn..

 r    c                 ~   ||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
        z$only step OR count can be specified!g      ?)step)r  z'either count or step must be specified!)ry   )r3   r<   r   rE   re   r   grid_arangegrid_linspaceru   transform_pointsrF   )r   r  r  r   gridtransformeds         r   sample_gridzBox.sample_grid=  s    & !1CDD DNN222DNN4J4JKLsR##F6D%%fE:DFGG))$t~~7O7OPr    c                     t        j                  | j                  j                  d      rGt	        j
                  | j                  j                  ddddf   t	        j                  d             S y)zK
        Returns whether or not the current box is rotated at all.
        ra   r   r+   F)r   r-   rE   rF   r<   ri   r   r%   s    r   is_orientedzBox.is_oriented`  sV    
 ==116:{{4>>#;#;AaC1H#ErvvayQQQr    c                 j    t        t        j                  | j                  j                              }|S )z
        Volume of the box Primitive.

        Returns
        --------
        volume : float
          Volume of box.
        )r   r<   prodrE   re   r  s     r   r   z
Box.volumej  s&     rwwt~~5567r    c                    t        j                  d       t        j                  | j                  j
                  | j                  j                        }| j                  j                  j                  |j                  j                         |j                  | j                  d<   |j                  | j                  d<   |j                  | j                  d<   y )Nzcreating mesh for Box primitiver  r7   r(   r:   )r   r   r   r  rE   re   rF   r   cacherM   r7   r(   r:   )r   r  s     r   r.   zBox._create_meshw  s    		34llNN**dnn6N6N
 	  !1!12"%,,J"yyG&)&6&6N#r    c                 r    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   re   rF   )r   r&  s     r   
as_outlinezBox.as_outline  s/     	/ NN**dnn6N6N
 	
r    )NNNT)NN)r$   r   r   r   rI   r   rF   r  r  r   r   r   r.   r(  r   r   s   @r   rm   rm     s_    '
R
" ( (*!F   
 
	7
r    rm   c            	            e Zd Z	 	 	 	 	 ddee   dededef fdZed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zd ZddZd Zd Z xZS )	ExtrusionrF   rc   r   	mid_planec           	          ddl m} t        |            |ddg      j	                  d      t        j                  d      ddd}t        | |||||d|      | _        y	)
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   )Pointrb   r   F)polygonrF   rc   r+  )rF   r.  rc   r+  r   N)	shapely.geometryr-  r   r   r   r<   r   r   rE   )	r   r.  rF   rc   r   r+  r-  r   r   s	           r   r   zExtrusion.__init__  so    0 	+ 	 aV}++C0	
 -&" &	 

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   )rr   rE   rc   r.  lengthr   r  s     r   r   zExtrusion.area  sQ     4>>((4>>+A+A+H+HH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
        )rr   rE   r.  r   rc   r  s     r   r   zExtrusion.volume  s2     T^^++004>>3H3HH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<   rw   rE   rF   signrc   )r   r   s     r   r   zExtrusion.direction  sT     FFNN$$RaR!V,sCAVAV9W.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
                  j                        \  }}t        j                  |t        | j                  j                              }t        j                  j                  t        j                  |            }| j                  j                  dz  |d<   t        j                  | j                  j                   |      }t#        ||d      S )Nr   )r   r   r  F)rF   re   r   ) r   oriented_bounds_2DrE   r.  exteriorcoordsr<   appendrr   rc   rk   invru   planar_matrix_to_3Drw   rF   rm   )r   r   	to_originr  re   
rotation_Zto_3Ds          r   r   zExtrusion.bounding_box_oriented  s     	  224>>3I3I3R3R3Y3YZ	3))CT^^%:%:!;<YY]]2#9#9)#DE
>>0036
4t~~//<UGUCCr    c                     t        |      }t        j                  d      }||d<   t        j                  | j                  j
                  j                         |j                               }|| j                  _        y)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   rw   rE   rF   rP   )r   r   translationnew_transforms       r   slidezExtrusion.slide  s\     ?ffQi$Dt~~77<<>@P@P@RS#0 r    c                    t        |      }||}| j                  j                  }|t        j                  |      dz  |z  z  } t        |       d| j                  j                  j                         | j                  j                  j                  |      |d|}|j                  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
        r   )rF   r.  rc   rL   )r   rE   rc   r<   r5  r#   rF   rP   r.  r   rG  )r   r   distance_heightrU   rc   r   s         r   r   zExtrusion.buffer)  s    & ?"&O &&"''&/C'/99 4: 
nn..335NN**11(;
 	
 	'/9:r    c                     d| j                   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   rc   )rE   r.  wktrF   r   r   rc   r%   s    r   rI   zExtrusion.to_dictT  sL      ~~--111188:DNN112	
 	
r    c                    t        j                  d       t        j                  | j                  j
                  | j                  j                  | j                  j                  | j                  j                        }t        j                  r|j                  dk  rt        d      |j                  | j                  d<   |j                  | j                  d<   y )Nz%creating mesh for Extrusion primitive)r.  rc   rF   r+  r4  zmatrix inverted mesh!r7   r(   )r   r   r   extrude_polygonrE   r.  rc   rF   r+  r   strictr   r3   r7   r   r(   r   s     r   r.   zExtrusion._create_meshf  s    		9:''NN**>>((nn..nn..	
 ::$+++455 #'--J#zzGr    )NNrb   TFr   )r$   r   r   r   r   r   r  r   r   r   r   r   r   r7  rF   r   rG  r   rI   r.   r   r   s   @r   r*  r*    s     )-.
 I&.
 	.

 .
 .
`  "      
/ 
/ ( ( D D 1 )V
$*r    r*  )#r   r   numpyr<   r:  r   r   r   r   r   r	   ru   baser
   cachingr   	constantsr   r   typedr   r   r   r   r   rj   flags	writeabler   r   rn   ro   rp   rm   r*  rL   r    r   <module>rW     s      8 8 #  $  7 7 BFF1I	!	 ND NDb] ]@]8y ]8@j8i j8ZM8Y M8`h
) h
Vb*	 b*r    