
    BPc>                     x   d Z ddlZddlmZmZmZmZmZmZ ddl	Z	ddl
mZ ddl	mZmZ ddlmZmZ ddlmZ 	 ddlZn	#  dZY nxY wd Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Z G d de           Z! G d de           Z" G d de	j#                  Z$e%dk    r e$            &                                 dS dS )as  
This extension draws 3d objects from a Wavefront .obj 3D file stored in a local folder
Many settings for appearance, lighting, rotation, etc are available.

                              ^y
                              |
        __--``|               |_--``|     __--
  __--``      |         __--``|     |_--``
 |       z    |        |      |_--``|
 |       <----|--------|-----_0-----|----------------
 |            |        |_--`` |     |
 |      __--``     <-``|      |_--``
 |__--``           x   |__--``|
  IMAGE PLANE           SCENE|
                              |

 Vertices are given as "v" followed by three numbers (x,y,z).
 All files need a vertex list
 v  x.xxx   y.yyy   z.zzz

 Faces are given by a list of vertices
 (vertex 1 is the first in the list above, 2 the second, etc):
 f  1   2   3

 Edges are given by a list of vertices. These will be broken down
 into adjacent pairs automatically.
 l  1   2   3

 Faces are rendered according to the painter's algorithm and perhaps
 back-face culling, if selected. The parameter to sort the faces by
 is user-selectable between max, min and average z-value of the vertices
    N)acoscosfloorpisinsqrt)pairwise)GroupCircle)MoveLine)inkex_gettextc           	          |                     t          t          |          t          |          t          |                               }dt          |          |d|_        ||_        dS )zDraw an SVG circle)cxcyr#000000)strokestroke-widthfillN)addr   strstylelabel)r   r   r   widthr   nameparentcircles           //usr/share/inkscape/extensions/polyhedron_3d.pydraw_circler    D   sV    ZZ#b''c"ggQ@@@AAF'UTRRFLFLLL    c                     |                     t          j                              }dt          |          ddd|_        |                    d|           t          | |          t          ||          g|_        d S )Nr   noneround)r   r   r   zstroke-linecapzinkscape:label)	r   inkexPathElementr   r   setr   r   path)x1y1x2y2r   r   r   elems           r   	draw_liner.   K   ss    ::e'))**DE

!	 DJ 	HHt$$$b"tB||,DIIIr!   c           	      @   dt          |j                  |j        |j        |j        |j        d}t          j                    }|D ]}|sC|                    t          | |dz
           d         | |dz
           d                               G|                    t          | |dz
           d         | |dz
           d                               |                                 |                    t          j                              }||_        ||_        ||_        dS )zDraw polygoner   )r   r   zstroke-linejoinzstroke-opacityr   zfill-opacity   r   N)r   thlinejoins_opacr   f_opacr%   Pathappendr   r   closer   r&   r   r   r(   )	ptsfacestr   r   r   r(   facetpolys	            r   	draw_polyr=   W   s    BE

;)	 E :<<D E E 	EKKS^A.UQY1B0BCCDDDDKKS^A.UQY1B0BCCDDDDJJLLL::e'))**DDJDJDIIIr!   c           
      >   | D ]}||d         dz
           dd         }||d         dz
           dd         }dt          |d                   z   dz   t          |d                   z   }t          |d         |d          |d         |d          |j        ||           d S )Nr   r0      Edge-)r   r.   r1   )	edge_listr8   r:   r   edgept_1pt_2r   s           r   
draw_edgesrF   o   s     M M47Q;!$47Q;!$DG$s*Sa\\9$q'DG8T!WtAwhtVLLLL	M Mr!   c           
          | D ]s}|r$t          ||d         t          z            |_        nt          |d          |_        |d         }t          ||j        |         |dt          |          z   |           td S )Nr0      zFace:)get_darkened_colourr   r   r=   fcer   )	
