
    Mi                     ^   S r SSKrSSKrSSKJrJrJrJrJ	r	  SSKJ
r  SSKJr  SSKJr  SSKJrJr  SS	KJrJrJrJr  \R0                  " S
5      rS\R4                  l         " S S\5      r " S S5      r " S S\5      r " S S\5      r " S S\5      r  " S S\5      r! " S S\5      r"g)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                   &  ^  \ rS rSrSrSrSrU 4S jrS r\	S 5       r
\
R                  S 5       r
\	S 5       r\R                  S	 5       r\	S
 5       r\R                  S 5       r\	S 5       r\R                   S 5       rSS jrS rS rS rSrU =r$ )	Primitive   zv
Geometric Primitives which are a subclass of Trimesh.
Mesh is generated lazily when vertices or faces are requested.
Nc                    > [         TU ]  5         U R                  R                  5         SU l        SU R
                  l        g )NFT)super__init___dataclear	_validate_cacheforce_immutable)self	__class__s    l/var/www/eduai.edurigo.com/storigo/production/storigo_env/lib/python3.13/site-packages/trimesh/primitives.pyr   Primitive.__init__%   s5     	

 '+#    c                 4    S[        U 5      R                   S3$ )Nz<trimesh.primitives.>)type__name__r   s    r    __repr__Primitive.__repr__1   s    %d4j&9&9%:!<<r"   c                     U R                   S   n[        R                  " US5      (       a  U$ U R                  5         U R                   S   $ )Nfaces   r   r   is_shape_create_meshr   storeds     r    r+   Primitive.faces4   sA    W%==))M{{7##r"   c                      Ub  [        S5      eg )Nz+primitive faces are immutable: not setting!