faces_datar8   objshadingfill_colr:   r   r9   face_nos	            r   
draw_facesrP   w   s     	M 	M 	7)$q'B, BGG *(A66BGq'#sww'Ws7||-CVLLLL	M 	Mr!   c                     ddt          || d         z            z  z   dt          || d         z            z  z   dt          || d         z            z  z   S )z<return a hex triplet of colour, reduced in lightness 0.0-1.0#z%02Xr   r0   r?   )r   )rgbfactors     r   rI   rI      se     	
5#a&))
)	*
5#a&))
)	* 5#a&))
)	*r!   c                    | j         t          d| j        z            z   dz   | j        z   t          d| j        z            z   dz   | j        z   t          d| j        z            z   dz   | j         z   t          d| j        z            z   dz   | j        z   t          d| j        z            z   dz   | j        z   t          d| j	        z            z   S )z[makes a string recording the axes and angles of each rotation, so an object can be repeatedz%.2f:)
r1_axr   r1_angr2_axr2_angr3_axr3_angr4_angr5_angr6_ang)optionss    r   make_rotation_logra      s    	
fw~%
&
&	'
	 -	 fw~%
&
&		'
 	 -	 fw~%
&
&	' 	 -		 fw~%
&
&
	' 	 -	 fw~%
&
&	' 	 -	  fw~%
&
&!	'r!   c                 t    t          t          j        | |                     }t          j        |           |z  S )zEreturn the unit vector pointing in the same direction as the argument)r   numpydotarray)vectorlengths     r   	normaliserh      s0    %)FF++,,F;v''r!   c           	      d   t          j        t          j        | |d         dz
                     t          j        | |d         dz
                     z
  t          j        | |d         dz
                     t          j        | |d         dz
                     z
                                            S )zRnormal vector for the plane passing though the first three elements of face of ptsr   r0   r?   )rc   crossre   flattenr8   r9   s     r   
get_normalrm      s    ;	Sa1%	&	&Sa15E)F)F	F	Sa1%	&	&Sa15E)F)F	F  giir!   c                 N    |rdnd}|t          t          | |                    z  S )z}
    Returns the unit normal for the plane passing through the
    first three points of face, taking account of winding
    r0   )rh   rm   )r8   r9   cw_woundwindings       r   get_unit_normalrr      s/     #bb!GYz#t445555r!   c           	      L   |dk    rUt          j        g ddt          |          t          |           gdt          |          t          |          gg          }n|dk    rUt          j        t          |          dt          |          gg dt          |           dt          |          gg          }nZ|dk    rTt          j        t          |          t          |           dgt          |          t          |          dgg dg          }t          j        ||           S )z)choose the correct rotation matrix to usex)r0   r   r   r   y)r   r0   r   z)r   r   r0   )rc   re   r   r   matmul)matrixradsaxis	trans_mats       r   rotater|      s   s{{KYYCIID		z2QD		3t994MN
 
		 
K$iiCII&			SYYJ3t993MN
 
		 
K$ii#d))Q'#d))SYY)BIIIN
 
	 <	6***r!   c                       e Zd Zd ZdS )Stylec                     |j         | _         d| _        d| _        d| _        t	          |j        dz            | _        t	          |j        dz            | _        d| _        d| _        d S )Nz#ff0000r   r?         Y@r$   )	r1   r   colr   r   r4   r3   linecapr2   )selfr`   s     r   __init__zStyle.__init__   s^    *	'.5011'.5011r!   N)__name__