ValueErrorr   valuess     r    r+   r4   <   s    JKK r"   c                     U R                   S   n[        R                  " US5      (       a  U$ U R                  5         U R                   S   $ )Nverticesr,   r/   r2   s     r    r;   Primitive.verticesA   sA    Z(==))M{{:&&r"   c                      Ub  [        S5      eg )Nz.primitive vertices are immutable: not setting!r6   r8   s     r    r;   r<   J   s    MNN r"   c                 J   SU R                   ;  a  U R                  5         U R                   S   n[        R                  " US5      (       a  U$ [        R
                  " U R                  5      u  p#[        R                  " [        U5      S45      nX$U'   X@R                   S'   U$ )Nr;   face_normalsr,   r.   )	r   r1   r   r0   r   normalsnpzeroslen)r   r3   unitvalidr@   s        r    r?   Primitive.face_normalsO   s    
 T[[( ^,==))M  ''7((CJ?+&-N#r"   c                 8    Ub  [         R                  " S5        g g )Nz%Primitive face normals are immutable!)r   warningr8   s     r    r?   rF   f   s    KK?@ r"   c                 .    U R                   R                  $ )z|
The transform of the Primitive object.

Returns
-------------
transform : (4, 4) float
  Homogeneous transformation matrix
	primitive	transformr'   s    r    rL   Primitive.transformk   s     ~~'''r"   c                     [        5       e)z*
Should be implemented by each primitive.
)NotImplementedErrorr'   s    r    to_dictPrimitive.to_dictw   s    
 "##r"   c                    UR                  U R                  5       5        UR                  S5        [        U 5      " S0 UD6nU(       a  U R                  R                  5       Ul        U R                  R                  5       Ul        U R                  R                  R                  5        H$  u  pEXCR                  ;  d  M  XSR                  U'   M&     U$ )zk
Return a copy of the Primitive object.

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

6d-f-$(KK$4$4$6N! #'--"4"4"6JJOO))+DA,,,*+$$Q' , r"   c           
          [        SU R                  R                  5       U R                  R                  5       U R                  R                  5       UR                  SS5      S.UD6nU$ )z
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)r;   r+   r?   rc   rT   )r
   r;   rX   r+   r?   rV   )r   r]   results      r    to_meshPrimitive.to_mesh   sb      
]]'')**//#**//1JJy%0	

 
 r"   c                    [         R                  " US[         R                  S9nUR                  S:w  a  [	        S5      e[
        R                  " U[        S5      (       a  U $ U R                  nUR                  R                  5       n[         R                  R                  USS2SS24   5      S-  n[        [        [        [         4n[#        X5      (       a  [%        US	-
  5      S:  a  ['        US
5      (       a  U=R(                  U-  sl        ['        US5      (       a  U=R*                  U-  sl        ['        US5      (       a  U=R,                  U-  sl        USS2S4==   U-  ss'   [
        R.                  " U[0        R2                  " S	U-  5      U/5      nO[         R4                  " X5      n[0        R6                  " U5      (       d  [	        S5      eX`R                  l	        U $ )a$  
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!)rA   
asanyarrayfloat64shaper7   r   allclose	_IDENTITYrK   rL   rX   linalgdetBoxCylinderCapsuleSphere
isinstanceabshasattrrm   rn   ro   	multi_dottfscale_matrixdotis_rigid)r   matrixprimcurrentscalekindsupdateds          r    apply_transformPrimitive.apply_transform   s~    vS

C<<6!788==D11K~~..%%'		fRaR!Vn-)< h0d""s53;'7$'>tX&&u$tX&&u$tY''%BQBENe#NnnfboocEk.JG%TUG ffV-G {{7##@AA $+ r"   c                     [        S5      e)Nz'Primitive doesn't define mesh creation!r6   r'   s    r    r1   Primitive._create_mesh   s    BCCr"   )r   T)r&   
__module____qualname____firstlineno____doc____copy____deepcopy__r   r(   propertyr+   setterr;   r?   rL   abcabstractmethodrP   rX   re   r   r1   __static_attributes____classcell__r   s   @r    r   r      s     HL
+= $ $ \\L L ' ' __O O  , A A 	( 	( 	$ $:.4lD Dr"   r   c                   X   ^  \ rS rSrSrS	S jr\S 5       rU 4S jrU 4S jrS r	Sr
U =r$ )
PrimitiveAttributes   z2
Hold the mutable data which defines a primitive.
c                 l   UR                   U l         X l        Xl        U R                   R                  U5        X@l        UR                  5        H?  u  pVUR                  US5      nUc  M  [        R                  " Xv5      U R                   U'   MA     U R                  (       d  SU R                   l	        gg)z
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_parentrU   _mutabler[   getr   convert_likemutable)r   parentdefaultsr]   r   keydefaultvalues           r    r   PrimitiveAttributes.__init__   s     \\
!

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

3	 - }}!&DJJ r"   c                     SS K nSR                  U R                  R                  R                  UR                  U R                  SS9SS S9nU$ )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   PrimitiveAttributes.__doc__  sW    
 	 &''00^^DNN"^=aC  
 	 
r"   c                 $  > UR                  S5      (       a  [        TU ]	  U5      $ US:X  a  U R                  S   S S2S4   $ XR                  ;   a1  [
        R                  " U R                  U   U R                  U   5      $ [        SU S35      e)N_centerrL   r.   z#primitive object has no attribute 'z' )
startswithr   __getattr__r   r   r   r   AttributeError)r   r   r   s     r    r   PrimitiveAttributes.__getattr__)  s    >>#7&s++H_::k*2A2q511NN"$$TZZ_dnnS6IJJB3%rJKKr"   c                   > UR                  S5      (       a  [        TU ]	  X5      $ US:X  aP  [        R                  " U[        R
                  S9n[        R                  " S5      nX#S S2S4'   X0R                  S'   g XR                  ;   aM  U R                  (       a1  [        R                  " X R                  U   5      U R                  U'   g [        S5      e[        U R                  R                  5       5      n[        SU S	35      e)
Nr   r   rj   r   r.   rL   z;Primitive is configured as immutable! Cannot set attribute!zOnly default attributes z can be set!)r   r   __setattr__rA   arrayrq   eyer   r   r   r   r   r7   listkeys)r   r   r   rL   r   r   s        r    r   PrimitiveAttributes.__setattr__3  s    >>#7&s22H_HHU"**5Eq	I$bqb!e&/JJ{#NN"}}"&"3"3E>>#;N"O

3 Q  ++-.D7v\JKKr"   c                     [        [        [        U 5      5      [        U R                  R                  5       5      -   5      nU$ N)sorteddirr%   r   r   r   )r   rd   s     r    __dir__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   r   r   r   r   r   r   s   @r    r   r      s8     'D  *LL( r"   r   c                      ^  \ rS rSrSU 4S jjr\S 5       r\S\4S j5       r\S 5       r	\S 5       r
\S 5       rS	 rS
 rS rSrU =r$ )rx   iL  c           	         > [         TU ]  5         SS[        R                  " S5      SS.n[	        U UUUUUS.US9U l        g)aD  
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.
      $@rl   r       rm   rn   rL   sectionsr   r]   r   Nr   r   rA   r   r   rK   r   rn   rm   rL   r   r   r   r   s          r    r   Cylinder.__init__M  sO    " 	"cq	WYZ,  &$	 

r"   c                     [         R                  U R                  R                  S-  -  U R                  R                  -  $ )zk
The analytic volume of the cylinder primitive.

Returns
---------
volume : float
  Volume of the cylinder
   )rA   pirK   rn   rm   r'   s    r    volumeCylinder.volumem  s1     --q00DNN4I4IIIr"   returnc                     U R                   R                  U R                   R                  p![        R                  S-  U-  U-  S[        R                  -  US-  -  -   $ )z/
The analytical area of the cylinder primitive
r   rK   rn   rm   rA   r   r   rn   rm   s      r    areaCylinder.areay  sM     ..0E0E	F"V+BEE	FAI0EFFr"   c                     [         R                  " U R                  U R                  R                  U R                  R
                  U R                  R                  S9nU$ )zu
The analytic inertia tensor of the cylinder primitive.

Returns
----------
tensor: (3, 3) float
  3D inertia tensor
)massrn   rm   rL   )r   cylinder_inertiar   rK   rn   rm   rL   )r   tensors     r    moment_inertiaCylinder.moment_inertia  sI     ))>>((>>((nn..	
 r"   c                 f    [         R                  " U R                  R                  / SQ5      SS nU$ )zj
The direction of the cylinder's axis.

Returns
--------
axis: (3,) float, vector along the cylinder axis
r   r   r   r   Nr.   rA   r   rK   rL   r   axiss     r    	directionCylinder.direction  s*     vvdnn..=bqAr"   c           
          U R                   R                  S-  n[        R                  " U R                   R                  [        R
                  " SSU* S/SSUS//5      5      R                  SS2SS24   nU$ )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.   )rK   rm   rA   r   rL   	transposeT)r   halfpointss      r    segmentCylinder.segment  sr     ~~$$s*NN$$bllQD5!4Dq!TSTo3V&W

!ArrE r"   c                     SU R                   R                  R                  5       [        U R                   R                  5      [        U R                   R
                  5      S.$ )z
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)rS   rL   rn   rm   )rK   rL   tolistfloatrn   rm   r'   s    r    rP   Cylinder.to_dict  sK     1188:DNN112DNN112	
 	
r"   c                     [        U5      n[        U R                  R                  US-  -   U R                  R                  U-   U R                  R
                  R                  5       S9nU$ )a7  
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   )rm   rn   rL   )r   rx   rK   rm   rn   rL   rX   )r   distancebuffereds      r    bufferCylinder.buffer  s\      ?>>((8a<7>>((83nn..335

 r"   c                    [         R                  " S5        [        R                  " U R                  R
                  U R                  R                  U R                  R                  U R                  R                  S9nUR                  U R                  S'   UR                  U R                  S'   UR                  U R                  S'   g )Nz$creating mesh for Cylinder primitive)rn   rm   r   rL   r;   r+   r?   )r   debugr   r   rK   rn   rm   r   rL   r;   r   r+   r?   r   meshs     r    r1   Cylinder._create_mesh  s    		89  >>((>>((^^,,nn..	
 #'--J#zzG&*&7&7N#r"   rK   )rl   rl   Nr   T)r&   r   r   r   r   r   r   r   r   r   r   r   r   rP   r   r1   r   r   r   s   @r    rx   rx   L  s    
@ 	J 	J Ge G G  $ 	 	  $
$08 8r"   rx   c                      ^  \ rS rSr SU 4S jjr\S 5       r\S\4S j5       r	\S\4S j5       r
S r\S 5       rS	 rS
rU =r$ )ry   i  c           	         > [         TU ]  5         SS[        R                  " S5      SS.n[	        U UUUUUS.US9U l        g)a3  
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.
rl   r   r   r   r   Nr   r   s          r    r   Capsule.__init__  sO    & 	!SrvvayVXY,  &$	 

r"   c                 .    U R                   R                  $ r   rJ   r'   s    r    rL   Capsule.transform      ~~'''r"   r   c                     U R                   R                  U R                   R                  p![        R                  US-  -  SU-  U-   -  $ )zi
The analytic volume of the capsule primitive.

Returns
---------
volume : float
  Volume of the capsule
r   gUUUUUU?r   r   s      r    r   Capsule.volume  sA     ..0E0E	!yF&:V&CDDr"   c                     U R                   R                  U R                   R                  p!S[        R                  -  U-  U-  S[        R                  -  US-  -  -   $ )zc
The analytic area of the capsule primitive.

Returns
---------
area : float
  Area of the capsule
r   r   r   r   s      r    r   Capsule.area   sM     ..0E0EBEE	F"V+BEE	FAI0EFFr"   c                     SU R                   R                  R                  5       [        U R                   R                  5      [        U R                   R
                  5      S.$ )z
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)rS   rL   rm   rn   )rK   rL   r   r   rm   rn   r'   s    r    rP   Capsule.to_dict-  sK     1188:DNN112DNN112	
 	
r"   c                 f    [         R                  " U R                  R                  / SQ5      SS nU$ )zk
The direction of the capsule's axis.

Returns
--------
axis : (3,) float
  Vector along the cylinder axis
r   Nr.   r   r   s     r    r   Capsule.direction?  s*     vvdnn..=bqAr"   c                    [         R                  " S5        [        R                  " U R                  R
                  U R                  R                  S9nUR                  U R                  R                  5        UR                  U R                  S'   UR                  U R                  S'   UR                  U R                  S'   g )Nz%creating mesh for `Capsule` primitive)rn   rm   r;   r+   r?   )r   r   r   r  rK   rn   rm   r   rL   r;   r   r+   r?   r   s     r    r1   Capsule._create_meshL  s    		9:>>((1F1F
 	T^^556"&--J#zzG&*&7&7N#r"   r  )rl   r   Nr   T)r&   r   r   r   r   r   rL   r   r   r   r   rP   r   r1   r   r   r   s   @r    ry   ry     s    LP 
D ( ( 
E 
E 
E 
Ge 
G 
G
$ 
 

8 
8r"   ry   c                      ^  \ rS rSr     SS\S\\   S\\   S\S\4
U 4S jjjr	\
S 5       r\R                  S	 5       rS
 r\
S 5       r\
S 5       r\S 5       r\S 5       r\S 5       rS rSrU =r$ )rz   iY  rn   r   rL   subdivisionsr   c                   > [         TU ]  5         [        U5      [        U5      S.nUb1  Ub  [	        S5      e[
        R                  " S5      nX'SS2S4'   XvS'   OUb  X6S'   [        U S[
        R                  " S5      SS.UUS	9U l        g)
aa  
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.
)rn   r  Nz3only one of `center` and `transform` may be passed!r   r.   rL   rl   )rn   rL   r  r   )	r   r   r   intr7   rA   r   r   rK   )	r   rn   r   rL   r  r   constructor	translater   s	           r    r   Sphere.__init__Z  s    2 	!&vL@QR $ !VWWq	I%bqb!e'0$"'0$ - #"&&)QO	
r"   c                 .    U R                   R                  $ r   rK   r   r'   s    r    r   Sphere.center  s    ~~$$$r"   c                 $    XR                   l        g r   r  )r   r   s     r    r   r    s     %r"   c                     SU R                   R                  R                  5       [        U R                   R                  5      S.$ )z
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)rS   rL   rn   )rK   rL   r   r   rn   r'   s    r    rP   Sphere.to_dict  s9     1188:DNN112
 	
r"   c                     [         R                  " U R                  R                  U R                  R                  -
  U R                  R                  U R                  R                  -   /5      nU$ r   )rA   r   rK   r   rn   )r   boundss     r    r"  Sphere.bounds  sV    
 %%(=(==%%(=(==
 r"   c                     U R                   $ r   )bounding_boxr'   s    r    bounding_box_orientedSphere.bounding_box_oriented  s        r"   c                 `    S[         R                  -  U R                  R                  S-  -  nU$ )zs
Surface area of the current sphere primitive.

Returns
--------
area: float, surface area of the sphere Primitive
      @r   rA   r   rK   rn   r   r   s     r    r   Sphere.area  s*     RUU{dnn33Q67r"   c                 f    S[         R                  -  U R                  R                  S-  -  S-  nU$ )zi
Volume of the current sphere primitive.

Returns
--------
volume: float, volume of the sphere Primitive
r)  r.   g      @r*  r   r   s     r    r   Sphere.volume  s/     +!6!6!9:cAr"   c                 h    [         R                  " U R                  U R                  R                  S9$ )zt
The analytic inertia tensor of the sphere primitive.

Returns
----------
tensor: (3, 3) float
  3D inertia tensor.
)r   rn   )r   sphere_inertiar   rK   rn   r'   s    r    r   Sphere.moment_inertia  s%     %%4;;t~~?T?TUUr"   c                 n   [         R                  " S5        [        R                  " U R                  R
                  U R                  R                  S9nUR                  U R                  R                  -   U R                  S'   UR                  U R                  S'   UR                  U R                  S'   g )Nz"creating mesh for Sphere primitive)r  rn   r;   r+   r?   )r   r   r   	icosphererK   r  rn   r;   r   r   r+   r?   )r   rD   s     r    r1   Sphere._create_mesh  s    		67!!44T^^=R=R

 #'--$..2G2G"GJ#zzG&*&7&7N#r"   r  )rl   NNr.   T)r&   r   r   r   r   r   r   r   boolr   r   r   r   rP   r"  r&  r   r   r   r   r1   r   r   r   s   @r    rz   rz   Y  s     &*)- !-
-
 #-
 I&	-

 -
 -
 -
^ % % ]]& &
" 
 
 ! ! 
 
 
 
 	V 	V	8 	8r"   rz   c                   ~   ^  \ rS rSrSU 4S jjrS r\S 5       rS rSS jr	\S 5       r
\S 5       rS	 rS
 rSrU =r$ )rw   i  c                   > [         TU ]  5         [        R                  " S5      [        R                  " S5      S.nUb  Uc  Ub  [        S5      e[        R                  " U[        R                  S9nUR                  S:w  a  [        S5      e[        R                  " US	S
9n[        R                  " S5      nUS	   US-  -   USS2S4'   [        U UXS.US9U l        g)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.   )rL   ro   Nz<if `bounds` is passed `extents` and `transform` must not be!r   r   r.   z`bounds` must be (2, 3) floatr   )r   r   ro   rL   r   )r   r   rA   r   onesr7   r   rq   rr   ptpr   rK   )r   ro   rL   r"  r   r   r   s         r    r   Box.__init__  s      	!#rwwqzB"i&; R  XXfBJJ7F||v% !@AAffV!,Gq	I%ay7S=8Ibqb!e,&?	
r"   c                     SU R                   R                  R                  5       U R                   R                  R                  5       S.$ )z
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)rS   rL   ro   )rK   rL   r   ro   r'   s    r    rP   Box.to_dict  s=     1188:~~--446
 	
r"   c                 .    U R                   R                  $ r   rJ   r'   s    r    rL   Box.transform$  r  r"   c                     [         R                  " U R                  R                  UU R                  R                  S9nU$ )z
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
)ro   countrL   )r   volume_rectangularrK   ro   rL   )r   rD  sampless      r    sample_volumeBox.sample_volume(  s8     ++NN**nn..

 r"   c                 v   Ub  Ub  [        S5      e[        R                  " U R                  R                  * U R                  R                  /5      S-  nUb  [
        R                  " X2S9nO#Ub  [
        R                  " X1S9nO[        S5      e[        R                  " X@R                  R                  S9nU$ )av  
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)rD  z'either count or step must be specified!)r   )r7   rA   r   rK   ro   r   grid_arangegrid_linspacer   transform_pointsrL   )r   rD  rJ  r"  gridtransformeds         r    sample_gridBox.sample_grid=  s    & !1CDD DNN222DNN4J4JKLsR##F6D%%f:DFGG))$~~7O7OPr"   c                     [         R                  " U R                  R                  S5      (       aM  [        R
                  " U R                  R                  SS2SS24   [        R                  " S5      5      (       + $ g)z;
Returns whether or not the current box is rotated at all.
rk   r   r.   F)r   r0   rK   rL   rA   rs   r   r'   s    r    is_orientedBox.is_oriented`  sY    
 ==116::{{4>>#;#;AaC1H#ErvvayQQQr"   c                 l    [        [        R                  " U R                  R                  5      5      nU$ )zP
Volume of the box Primitive.

Returns
--------
volume : float
  Volume of box.
)r   rA   prodrK   ro   r.  s     r    r   
Box.volumej  s&     rwwt~~5567r"   c                    [         R                  " S5        [        R                  " U R                  R
                  U R                  R                  S9nU R                  R                  R                  UR                  R                  5        UR                  U R                  S'   UR                  U R                  S'   UR                  U R                  S'   g )Nzcreating mesh for Box primitiver:  r;   r+   r?   )r   r   r   r?  rK   ro   rL   r   cacherU   r;   r+   r?   )r   r?  s     r    r1   Box._create_meshw  s    		34llNN**dnn6N6N
 	  !1!12"%,,J"yyG&)&6&6N#r"   c                 l    SSK Jn  U" U R                  R                  U R                  R                  S9$ )z
Return a Path3D containing the outline of the box.

Returns
-----------
outline : trimesh.path.Path3D
  Outline of box primitive
r   )box_outliner:  )path.creationr\  rK   ro   rL   )r   r\  s     r    
as_outlineBox.as_outline  s/     	/ NN**dnn6N6N
 	
r"   r  )NNNT)NN)r&   r   r   r   r   rP   r   rL   rG  rP  rS  r   r   r1   r^  r   r   r   s   @r    rw   rw     sd    '
R
" ( (*!F   
 
	7
 
r"   rw   c            	          ^  \ rS rSr     SS\\   S\S\S\4U 4S jjjr\	S 5       r
\	S 5       r\	S	 5       r\S
 5       r\S 5       r\	S 5       rS rSS jrS rS rSrU =r$ )	Extrusioni  rL   rm   r   	mid_planec           	         > SSK Jn  [        TU ]  5         U" SS/5      R	                  S5      [
        R                  " S5      SSS.n[        U UUUUUS.US9U l        g	)
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   )Pointrl   r   F)polygonrL   rm   rb  )rL   re  rm   rb  r   N)	shapely.geometryrd  r   r   r   rA   r   r   rK   )	r   re  rL   rm   r   rb  rd  r   r   s	           r    r   Extrusion.__init__  so    0 	+ 	 aV}++C0	
 -&" &	 

r"   c                     [        U R                  R                  U R                  R                  R                  -  5      nXR                  R                  R
                  S-  -  nU$ )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   )r|   rK   rm   re  lengthr   r+  s     r    r   Extrusion.area  sO     4>>((4>>+A+A+H+HHI&&++a//r"   c                     [        U R                  R                  R                  U R                  R                  -  5      nU$ )z
The volume of the Extrusion primitive.
Calculated from polygon and height to avoid mesh creation.

Returns
----------
volume : float
  Volume of 3D extrusion
)r|   rK   re  r   rm   r.  s     r    r   Extrusion.volume  s2     T^^++004>>3H3HHIr"   c                     [         R                  " U R                  R                  SS2SS24   SS[         R                  " U R                  R
                  5      /5      nU$ )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.           )rA   r   rK   rL   signrm   )r   r   s     r    r   Extrusion.direction  sT     FFNN$$RaR!V,sCAVAV9W.X
	 r"   c                 <    U R                   R                  SS2S4   $ )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.   rJ   r'   s    r    originExtrusion.origin  s!     ~~''A..r"   c                 .    U R                   R                  $ r   rJ   r'   s    r    rL   Extrusion.transform  r  r"   c                    SSK Jn  UR                  U R                  R                  R
                  R                  5      u  p#[        R                  " U[        U R                  R                  5      5      n[        R                  R                  [        R                  " U5      5      nU R                  R                  S-  US'   [        R                  " U R                  R                   U5      n[#        XdSS9$ )Nr   )r"  r   r9  F)rL   ro   r   ) r"  oriented_bounds_2DrK   re  exteriorcoordsrA   appendr|   rm   ru   invr   planar_matrix_to_3Dr   rL   rw   )r   r"  	to_originr?  ro   