__module____qualname__r    r!   r   r~   r~      s#                 r!   r~   c                   t    e Zd ZdZ ed           Zd Zd Zd Ze	e
fd            Zd Zd Zd	 Zd
 Zd ZdS )WavefrontObjzQWavefront based 3d object defined by the vertices and the faces (eg a polyhedron)c                 8    | j                             dd           S )Nr   )metaget)r   s    r   <lambda>zWavefrontObj.<lambda>   s    vt!<!< r!   c                     dt           j                            |                              dd          d         i| _        g | _        g | _        g | _        |                     |           d S )Nr   .r0   r   )	osr(   basenamersplitr   vtxedgrJ   _parse_file)r   filenames     r   r   zWavefrontObj.__init__   sb    RW--h77>>sAFFqIJ	"""""r!   c                 N   t           j                            |          s/t          t	          d                              |                    t          |d          5 }|D ])}|                     |                                           *	 d d d            d S # 1 swxY w Y   d S )Nz#Can't find wavefront object file {}r   )	r   r(   isfileIOError_formatopen_parse_linestrip)r   r   fhllines       r   r   zWavefrontObj._parse_file   s    w~~h'' 	U!ABBII(SSTTT(C   	/C / /  ..../	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/s   -BB!Bc                 D   |                     d          r=d|v r7|                    dd          \  }}|| j        |                                <   d S d S |rI|                    d d          \  }}d|z   }t	          | |          r t          | |          |           d S d S d S )NrR   rV   r0   add_)
startswithsplitr   lowerhasattrgetattr)r   r   r   valuekind	kind_names         r   r   zWavefrontObj._parse_line   s    ??3 	/d{{"jja00e*/	$**,,''' {  	/::dA..LT4ItY'' /(i((.....		/ 	// /r!   c                 D    fd|                                  D             S )Nc                 X    g | ]&} |                     d           d                   'S )/r   r   ).0vtyps     r   
<listcomp>z/WavefrontObj._parse_numbers.<locals>.<listcomp>   s1    ;;;AGGCLLO$$;;;r!   r   )r   r   s    `r   _parse_numberszWavefrontObj._parse_numbers   s'     <;;;djjll;;;;r!   c                     |                      |t                    }t          |          dk    r| j                            |           dS dS )zAdd vertex from parsed linerH   N)r   floatlenr   r6   )r   r   vertexs      r   add_vzWavefrontObj.add_v   sJ    $$T511v;;!HOOF##### r!   c                     |                      |t                    }t          |          dk    r+| j                            t          |d                     dS dS )zAdd line from parsed liner0   F)startN)r   intr   r   extendr	   r   r   vtxlists      r   add_lzWavefrontObj.add_l  sW    %%dC00w<<!HOOHWE:::;;;;; r!   c                     |                      |t                    }t          |          dk    r| j                            |           dS dS )zAdd face from parsed liner?   N)r   r   r   rJ   r6   r   s      r   add_fzWavefrontObj.add_f  sJ    %%dC00w<<!HOOG$$$$$ r!   c           	          g }| j         D ]X}|                    t          j        |t          j        |          j                  j                                                   Y|S )z/translate vertex points according to the matrix)r   r6   rc   rw   re   Ttolist)r   r{   transformed_ptsr   s       r   get_transformed_ptsz WavefrontObj.get_transformed_pts  sh    8 	 	C""iS)9)9);<<?FFHH    r!   c                    g }| j         D ]T}t          |          D ]B\  }}|                    t          |||dz   t	          |          z           g                     CUd t          t          d |D                                 D             S )z:make an edge vertex list from an existing face vertex listr0   c                 ,    g | ]}t          |          S r   )listr   rt   s     r   r   z.WavefrontObj.get_edge_list.<locals>.<listcomp>"  s    JJJAQJJJr!   c              3   4   K   | ]}t          |          V  d S )N)tupler   s     r   	<genexpr>z-WavefrontObj.get_edge_list.<locals>.<genexpr>"  s(      +H+HE!HH+H+H+H+H+H+Hr!   )rJ   	enumerater6   sortedr   r'   )r   rB   r9   jrC   s        r   get_edge_listzWavefrontObj.get_edge_list  s    	H 	L 	LD$T?? L L4  tQUc$ii4G/H(I!J!JKKKKL KJ+H+Hi+H+H+H(H(H!I!IJJJJr!   N)r   r   r   __doc__propertyr   r   r   r   staticmethodr   r   r   r   r   r   r   r   r!   r   r   r      s        [[8<<==D# # #/ / /	/ 	/ 	/ !$ < < < \<$ $ $< < <% % %  K K K K Kr!   r   c                   x    e Zd ZdZd Zd Zd Zd Zd Zd Z	e
d             Ze
d	             Ze
d
             ZdS )Poly3Dz4Generate a polyhedron from a wavefront 3d model filec                    |                     dd           |                     dd           |                     dd           |                     dt          j        d	
           |                     dd           |                     dd           |                     dd           |                     dd           |                     dd           |                     dd           |                     dd           |                     dt          d
           |                     dt          d
           |                     dt          d
           |                     dt          d
           |                     dt          d
           |                     dt          d
           |                     dt          d
           |                     d|                     d                     |                     d t          j        d!
           |                     d"t
          d#
           |                     d$t
          d%
           |                     d&t
          d%
           |                     d't
          d(
           |                     d)t
          d(
           |                     d*t          d+
           |                     d,t          d-
           |                     d.t          d-
           |                     d/t          d0
           |                     d1t          j        d	
           |                     d2|                     d3          | j        
           d S )4Nz--tabcommon)defaultz--objcubez--spec_filezgreat_rhombicuboct.objz
--cw_woundF)typer   z--typer9   z--r1_axrt   z--r2_axz--r3_axz--r4_axz--r5_axz--r6_axz--r1_angg        z--r2_angz--r3_angz--r4_angz--r5_angz--r6_angz--sclr   z--showgen)r   z--shadeTz--f_r   z--f_gr   z--f_bz--f_opacd   z--s_opacz--thr?   z--lv_xr0   z--lv_yz--lv_zz--backz--z_sortz_sort)add_argumentr%   Booleanr   
arg_methodr   
z_sort_min)r   parss     r   add_argumentszPoly3D.add_arguments(  sg   '8444 	'6222-1IJJJ,U]EJJJ(F333)S111)S111)S111)S111)S111)S111*5#>>>*5#>>>*5#>>>*5#>>>*5#>>>*5#>>>'u===()?)?@@@)%-FFF'S999'Q777'Q777*3<<<*3<<<&ua888(:::(:::(;;;(FFFT__X66 	 	
 	
 	
 	
 	
r!   c                     d}| j         j        dk    r| j         j        }n| j         j        dz   }|                                 }t          j                            |d|          S )z"Get the filename for the spec file 	from_filez.objPoly3DObjects)r`   rL   	spec_fileext_pathr   r(   join)r   r   moddirs      r   get_filenamezPoly3D.get_filenameO  sW    <{**<)DD<#f,Dw||FOT:::r!   c                 n   t           !t          j        t          d                    | j        }t          |                                           }| j                            d          }t          |          }t          j        |j        dz   t          |          z             }| j        j        j        \  }}|j                            ||           |j                            |           t          j        dt(                    }t+          dd          D ]d}	t-          |d                    |	                    }
t-          |d                    |	                    t0          z  d	z  }t3          |||
          }e||j        z  }|                    |          }|                    ||||           |S )
Nz*This extension requires the numpy library.1pxrV   rH   r0      zr{}_axzr{}_ang   )rc   r%   AbortExtensionr   r`   r   r   svgunittouur~   r
   newr   ra   	namedviewcenter	transformadd_translate	add_scaleidentityr   ranger   r   r   r|   sclr   show)r   sorL   scaler:   r<   pos_xpos_yr{   irz   angler   s                r   generatezPoly3D.generateY  s   =&q)U'V'VWWW\4,,..//!!%((2YY yC*;B*?*??@@+2$$UE222  ''' N1e,,	q! 	7 	7A2xq1122DB	 0 0 3 344r9C?Ey%66II&	 11)<<
R///r!   c                     t          |          D ]@\  }}t          |j        |d         |d         |j        ddt	          |          z   |           AdS )zGenerate Vertexr   r0   r   PointN)r   r    r   r1   r   )r   rL   r:   r<   r   r  r8   s          r   gen_vtxzPoly3D.gen_vtxw  s`    00 	X 	XFAsc!fc!fbeY#a&&@PRVWWWW	X 	Xr!   c                 n    |j         }|j        r|                                }t          ||||           dS )zGenerate edgesN)r   rJ   r   rF   )r   rL   r:   r<   r   rB   s         r   gen_edgzPoly3D.gen_edg|  s@     G	7 	,))++I9or488888r!   c           	      ^   | j         }|j        |j        |j        f}t	          |j        |j         |j        f          }|j        rg }t          |j                  D ]\  }	}
t          ||
|j                  }t          t          j        ||                    }|                    ||
          }|j        s|d         dk    r|                    ||||	f           |                    d            t'          ||||j        |||           dS t+          j        t/          d                    )zGenerate facer?   r   c                     | d         S )Nr   r   )rt   s    r   r   z Poly3D.gen_fce.<locals>.<lambda>  s
    ad r!   )keyzFace data not found.N)r`   f_rf_gf_brh   lv_xlv_ylv_zrJ   r   rr   rp   r   rc   rd   r   backr6   sortrP   shader%   r   r   )r   rL   r:   r<   r   r  rN   lightingz_listr  r9   normr  z_sort_params                 r   gen_fcezPoly3D.gen_fce  s<   \FBFBF+bgx9::7 	BF$SW-- B B4&bkJJUYtX6677!yy$?? 7 Bd1gkk MM<a"@AAAKK"N     vRXxTRRRRR &q)?'@'@AAAr!   c                 :     t           fd|D                       S )z4returns the largest z_value of any point in the facec                 2    g | ]}|d z
           d         S r0   r?   r   r   r;   r8   s     r   r   z%Poly3D.z_sort_max.<locals>.<listcomp>  &    888%C	N1%888r!   )maxrl   s   ` r   
z_sort_maxzPoly3D.z_sort_max  (     88884888999r!   c                 :     t           fd|D                       S )z5returns the smallest z_value of any point in the facec                 2    g | ]}|d z
           d         S r!  r   r"  s     r   r   z%Poly3D.z_sort_min.<locals>.<listcomp>  r#  r!   )minrl   s   ` r   r   zPoly3D.z_sort_min  r&  r!   c                 Z     t           fd|D                       t          |          z  S )z5returns the centroid z_value of any point in the facec                 2    g | ]}|d z
           d         S r!  r   r"  s     r   r   z&Poly3D.z_sort_cent.<locals>.<listcomp>  r#  r!   )sumr   rl   s   ` r   z_sort_centzPoly3D.z_sort_cent  s3     8888488899CIIEEr!   N)r   r   r   r   r   r   r  r  r  r  r   r%  r   r-  r   r!   r   r   r   %  s        >>%
 %
 %
N; ; ;  <X X X
9 9 9B B B@ : : \: : : \: F F \F F Fr!   r   __main__)'r   r   mathr   r   r   r   r   r   r%   inkex.utilsr	   r
   r   inkex.pathsr   r   inkex.localizationr   r   rc   r    r.   r=   rF   rP   rI   ra   rh   rm   rr   r|   objectr~   r   GenerateExtensionr   r   runr   r!   r   <module>r6     sD  ( B 
			 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0                      " " " " " " " " 1 1 1 1 1 1LLLLEEE  	- 	- 	-  0M M M
M 
M 
M    .( ( (  6 6 6+ + +"	  	  	  	  	 F 	  	  	 HK HK HK HK HK6 HK HK HKVNF NF NF NF NFU$ NF NF NFb z
FHHLLNNNNN s	   = A