rotation_Zto_3Ds          r    r&  Extrusion.bounding_box_oriented  s     	  224>>3I3I3R3R3Y3YZ	))CT^^%:%:!;<YY]]2#9#9)#DE
>>0036
4t~~//<UUCCr"   c                     [        U5      n[        R                  " S5      nXS'   [        R                  " U R                  R
                  R                  5       UR                  5       5      nX0R                  l        g)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   r9  N)r   rA   r   r   rK   rL   rX   )r   r   translationnew_transforms       r    slideExtrusion.slide  sX     ?ffQi$Dt~~77<<>@P@P@RS#0 r"   c                    [        U5      nUc  UnU R                  R                  nU[        R                  " U5      S-  U-  -  n[        U 5      " SU R                  R                  R                  5       U R                  R                  R                  U5      US.UD6nUR                  [        R                  " U5      * U-  5        U$ )az  
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   )rL   re  rm   rT   )r   rK   rm   rA   ro  r%   rL   rX   re  r   r  )r   r   distance_heightr]   rm   r   s         r    r   Extrusion.buffer)  s    & ?"&O &&"''&/C'/99 : 
nn..335NN**11(;
 	
 	'/9:r"   c                     SU R                   R                  R                  U R                   R                  R	                  5       [        U R                   R                  5      S.$ )z
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)rS   re  rL   rm   )rK   re  wktrL   r   r   rm   r'   s    r    rP   Extrusion.to_dictT  sL      ~~--111188:DNN112	
 	
r"   c                    [         R                  " S5        [        R                  " U R                  R
                  U R                  R                  U R                  R                  U R                  R                  S9n[        R                  (       a  UR                  S:  a  [        S5      eUR                  U R                  S'   UR                  U R                  S'   g )Nz%creating mesh for Extrusion primitive)re  rm   rL   rb  rn  zmatrix inverted mesh!r;   r+   )r   r   r   extrude_polygonrK   re  rm   rL   rb  r   strictr   r7   r;   r   r+   r   s     r    r1   Extrusion._create_meshf  s    		9:''NN**>>((nn..nn..	
 ::$+++455 #'--J#zzGr"   r  )NNrl   TFr   )r&   r   r   r   r   r   r   r6  r   r   r   r   r   r   rr  rL   r&  r  r   rP   r1   r   r   r   s   @r    ra  ra    s     )-.
 I&.
 	.

 .
 .
 .
`  "      
/ 
/ ( ( D D 1 )V
$* *r"   ra  )#r   r   numpyrA   rw  r   r   r   r   r   r	   r   baser
   cachingr   	constantsr   r   typedr   r   r   r   r   rt   flags	writeabler   r   rx   ry   rz   rw   ra  rT   r"   r    <module>r     s      8 8 #  $  7 7 FF1I	!	 ND NDb] ]@]8y ]8@j8i j8ZM8Y M8`h
) h
Vb*	 b*r"   