§
    â²âjš–  ã                   ó  — d Z ddlZddlZddlZddlmZ ddlmZ ddlZ	 ee
¦  «                             ¦   «         j        j        dz  ZdZdZdZd	„ Zd
„ Zdd„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdd„Zd„ Zedk    r e¦   «          dS dS )zÚ../report/index.html from ../report/degree_sweep.csv (rerun at any time: rows still being written are shown as they are).

    env -u PYTHONPATH .venv/bin/python ~/code/data/meshes/fcp_2810_partition/scripts/report.py
é    N)Údefaultdict)ÚPathÚreport)útracked-fitÚ100Ú24aä  
:root{--bg:#fafaf8;--fg:#1d1d1b;--mut:#6b6b66;--line:#ddd9d0;--acc:#2f6f8f;--bad:#b4442a;--good:#2e7d4f}
body{background:var(--bg);color:var(--fg);font:15px/1.5 system-ui,sans-serif;margin:0 auto;max-width:1180px;padding:24px 16px}
h1{font-size:26px;margin:0 0 4px}h2{font-size:19px;margin:36px 0 8px;border-bottom:1px solid var(--line);padding-bottom:4px}
h3{font-size:16px;margin:22px 0 6px}
.mut{color:var(--mut)}table{border-collapse:collapse;width:100%;font-variant-numeric:tabular-nums;font-size:12.5px}
th,td{padding:4px 7px;border-bottom:1px solid var(--line);text-align:right}th{background:#efece5}
td.l,th.l{text-align:left}td.bad{color:var(--bad);font-weight:600}td.good{color:var(--good);font-weight:600}
tr.base td{background:#f1efe9}.wrap{overflow-x:auto}code{background:#efece5;padding:1px 4px;border-radius:3px}
img{max-width:100%;border:1px solid var(--line);background:#fff;margin:6px 0}
.box{border-left:4px solid var(--acc);padding:6px 12px;background:#f1efe9;margin:10px 0}
u#  
<div class="box"><b>Question.</b> Keep <code>tracked-fit</code> (decision 22: tracking, the fit cut, the step rule that puts
the cut on the event) but cut only where a part really breaks (a ledge, a joint), and let a higher height degree follow the
rest. Step 1: the same rule against the degree cap, <code>M</code> and <code>KAPPA</code> (largest condition number of the
Chebyshev basis on a part's layer centres; at 1e2 the degree is at most 11 / 17 / 25 / 35 on 16 / 32 / 64 / 128 layers).
A higher cap lets one fit follow more, so the rule cuts less by itself. The SDF decode reads a part only at its layer
centres, so a higher degree cannot wobble between layers there. Meshes only (exact slices, no slicer noise), 128 layers,
up = +z, decoded on the SDF default at 128. (<code>tracked</code>, no cuts, is in the CSV but not shown: it is the old rule
and loses the joints.)</div>
<div class="box"><b>The 2x2</b> (below): the stored degree alone changes nothing (high basis on the default parts: 1.000 /
1.000 / 0.998 Chamfer); the cuts a high cap removes are what cost (default basis on those parts: 1.13 at every budget, normals
1.4-3.5 times; bowl_of 1.4, shoe 1.3-1.5, horse 1.2). Cuts removed by a higher degree are not the unneeded ones.</div>
<div class="box"><b>Step 1, so far.</b> A higher cap removes cuts (134 parts over the ten at the default, 121 at Îº 1e3, 108 at
Îº 1e4) at the same Chamfer at 6144 atoms, but worse at 256 / 1024 (up to 1.13 / 1.05 times) and with more normals over 30Â°
(up to 1.4 / 1.6 times). The renders show which cuts go.</div>
c                  ó¢   — t           dz  } |                      ¦   «         r0d„ t          j        |                      ¦   «         ¦  «        D ¦   «         ng S )Nzdegree_sweep.csvc                 ó*   — g | ]}|d          dk    ¯|‘ŒS )Úruler   © ©Ú.0Úrs     ú@/home/joao/code/data/meshes/fcp_2810_partition/scripts/report.pyú
<listcomp>zload.<locals>.<listcomp>/   s&   € ÐNÐNÐN�!°1°V´9ÀÒ3MÐ3MˆAÐ3MÐ3MÐ3Mó    )ÚREPORTÚexistsÚcsvÚ
DictReaderÚopen©Úps    r   Úloadr   -   sK   € ÝÐ#Ñ#€AØRS×RZÒRZÑR\ÔR\ÐdÐNÐN•s”~ a§f¢f¡h¤hÑ/Ô/ÐNÑNÔNÐNÐbdÐdr   c                 ó0   — | d         | d         | d         fS )Nr   ÚkappaÚMr   )r   s    r   Úcfgr   2   s   € ØˆVŒ9�a˜”j ! C¤&Ð(Ð(r   ç{®Gáz”?c                 ó2   — | d|z
  k     rdn| d|z   k    rdndS )Né   ÚgoodÚbadÚ r   )ÚratioÚtols     r   Úclsr'   6   s(   € Ø˜Q ™W’_�_ˆ6ˆ6°5¸1¸s¹7²?°?¨%¨%ÈÐJr   c                 ó†  ‡‡‡— t          t          ¦  «        }| D ](}||t          |¦  «        |d         f         |d         <   Œ)t          d„ | D ¦   «         d„ ¬¦  «        }d                     d„ |D ¦   «         ¦  «        d                     d„ |D ¦   «         ¦  «        z   }d	|› d
�g}|D �]ð}g d }	}dD ]ëŠ|D ]æ}
|                     ||
fi ¦  «        |                     t          |
fi ¦  «        cŠŠˆfd„‰D ¦   «         }|	€|n|	}	ˆˆˆfd„|D ¦   «         }|rEt          t          j	        t          j
        t          j        |¦  «        ¦  «        ¦  «        ¦  «        nt          j        }|                     d|t          k    rt          |¦  «        nd› d|d›d�¦  «         ŒçŒìt          |                     ||d         fi ¦  «                             ¦   «         ¦  «        }t#          d„ |D ¦   «         ¦  «        }t%          d„ |D ¦   «         d¬¦  «        }t#          d„ |D ¦   «         ¦  «        }|                     d|t          k    rdnd› d|d         › d|d         › d|d         › dt'          |¦  «        › d|› d|› dd                     |¦  «        › d|d›d �¦  «         �Œò|                     d!¦  «         d"                     |¦  «        S )#NÚatomsÚobjectc                 ó,   — h | ]}t          |¦  «        ’ŒS r   ©r   r   s     r   ú	<setcomp>zsummary.<locals>.<setcomp>>   s   € Ð+Ð+Ð+ •c˜!‘f”fÐ+Ð+Ð+r   c                 ól   — | d         dk    t          | d         ¦  «        t          | d         ¦  «        fS )Nr   r   r!   é   )ÚfloatÚint©Úcs    r   ú<lambda>zsummary.<locals>.<lambda>>   s6   € ¸A¸a¼DÀMÒ<QÕSXÐYZÐ[\ÔY]ÑS^ÔS^Õ`cÐdeÐfgÔdhÑ`iÔ`iÐ;j€ r   ©Úkeyr$   c              3   ó"   K  — | ]
}d |› d�V — ŒdS ©u   <th>Chamfer Ã—<br>ú</th>Nr   ©r   ÚTs     r   ú	<genexpr>zsummary.<locals>.<genexpr>?   s.   è è € ÐBÐB°QÐ0¨Ð0Ð0Ð0ÐBÐBÐBÐBÐBÐBr   c              3   ó"   K  — | ]
}d |› d�V — ŒdS ©u   <th>&gt;30Â° Ã—<br>r9   Nr   r:   s     r   r<   zsummary.<locals>.<genexpr>?   s0   è è € ÐL}ÐL}ÐpqÐMkÐcdÐMkÐMkÐMkÐL}ÐL}ÐL}ÐL}ÐL}ÐL}r   u{   <div class='wrap'><table><tr><th class='l'>rule</th><th>Îº</th><th>M</th><th>objects</th><th>parts</th><th>longest deg</th>z<th>encode s</th></tr>©ÚchamferÚn_over30c                 ó   •— g | ]}|‰v ¯|‘Œ	S r   r   )r   ÚoÚbases     €r   r   zsummary.<locals>.<listcomp>G   s   ø€ Ð6Ð6Ð6 ¨A°¨I¨I˜!¨I¨I¨Ir   c                 ó¼   •— g | ]X}t          ‰|         ‰         ¦  «        d k    ¯!t          ‰|         ‰         ¦  «        t          ‰|         ‰         ¦  «        z  ‘ŒYS ©r   ©r0   ©r   rC   rD   Úcurr6   s     €€€r   r   zsummary.<locals>.<listcomp>I   s_   ø€ ÐkÐkÐkÀAÕSXÐY]Ð^_ÔY`ÐadÔYeÑSfÔSfÐijÒSjÐSj•u˜S œV Cœ[Ñ)Ô)­E°$°q´'¸#´,Ñ,?Ô,?Ñ?ÐSjÐSjÐSjr   ú<td class='ú'>ú.3fú</td>éÿÿÿÿc              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS ©ÚpartsN©r1   r   s     r   r<   zsummary.<locals>.<genexpr>M   s,   è è € Ð0Ð0¨•C˜˜'œ
‘O”OÐ0Ð0Ð0Ð0Ð0Ð0r   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS )Úmax_degNrR   r   s     r   r<   zsummary.<locals>.<genexpr>N   s.   è è € Ð1Ð1¨•3�q˜”|Ñ$Ô$Ð1Ð1Ð1Ð1Ð1Ð1r   r   ©Údefaultc              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS )ÚsecondsNrG   r   s     r   r<   zsummary.<locals>.<genexpr>O   s.   è è € Ð2Ð2¨!•%˜˜)œÑ%Ô%Ð2Ð2Ð2Ð2Ð2Ð2r   ú<tr class='rD   ú'><td class='l'>ú	</td><td>r!   r/   ú<td>ú.2fú
</td></tr>ú</table></div>ú
)r   Údictr   ÚsortedÚjoinÚgetÚBASEr0   ÚnpÚexpÚmeanÚlogÚnanÚappendr'   ÚlistÚvaluesÚsumÚmaxÚlen)ÚrowsÚbudgetsÚbyr   ÚconfigsÚheadÚoutr3   ÚcellsÚobjsr;   ÚcommonÚratÚgÚrsrQ   ÚdegÚsecrD   rI   r6   s                     @@@r   Úsummaryr   :   s‚  øøø€ Ý	•TÑ	Ô	€BØð 0ð 0ˆØ./ˆ�3ˆq‰6Œ6�1�W”:ÐÔ˜q œ{Ñ+Ð+ÝÐ+Ð+ dÐ+Ñ+Ô+Ð1jÐ1jÐkÑkÔk€GØ�7Š7ÐBÐB¸'ÐBÑBÔBÑBÔBÀRÇWÂWÐL}ÐL}Ðu|ÐL}ÑL}ÔL}ÑE}ÔE}Ñ}€Dð?Ø"&ð?ð ?ð ?ð @€Càð oñ oˆØ˜$ˆtˆØ*ð 	Xð 	XˆCØð Xð X�ØŸFšF A q 6¨2Ñ.Ô.°·²½¸a°yÀ"Ñ0EÔ0E�	��TØ6Ð6Ð6Ð6 SÐ6Ñ6Ô6�Ø!% �v�v°4�ØkÐkÐkÐkÐkÐkÈÐkÑkÔk�Ø;>ÐJ•E�"œ&¥¤­¬°©¬Ñ!5Ô!5Ñ6Ô6Ñ7Ô7Ð7ÅBÄF�Ø—’ÐV°Q½$²Y°Y­3¨q©6¬6¨6ÀBÐVÐVÈ!ÐVÐVÐVÐVÑWÔWÐWÐWðXõ �"—&’&˜!˜W Rœ[Ð)¨2Ñ.Ô.×5Ò5Ñ7Ô7Ñ8Ô8ˆÝÐ0Ð0¨RÐ0Ñ0Ô0Ñ0Ô0ˆÝÐ1Ð1¨bÐ1Ñ1Ô1¸1Ð=Ñ=Ô=ˆÝÐ2Ð2¨rÐ2Ñ2Ô2Ñ2Ô2ˆØ�
Š
ð n¨1µª9¨9  ¸"ð nð nÈaÐPQÌdð nð nÐ]^Ð_`Ô]að nð nÐlmÐnoÔlpð nð nÝ˜b™'œ'ðnð nØ,1ðnð nØ<?ðnð nØFHÇgÂgÈeÁnÄnðnð nØZ]Ðmðnð nð nñ 	oô 	oð 	oñ 	oà‡J‚JÐÑ Ô Ð Ø�9Š9�S‰>Œ>Ðr   c                 óh  ‡‡— g }t                                d„ | D ¦   «         ¦  «        D �]ôŠˆfd„| D ¦   «         }d„ |D ¦   «         }|                     d‰› dt          j        ‰¦  «        › d�d                     d„ |D ¦   «         ¦  «        z   d                     d	„ |D ¦   «         ¦  «        z   d
z   |d         z   dz   ¦  «         t                                d„ |D ¦   «         ¦  «        D �]´Šˆfd„|D ¦   «         }t          t          |                     ¦   «         ¦  «        ¦  «        }g }dD ]Û}|D ]Ö}	|	|vr|                     d¦  «         Œt          ||	         |         ¦  «        |	|v rt          ||	         |         ¦  «        nt          j        }}
|                     |dk    r-d‰t          k    r|dk    rt          |
|z  ¦  «        nd› d|
d›d�n-d‰t          k    r|dk    rt          |
|z  d¦  «        nd› d|
d›d�¦  «         Œ×ŒÜ|d         |v r||d                  d         nd}|                     d‰t          k    rdnd› d‰d         › d‰d         › d‰d         › d|d         › d|d          › d|d!         › dd                     |¦  «        › d"|› d#�¦  «         �Œ¶|                     d$¦  «         t          t          d%z                       ‰› d&�¦  «        d'„ ¬(¦  «        D ]:}|                     d)|j        › d*t          j        |j        ¦  «        › d+�¦  «         Œ;�Œöd,                     |¦  «        S )-Nc              3   ó&   K  — | ]}|d          V — ŒdS ©r*   Nr   r   s     r   r<   zper_object.<locals>.<genexpr>X   s&   è è € Ð7Ð7¨Q˜Q˜xœ[Ð7Ð7Ð7Ð7Ð7Ð7r   c                 ó,   •— g | ]}|d          ‰k    ¯|‘ŒS )r*   r   )r   r   Úobjs     €r   r   zper_object.<locals>.<listcomp>Y   s'   ø€ Ð4Ð4Ð4�A  8¤°Ò!3Ð!3ˆaÐ!3Ð!3Ð!3r   c                 óP   — i | ]#}t          |¦  «        t          k    ¯|d          |“Œ$S ©r)   )r   re   r   s     r   ú
<dictcomp>zper_object.<locals>.<dictcomp>Z   s)   € Ð<Ð<Ð< !­S°©V¬Vµtª^¨^��'”
˜A¨^¨^¨^r   z<h3 id='rK   u„   </h3><div class='wrap'><table><tr><th class='l'>rule</th><th>Îº</th><th>M</th><th>parts</th><th>longest deg</th><th>mean length</th>r$   c              3   ó"   K  — | ]
}d |› d�V — ŒdS )ú<th>Chamfer %<br>r9   Nr   r:   s     r   r<   zper_object.<locals>.<genexpr>]   s.   è è € ÐKÐK¸aÐ9°Ð9Ð9Ð9ÐKÐKÐKÐKÐKÐKr   c              3   ó"   K  — | ]
}d |› d�V — ŒdS )u   <th>&gt;30Â° %<br>r9   Nr   r:   s     r   r<   zper_object.<locals>.<genexpr>^   s.   è è € ÐLÐL¸qÐ:°!Ð:Ð:Ð:ÐLÐLÐLÐLÐLÐLr   z<th>p95 %<br>rN   z
</th></tr>c              3   ó4   K  — | ]}t          |¦  «        V — Œd S ©Nr,   r   s     r   r<   zper_object.<locals>.<genexpr>_   s(   è è € Ð2Ð2¨!�s 1™vœvÐ2Ð2Ð2Ð2Ð2Ð2r   c                 óH   •— i | ]}t          |¦  «        ‰k    ¯|d          |“ŒS r†   r,   )r   r   r3   s     €r   r‡   zper_object.<locals>.<dictcomp>`   s*   ø€ Ð;Ð;Ð; A­s°1©v¬v¸ª{¨{�!�G”*˜a¨{¨{¨{r   r?   z	<td></td>r@   rJ   r   ú.4frM   çš™™™™™©?r]   Úp95rY   rD   rZ   r[   r!   r/   rQ   rT   Úmean_lenr\   r^   r_   Úimgz_*.pngc                 ó"   — d| j         v| j         fS )Nr   )Únamer   s    r   r4   zper_object.<locals>.<lambda>o   s   € ÐQ^ÐfgÔflÐQlÐopÔouÐOv€ r   r5   ú<img src='img/ú' alt='ú' loading='lazy'>r`   )ra   Úfromkeysrk   ÚhtmlÚescaperc   ÚnextÚiterrm   r0   rf   rj   re   r'   rb   r   Úglobr”   Ústem)rq   rr   rv   r|   rD   ÚatÚr0rw   r6   r;   ÚvÚbr�   Úpngr3   r„   s                 @@r   Ú
per_objectr¤   V   s`  øø€ Ø
€CÝ�}Š}Ð7Ð7°$Ð7Ñ7Ô7Ñ7Ô7ð cñ cˆØ4Ð4Ð4Ð4˜Ð4Ñ4Ô4ˆØ<Ð< rÐ<Ñ<Ô<ˆØ�
Š
ð W˜cð Wð W¥T¤[°Ñ%5Ô%5ð Wð Wð Wà—W’WÐKÐKÀ7ÐKÑKÔKÑKÔKñLð —W’WÐLÐLÀGÐLÑLÔLÑLÔLñMð P_ñ_ð biÐikÔalñmð p|ñ|ñ 	}ô 	}ð 	}õ —’Ð2Ð2¨rÐ2Ñ2Ô2Ñ2Ô2ð 	Fñ 	FˆAØ;Ð;Ð;Ð;¨Ð;Ñ;Ô;ˆBÝ•d˜2Ÿ9š9™;œ;Ñ'Ô'Ñ(Ô(ˆBØˆEØ.ð uð u�Ø ð uð u�AØ �{�{ØŸš [Ñ1Ô1Ð1Ø Ý   A¤ s¤Ñ,Ô,ÀQÈ$ÀYÀY­e°D¸´G¸C´LÑ.AÔ.AÐ.AÕTVÔTZ�q�AØ—L’LÐloÐs|Òl|Ðl|Ð!h¸QÅ$ºY¸YÈ1ÈqÊ5È5­s°1°q±5©z¬z¨zÐVXÐ!hÐ!hÐ\]Ð!hÐ!hÐ!hÐ!hÐ!hØ&sÈÍTÊ	È	ÐVWÐZ[ÒV[ÐV[µC¸¸A¹¸tÑ4DÔ4DÐ4DÐacÐ&sÐ&sÐghÐ&sÐ&sÐ&sÐ&sñuô uð uð uðuð -4°B¬K¸2Ð,=Ð,=�"�W˜R”[”/ %Ô(Ð(À2ˆCØ�JŠJð E¨qµDªy¨y V V¸bð Eð EÐRSÐTUÔRVð Eð EÐabÐcdÔaeð Eð EÐpqÐrsÔptð Eð EØ  œkðEð EØ46°y´MðEð EØLNÈzÌNðEð EØac×ahÒahÐinÑaoÔaoðEð EØuxðEð Eð Eñ Fô Fð Fñ Fà�
Š
Ð#Ñ$Ô$Ð$Ý�6 E™>×/Ò/°3°°°Ñ?Ô?ÐEvÐEvÐwÑwÔwð 	cð 	cˆCØ�JŠJÐa¨¬ÐaÐa½¼ÀSÄXÑ9NÔ9NÐaÐaÐaÑbÔbÐbÐbñ	cà�9Š9�S‰>Œ>Ðr   c                  óh  ‡‡‡‡‡‡‡— t           dz  } |                      ¦   «         sdS t          t          j        |                      ¦   «         ¦  «        ¦  «        }t          d„ |D ¦   «         t          ¬¦  «        Št          t          ¦  «        Š|D ](}|‰|d         |d         |d         f         |d         <   Œ)d	d
 
                    d„ ‰D ¦   «         ¦  «        z   d
 
                    d„ ‰D ¦   «         ¦  «        z   dz   g}dD �]—}dD �]�}g }dD ]ÑŠ‰D ]Ì}‰                     |||fi ¦  «        ‰                     dd|fi ¦  «        cŠŠˆˆˆfd„‰D ¦   «         }|rEt          t          j        t          j        t          j        |¦  «        ¦  «        ¦  «        ¦  «        nt          j        Š|                     d||fdk    rt'          ‰¦  «        nd
› d‰d›d�¦  «         ŒÍŒÒt          ‰                     ||‰d         fi ¦  «                             ¦   «         ¦  «        }	|                     d||fdk    rdnd
› d|dk    rdnd› d|dk    rdnd› d t+          |	¦  «        › d t-          d!„ |	D ¦   «         ¦  «        › dd
 
                    |¦  «        › d�¦  «         �Œ’�Œ™|                     d"¦  «         d#d
 
                    d$„ dD ¦   «         ¦  «        z   d
 
                    ˆfd%„dD ¦   «         ¦  «        z   dz   g}
t                               d&„ |D ¦   «         ¦  «        D ]jŠˆˆfd'„Š|
                     d(‰› d�d
 
                    ˆˆfd)„dD ¦   «         ¦  «        z   d
 
                    ˆˆfd*„dD ¦   «         ¦  «        z   dz   ¦  «         Œk|
                     d"¦  «         d+ 
                    ||
z   ¦  «        S ),ze../report/split_2x2.csv: the cut decision and the stored basis each at the default cap or a high one.zsplit_2x2.csvú<p>not run yet</p>c                 ó   — h | ]
}|d          ’ŒS r†   r   r   s     r   r-   ztwo_by_two.<locals>.<setcomp>z   ó   € Ð/Ð/Ð/ Q�a˜”jÐ/Ð/Ð/r   r5   ÚcutÚbasisr)   r*   zy<div class='wrap'><table><tr><th class='l'>cut decision</th><th class='l'>stored basis</th><th>objects</th><th>parts</th>r$   c              3   ó"   K  — | ]
}d |› d�V — ŒdS r8   r   r:   s     r   r<   ztwo_by_two.<locals>.<genexpr>   ó.   è è € ÐDÐD°qÐ2¨!Ð2Ð2Ð2ÐDÐDÐDÐDÐDÐDr   c              3   ó"   K  — | ]
}d |› d�V — ŒdS r>   r   r:   s     r   r<   ztwo_by_two.<locals>.<genexpr>   ó0   è è € ÐNÐNÐrsÐOmÐefÐOmÐOmÐOmÐNÐNÐNÐNÐNÐNr   ú</tr>©ÚloÚhir?   r±   c                 óÄ   •— g | ]\}|‰v ¯t          ‰|         ‰         ¦  «        d k    ¯%t          ‰|         ‰         ¦  «        t          ‰|         ‰         ¦  «        z  ‘Œ]S rF   rG   rH   s     €€€r   r   ztwo_by_two.<locals>.<listcomp>†   sk   ø€ ÐzÐzÐzÈÐTUÐY]ÐT]ÐT]ÕbgÐhlÐmnÔhoÐpsÔhtÑbuÔbuÐxyÒbyÐby�5  Q¤¨¤Ñ-Ô-µ°d¸1´g¸c´lÑ0CÔ0CÑCÐbyÐbyÐbyr   rJ   )r±   r±   rK   rL   rM   rN   rY   rD   rZ   u   default (Îº 1e2, M 24)u   high (Îº 1e4, M 50)z</td><td class='l'>rV   Úhighr[   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS rP   rR   r   s     r   r<   ztwo_by_two.<locals>.<genexpr>Œ   s,   è è € Ð!>Ð!>°a¥# a¨¤j¡/¤/Ð!>Ð!>Ð!>Ð!>Ð!>Ð!>r   r_   z6<div class='wrap'><table><tr><th class='l'>object</th>c              3   ó"   K  — | ]
}d |› d�V — ŒdS )z<th>parts<br>cut r9   Nr   ©r   r3   s     r   r<   ztwo_by_two.<locals>.<genexpr>Ž   sG   è è € ð N<ð N<Ø)*Ð$˜AÐ$Ð$Ð$ðN<ð N<ð N<ð N<ð N<ð N<r   c           
   3   ó`   •K  — | ](}d D ]#}‰d         ‰d         fD ]}d|› d|› d|› d�V — ŒŒ$Œ)dS )r°   r   rN   r‰   ú/ú r9   Nr   )r   r3   r¢   r;   rr   s       €r   r<   ztwo_by_two.<locals>.<genexpr>�   s§   øè è € ð F}ð F}Ø12ÈLðF}ð F}ØGHÐcjÐklÔcmÐovÐwyÔozÐb{ðF}ð F}Ø]^Ð,˜AÐ,Ð, Ð,Ð, AÐ,Ð,Ð,ðF}ð F}ð F}ð F}ð F}ð F}ð F}ð F}r   c              3   ó&   K  — | ]}|d          V — ŒdS r‚   r   r   s     r   r<   ztwo_by_two.<locals>.<genexpr>‘   ó&   è è € Ð5Ð5¨1˜1˜Xœ;Ð5Ð5Ð5Ð5Ð5Ð5r   c                 ó†   •— ‰                      | ||fi ¦  «                              ‰i ¦  «                              |d¦  «        S )Nr$   ©rd   )r3   r¢   r;   Úkrs   rC   s       €€r   r4   ztwo_by_two.<locals>.<lambda>’   s;   ø€ ˜rŸvšv q¨!¨Q i°Ñ4Ô4×8Ò8¸¸BÑ?Ô?×CÒCÀAÀrÑJÔJ€ r   ú<tr><td class='l'>c              3   óH   •K  — | ]}d  ‰|d‰d         d¦  «        › d�V — ŒdS )r\   r±   rN   rQ   rM   Nr   )r   r3   rr   r{   s     €€r   r<   ztwo_by_two.<locals>.<genexpr>“   s^   øè è € ð  ;Að  ;AÐnoÐ;iÀ!À!ÀAÀtÈWÐUWÌ[ÐZaÑBbÔBbÐ;iÐ;iÐ;ið  ;Að  ;Að  ;Að  ;Að  ;Að  ;Ar   c           
   3   ól   •K  — | ].}d D ])}‰d         ‰d         fD ]}d ‰|||d¦  «        › d�V — ŒŒ*Œ/dS )r°   r   rN   r\   r@   rM   Nr   )r   r3   r¢   r;   rr   r{   s       €€r   r<   ztwo_by_two.<locals>.<genexpr>”   s±   øè è € ð  Qð  QÀQÐ`lð  Qð  QÐ[\Ðw~ð  @Aô  xBð  DKð  LNô  DOð  wPð  Qð  QÐqrÐ@ A A a¨¨A¨yÑ$9Ô$9Ð@Ð@Ð@ð  Qð  Qð  Qð  Qð  Qð  Qð  Qð  Qr   r`   )r   r   rl   r   r   r   rb   r1   r   ra   rc   rd   r0   rf   rg   rh   ri   rj   rk   r'   rm   rp   rn   r˜   )r   rq   r   rv   r©   rª   rw   r;   rz   r|   ÚperrD   rr   rs   rI   r{   r6   rC   s              @@@@@@@r   Ú
two_by_tworÄ   t   sG  øøøøøøø€ å�Ñ €AØ�8Š8‰:Œ:ð $Ø#Ð#Ý•”˜qŸvšv™xœxÑ(Ô(Ñ)Ô)€DÝÐ/Ð/¨$Ð/Ñ/Ô/µSÐ9Ñ9Ô9€GÝ	•TÑ	Ô	€BØð >ð >ˆØ<=ˆˆ1ˆUŒ8�Q�w”Z  7¤Ð+Ô,¨Q¨x¬[Ñ9Ð9ð GØ�WŠWÐDÐD¸GÐDÑDÔDÑDÔDñEØGIÇwÂwÐNÐNÐw~ÐNÑNÔNÑGÔGñ@ð CJñJð K€Càð \ñ \ˆØ!ð 	\ñ 	\ˆEØˆEØ.ð oð o�Ø ð oð o�AØ "§¢¨¨U°A ¸Ñ ;Ô ;¸R¿VºVÀTÈ4ÐQRÀOÐUWÑ=XÔ=X�I�C˜ØzÐzÐzÐzÐzÐzÈSÐzÑzÔz�CØ?BÐN��bœf¥R¤W­R¬V°C©[¬[Ñ%9Ô%9Ñ:Ô:Ñ;Ô;Ð;ÍÌ�AØ—L’LÐ!m¸#¸u¸ÈÒ9UÐ9U­s°1©v¬v¨vÐ[]Ð!mÐ!mÐabÐ!mÐ!mÐ!mÐ!mÑnÔnÐnÐnð	oõ
 �b—f’f˜c 5¨'°"¬+Ð6¸Ñ;Ô;×BÒBÑDÔDÑEÔEˆBØ�JŠJð [°°U¨|¸|Ò/KÐ/K V VÐQSð [ð [ð  BEð  IMò  BMð  BMÐe}Ðe}ð  Shð [ð [Ø5:¸d²]°]¨	¨	Èð[ð [ÝY\Ð]_ÑY`ÔY`ð[ð [å!Ð!>Ð!>¸2Ð!>Ñ!>Ô!>Ñ>Ô>ð[ð [àEGÇWÂWÈUÁ^Ä^ð[ð [ð [ñ \ô \ð \ñ \ñ	\ð ‡J‚JÐÑ Ô Ð ØCÀbÇgÂgð N<ð N<Ø.:ðN<ñ N<ô N<ñ G<ô G<ñ <Ø>@¿gºgð F}ð F}ð F}ð F}Ø6BðF}ñ F}ô F}ñ ?}ô ?}ñ}ð @GñGð H€Cõ �]Š]Ð5Ð5°Ð5Ñ5Ô5Ñ5Ô5ð \ð \ˆØJÐJÐJÐJÐJˆØ�
Š
Ð0¨Ð0Ð0Ð0°2·7²7ð  ;Að  ;Að  ;Að  ;Að  ;AÐsð  ;Añ  ;Aô  ;Añ  4Aô  4Añ  AØ—W’Wð  Qð  Qð  Qð  Qð  QÈ,ð  Qñ  Qô  Qñ  Qô  QñQð T[ñ[ñ 	\ô 	\ð 	\ð 	\à‡J‚JÐÑ Ô Ð Ø�9Š9�S˜3‘YÑÔÐr   c                  óä  ‡‡‡‡‡— t           dz  } |                      ¦   «         sdS t          t          j        |                      ¦   «         ¦  «        ¦  «        }t          d„ |D ¦   «         t          ¬¦  «        Št          t          ¦  «        Š|D ]!}|‰|d         |d         f         |d         <   Œ"ˆˆfd„t           
                    d	„ |D ¦   «         ¦  «        D ¦   «         Šd
d                     d„ ‰D ¦   «         ¦  «        z   d                     d„ ‰D ¦   «         ¦  «        z   dz   }d|z   g}ˆfd„dD ¦   «         Š‰D �])}g }dD ]µ\  }}}	‰D ]¬}
t          ‰d|
f         |         |         ¦  «        t          ‰d|
f         |         |         ¦  «        }}‰||
f                              |dk    r||z  nd¦  «         |                     d||› ›d|dk    rt          ||z  |	¦  «        nd› d||› ›d�¦  «         Œ­Œ¶|                     d|› d|› d‰d‰d         f         |         d         › d‰d‰d         f         |         d         › dd                     |¦  «        › d�¦  «         �Œ+‰r^d „ Šˆˆˆfd!„}d                     ˆˆˆfd"„d#D ¦   «         ¦  «        }|                     d$ |d¦  «        › d |d¦  «        › d|› d�¦  «         |                     d%¦  «         d&                     |¦  «        S )'zW../report/shape_test.csv: tracked-fit's fit test in coefficients (default) or in shape.zshape_test.csvr¦   c                 ó   — h | ]
}|d          ’ŒS r†   r   r   s     r   r-   z shape_section.<locals>.<setcomp>Ÿ   r¨   r   r5   Útestr)   r*   c                 óN   •‡— g | ] Št          ˆˆfd „‰D ¦   «         ¦  «        ¯‰‘Œ!S )c              3   óL   •K  — | ]}‰‰                      d |fi ¦  «        v V — ŒdS )ÚshapeNr¾   )r   r;   rs   rC   s     €€r   r<   z+shape_section.<locals>.<listcomp>.<genexpr>£   s?   øè è € ÐFvÐFvÐijÀqÈBÏFÊFÐT[Ð]^ÐS_ÐacÑLdÔLdÐGdÐFvÐFvÐFvÐFvÐFvÐFvr   ©Úall)r   rC   rr   rs   s    @€€r   r   z!shape_section.<locals>.<listcomp>£   s@   øø€ ÐwÐwÐw�!Å3ÐFvÐFvÐFvÐFvÐFvÐnuÐFvÑFvÔFvÑCvÔCvÐwˆAÐwÐwÐwr   c              3   ó&   K  — | ]}|d          V — ŒdS r‚   r   r   s     r   r<   z shape_section.<locals>.<genexpr>£   ó&   è è € Ð$?Ð$?°Q Q x¤[Ð$?Ð$?Ð$?Ð$?Ð$?Ð$?r   zJ<tr><th class='l'>object</th><th>parts<br>coef</th><th>parts<br>shape</th>r$   c              3   ó(   K  — | ]}d |› d|› d�V — ŒdS )z<th>Chamfer %<br>coef z</th><th>Chamfer %<br>shape r9   Nr   r:   s     r   r<   z shape_section.<locals>.<genexpr>¥   s7   è è € ÐhÐhÐ[\ÐV¨qÐVÐVÈaÐVÐVÐVÐhÐhÐhÐhÐhÐhr   c              3   ó(   K  — | ]}d |› d|› d�V — ŒdS )u   <th>&gt;30Â° %<br>coef u   </th><th>&gt;30Â° %<br>shape r9   Nr   r:   s     r   r<   z shape_section.<locals>.<genexpr>¦   s8   è è € ÐjÐjÐ]^ÐX°ÐXÐXÐPQÐXÐXÐXÐjÐjÐjÐjÐjÐjr   r¯   ú<div class='wrap'><table>c                 ó$   •— i | ]}‰D ]}||fg “ŒŒS r   r   )r   r¿   r;   rr   s      €r   r‡   z!shape_section.<locals>.<dictcomp>¨   s,   ø€ ÐKÐKÐK˜QÀ7ÐKÐK¸aˆq�!ˆf�bÐKÐKÐKÐKr   r?   ))r@   rŽ   r   )rA   r]   r�   ÚcoefrÊ   r   g      ð?r\   z</td><td class='rK   rM   z<tr><td class='l'><a href='#z</a></td><td>rN   rQ   r[   c           	      óŒ   — t          t          j        t          j        t          j        | ¦  «        ¦  «        ¦  «        ¦  «        S rŒ   )r0   rf   rg   rh   ri   )r¡   s    r   r4   zshape_section.<locals>.<lambda>³   s*   € •u�RœV¥B¤G­B¬F°1©I¬IÑ$6Ô$6Ñ7Ô7Ñ8Ô8€ r   c                 ó@   •‡ — t          ˆˆˆ fd„‰D ¦   «         ¦  «        S )Nc              3   ój   •K  — | ]-}t          ‰‰‰d          f         |         d         ¦  «        V — Œ.dS )rN   rQ   NrR   )r   rC   rr   rs   Úts     €€€r   r<   z2shape_section.<locals>.<lambda>.<locals>.<genexpr>´   sB   øè è € ÐNÐNÀA�C  1 g¨b¤k >Ô 2°1Ô 5°gÔ >Ñ?Ô?ÐNÐNÐNÐNÐNÐNr   ©rn   )r×   rr   rs   rx   s   `€€€r   r4   zshape_section.<locals>.<lambda>´   s+   øø€ �ÐNÐNÐNÐNÐNÐNÈÐNÑNÔNÑNÔN€ r   c           
   3   óœ   •K  — | ]F\  }}‰D ]>}d t           ‰‰||f         ¦  «        |¦  «        › d ‰‰||f         ¦  «        d›d�V — Œ?ŒGdS )z<td></td><td class='u   '>Ã— rL   rM   N)r'   )r   r¿   r&   r;   rr   ÚgmÚratioss       €€€r   r<   z shape_section.<locals>.<genexpr>µ   s§   øè è € ð `ð `Ù"˜A˜sÐW^ð`ð `ØRSð l­s°2°2°f¸QÀ¸T´lÑ3CÔ3CÀSÑ/IÔ/IÐkÐkÐPRÐPRÐSYÐZ[Ð]^ÐZ^ÔS_ÑP`ÔP`ÐkÐkÐkÐkð `ð `ð `ð `ð `ð `ð `r   ))r@   r   )rA   r�   zL<tr class='base'><td class='l'>all (geometric mean of shape / coef)</td><td>r_   r`   )r   r   rl   r   r   r   rb   r1   r   ra   r˜   rc   r0   rk   r'   )r   rq   r   ru   rv   rC   rw   r¿   Úfmtr&   r;   Úar¢   Útotrr   rs   rÚ   rx   rÛ   s                 @@@@@r   Úshape_sectionrß   ™   s*  øøøøø€ åÐ!Ñ!€AØ�8Š8‰:Œ:ð $Ø#Ð#Ý•”˜qŸvšv™xœxÑ(Ô(Ñ)Ô)€DÝÐ/Ð/¨$Ð/Ñ/Ô/µSÐ9Ñ9Ô9€GÝ	•TÑ	Ô	€BØð 3ð 3ˆØ12ˆˆ1ˆVŒ9�a˜”jÐ Ô! ! H¤+Ñ.Ð.ØwÐwÐwÐwÐw•t—}’}Ð$?Ð$?¸$Ð$?Ñ$?Ô$?Ñ?Ô?ÐwÑwÔw€DØXØ�gŠgÐhÐhÐ`gÐhÑhÔhÑhÔhñià�gŠgÐjÐjÐbiÐjÑjÔjÑjÔjñkàmtñu€Dð '¨Ñ-Ð
.€CØKÐKÐKÐKÐ"9ÐKÑKÔK€FØð \ñ \ˆØˆØPð 	qð 	q‰KˆAˆs�CØð qð q�Ý˜R ¨ 	œ]¨1Ô-¨aÔ0Ñ1Ô1µ5¸¸GÀQ¸J¼ÈÔ9JÈ1Ô9MÑ3NÔ3N�1�Ø�q˜!�t”×#Ò#¨Q°ªU¨U A¨¡E E¸Ñ<Ô<Ð<Ø—’Ðo A sÐoÐoÐoÐPQÐTUÒPUÐPU½SÀÀQÁÈ¹_¼_¸_Ð[]ÐoÐoÐabÐdgÐoÐoÐoÐoÑpÔpÐpÐpðqð 	�
Š
ð [°!ð [ð [°qð [ð [ÀrÈ&ÐRYÐZ\ÔR]ÐJ]ÔG^Ð_`ÔGaÐbiÔGjð [ð [Ø˜W g¨b¤kÐ1Ô2°1Ô5°gÔ>ð[ð [ØEGÇWÂWÈUÁ^Ä^ð[ð [ð [ñ 	\ô 	\ð 	\ñ 	\àð YØ8Ð8ˆØNÐNÐNÐNÐNÐNˆØ—’ð `ð `ð `ð `ð `ð `Ø&Mð`ñ `ô `ñ `ô `ˆà�
Š
ð  XÐbeÐbeÐflÑbmÔbmð  Xð  XÐx{Ðx{ð  }Dñ  yEô  yEð  Xð  Xð  LQð  Xð  Xð  Xñ  	Yô  	Yð  	YØ‡J‚JÐÑ Ô Ð Ø�9Š9�S‰>Œ>Ðr   c                  ó¬  ‡‡	‡
‡— t           dz  } |                      ¦   «         sdS t          t          j        |                      ¦   «         ¦  «        ¦  «        }g d¢}dd                     d„ |D ¦   «         ¦  «        z   dz   d                     d„ |D ¦   «         ¦  «        z   d	z   }d
|z   g}t                               d„ |D ¦   «         ¦  «        D ]ÍŠ	dD ]ÈŠ
ˆ	ˆ
fd„|D ¦   «         }d}dD ]cŠˆfd„|D ¦   «         Š|d                     ˆfd„|D ¦   «         ¦  «        z  }|dt          ‰¦  «        dk    rdnd› dt          ‰¦  «        d›d�z  }Œdt          d„ |D ¦   «         ¦  «        }| 
                    d‰	› d‰	› d‰
› dt          |¦  «        › d|› d|d›d�¦  «         ŒÉŒÎ| 
                    d¦  «         t                               d„ |D ¦   «         ¦  «        D ]kŠ	| 
                    d‰	› d‰	› d �¦  «         dD ]JŠ
t           d!z  d"‰	› d#‰
› d$�z                       ¦   «         r"| 
                    d%‰	› d#‰
› d&‰	› d'‰
› d(�	¦  «         ŒKŒld)                     |¦  «        S )*zj../report/fit_audit.csv: per part, how far the rings given back are from the sliced rings (layer heights).zfit_audit.csvr¦   ))r   çš™™™™™¹?z&le; 0.1)rá   ç      Ð?z0.1-0.25)râ   ç      à?z0.25-0.5)rã   g    eÍÍAz&gt; 0.5zF<tr><th class='l'>object</th><th class='l'>cut test</th><th>parts</th>r$   c              3   ó.   K  — | ]}d |d         › d�V — ŒdS )z<th>6144:<br>r/   r9   Nr   ©r   r¢   s     r   r<   z audit_section.<locals>.<genexpr>Ä   ó2   è è € Ð@Ð@°aÐ1 a¨¤dÐ1Ð1Ð1Ð@Ð@Ð@Ð@Ð@Ð@r   z<th>6144<br>worst</th>c              3   ó.   K  — | ]}d |d         › d�V — ŒdS )z<th>1024:<br>r/   r9   Nr   rå   s     r   r<   z audit_section.<locals>.<genexpr>Å   ræ   r   z5<th>1024<br>worst</th><th>full fit<br>worst</th></tr>rÑ   c              3   ó&   K  — | ]}|d          V — ŒdS r‚   r   r   s     r   r<   z audit_section.<locals>.<genexpr>Ç   r¼   r   )rÓ   rÊ   c                 óD   •— g | ]}|d          ‰k    ¯|d         ‰k    ¯|‘ŒS )r*   rÇ   r   )r   r   rC   r×   s     €€r   r   z!audit_section.<locals>.<listcomp>É   s0   ø€ ÐIÐIÐI˜ Q x¤[°AÒ%5Ð%5¸!¸F¼)Àqº.¸.�!¸.¸.¸.r   )Úa6144Úa1024c                 ó@   •— g | ]}t          |‰› d �         ¦  «        ‘ŒS )Ú_maxrG   )r   r   r¿   s     €r   r   z!audit_section.<locals>.<listcomp>Ì   s+   ø€ Ð6Ð6Ð6¨a•U˜1 ˜Z˜Z˜Zœ=Ñ)Ô)Ð6Ð6Ð6r   c              3   ód   •‡‡K  — | ](\  ŠŠ}d t          ˆˆfd„‰D ¦   «         ¦  «        › d�V — Œ)dS )r\   c              3   óP   •K  — | ] }‰|cxk     o‰k    nc p‰d k    o|d k    V — Œ!dS )r   Nr   )r   Úxr²   r±   s     €€r   r<   z*audit_section.<locals>.<genexpr>.<genexpr>Í   sJ   øè è € Ð+\Ð+\ÐUV¨B°¨L¨LªL¨L°bªL¨L¨L¨LÐ,P¸RÀ1ºWÐ=OÈÈaÊÐ+\Ð+\Ð+\Ð+\Ð+\Ð+\r   rM   NrØ   )r   Ú_r²   r±   r¡   s     @@€r   r<   z audit_section.<locals>.<genexpr>Í   s\   øøøè è € Ð zÐ zÑhqÐhjÐlnÐpqÐ!c­Ð+\Ð+\Ð+\Ð+\Ð+\ÐZ[Ð+\Ñ+\Ô+\Ñ(\Ô(\Ð!cÐ!cÐ!cÐ zÐ zÐ zÐ zÐ zÐ zr   rJ   rã   r#   rK   r]   rM   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS )Úfull_maxNrG   r   s     r   r<   z audit_section.<locals>.<genexpr>Ï   s.   è è € Ð8Ð8°•u˜Q˜zœ]Ñ+Ô+Ð8Ð8Ð8Ð8Ð8Ð8r   z"<tr><td class='l'><a href='#audit_z</a></td><td class='l'>r[   r\   r^   r_   c              3   ó&   K  — | ]}|d          V — ŒdS r‚   r   r   s     r   r<   z audit_section.<locals>.<genexpr>Ò   r¼   r   z<h3 id='audit_z</h3>r’   Úaudit_rñ   z.pngz<img src='img/audit_z.png' alt='audit rº   r—   r`   )r   r   rl   r   r   r   rc   ra   r˜   ro   rk   rp   )r   rq   Úbinsru   rv   r|   rw   Úfullr¿   rC   r×   r¡   s           @@@@r   Úaudit_sectionrø   ¼   s^  øøøø€ å�Ñ €AØ�8Š8‰:Œ:ð $Ø#Ð#Ý•”˜qŸvšv™xœxÑ(Ô(Ñ)Ô)€DØkÐkÐk€DØTØ�gŠgÐ@Ð@¸4Ð@Ñ@Ô@Ñ@Ô@ñAØC[ñ\à�gŠgÐ@Ð@¸4Ð@Ñ@Ô@Ñ@Ô@ñAàCzñ{€Dð '¨Ñ-Ð
.€CÝ�]Š]Ð5Ð5°Ð5Ñ5Ô5Ñ5Ô5ð 	Vð 	VˆØ"ð 	Vð 	VˆAØIÐIÐIÐIÐI˜TÐIÑIÔIˆBØˆEØ'ð Zð Z�Ø6Ð6Ð6Ð6°2Ð6Ñ6Ô6�Ø˜ŸšÐ zÐ zÐ zÐ zÐuyÐ zÑ zÔ zÑzÔzÑz�ØÐYµ°A±´¸²° u uÀ"ÐYÐYÍÈAÉÌÐYÐYÐYÐYÑY��ÝÐ8Ð8°RÐ8Ñ8Ô8Ñ8Ô8ˆDØ�JŠJð  U¸Að  Uð  UÀð  Uð  UÐ[\ð  Uð  UÕgjÐkmÑgnÔgnð  Uð  UÐuzð  Uð  Uð  AEð  Uð  Uð  Uð  Uñ  Vô  Vð  Vð  Vð	Vð ‡J‚JÐÑ Ô Ð Ý�]Š]Ð5Ð5°Ð5Ñ5Ô5Ñ5Ô5ð dð dˆØ�
Š
Ð1 AÐ1Ð1¨Ð1Ð1Ð1Ñ2Ô2Ð2Ø"ð 	dð 	dˆAÝ˜‘Ð!5¨!Ð!5Ð!5¨aÐ!5Ð!5Ð!5Ñ5×=Ò=Ñ?Ô?ð dØ—
’
Ðb°!ÐbÐb°aÐbÐbÈ!ÐbÐbÈaÐbÐbÐbÑcÔcÐcøð	dð �9Š9�S‰>Œ>Ðr   c                  ó   ‡‡‡— t           dz  } |                      ¦   «         sdS t          t          j        |                      ¦   «         ¦  «        ¦  «        }t          d„ |D ¦   «         t          ¬¦  «        }t          t          ¦  «        }|D ](}|||d         |d         |d         f         |d         <   Œ)t          d	„ |D ¦   «         d
„ ¬¦  «        }dd 
                    d„ |D ¦   «         ¦  «        z   d 
                    d„ |D ¦   «         ¦  «        z   dz   g}|D �]#}g }dD ]“Š|D ]Ž}	|g |¢|	‘R          |dd|	f         cŠŠt          t          j        t          j        ˆˆˆfd„‰D ¦   «         ¦  «        ¦  «        ¦  «        }
|                     d|dk    rt!          |
¦  «        nd› d|
d›d�¦  «         Œ�Œ”t#          d„ |g |¢|d         ‘R                               ¦   «         D ¦   «         ¦  «        }|                     d|dk    rdnd› d|d         › d|d         › d|› dd 
                    |¦  «        › d�¦  «         �Œ%|                     d ¦  «         d!D ]d}d"D ]_}t           d#z  d$|› d%|d         › d&|d         › d'�z  }|                     ¦   «         r&|                     d(|j        › d)|j        › d*�¦  «         Œ`Œed+ 
                    |¦  «        S ),zG../report/nm_sweep.csv: a smaller dictionary (N, M) for a small budget.znm_sweep.csvr¦   c                 ó   — h | ]
}|d          ’ŒS r†   r   r   s     r   r-   znm_section.<locals>.<setcomp>à   r¨   r   r5   ÚNr   r)   r*   c                 ó.   — h | ]}|d          |d         f’ŒS )rû   r   r   r   s     r   r-   znm_section.<locals>.<setcomp>ä   s%   € Ð1Ð1Ð1 q�1�S”6˜1˜Sœ6Ð"Ð1Ð1Ð1r   c                 óZ   — t          | d         ¦  «         t          | d         ¦  «         fS )Nr   r!   rR   r2   s    r   r4   znm_section.<locals>.<lambda>ä   s&   € Å3ÀqÈÄtÁ9Ä9À*ÍsÐSTÐUVÔSWÉyÌyÈjÐAY€ r   zI<div class='wrap'><table><tr><th class='l'>N</th><th>M</th><th>parts</th>r$   c              3   ó"   K  — | ]
}d |› d�V — ŒdS r8   r   r:   s     r   r<   znm_section.<locals>.<genexpr>å   sT   è è € ð  aQð  aQð  DEÐa~ÐvwÐa~Ða~Ða~ð  aQð  aQð  aQð  aQð  aQð  aQr   c              3   ó"   K  — | ]
}d |› d�V — ŒdS r>   r   r:   s     r   r<   znm_section.<locals>.<genexpr>æ   s.   è è € ÐEÐE¸Ð3¨1Ð3Ð3Ð3ÐEÐEÐEÐEÐEÐEr   r¯   r?   Ú16r   c           	      óà   •— g | ]j}t          ‰|         ‰         ¦  «        d k    ¯!t          j        t          ‰|         ‰         ¦  «        t          ‰|         ‰         ¦  «        z  ¦  «        ‘ŒkS rF   )r0   rf   ri   )r   rC   rD   rI   r¿   s     €€€r   r   znm_section.<locals>.<listcomp>ì   sk   ø€ Ð)}Ð)}Ð)}Ð[\ÕglÐmqÐrsÔmtÐuvÔmwÑgxÔgxÐ{|Òg|Ðg|­"¬&µ°s¸1´v¸a´yÑ1AÔ1AÅEÈ$ÈqÌ'ÐRSÌ*ÑDUÔDUÑ1UÑ*VÔ*VÐg|Ðg|Ðg|r   rJ   ©r   r   rK   rL   rM   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS rP   rR   r   s     r   r<   znm_section.<locals>.<genexpr>î   s,   è è € ÐKÐK¨•C˜˜'œ
‘O”OÐKÐKÐKÐKÐKÐKr   r   rY   rD   rZ   r[   r!   r_   )ÚdinoÚelephantÚhorseÚbowl_gso)r  )r   Ú8)r  r  r’   Únm_Ú_NÚ_Mú
_a1024.pngr•   r–   r—   r`   )r   r   rl   r   r   r   rb   r1   r   ra   rc   r0   rf   rg   rh   rk   r'   rn   rm   r”   rž   )r   rq   rr   rs   r   Únmsrv   r3   rw   r;   r{   rQ   r”   ÚfrD   rI   r¿   s                 @@@r   Ú
nm_sectionr  Ú   sæ  øøø€ å�Ñ€AØ�8Š8‰:Œ:ð $Ø#Ð#Ý•”˜qŸvšv™xœxÑ(Ô(Ñ)Ô)€DÝÐ/Ð/¨$Ð/Ñ/Ô/µSÐ9Ñ9Ô9€GÝ	•TÑ	Ô	€BØð 8ð 8ˆØ67ˆˆ1ˆSŒ6�1�S”6˜1˜Wœ:Ð%Ô& q¨¤{Ñ3Ð3Ý
Ð1Ð1¨DÐ1Ñ1Ô1Ð7YÐ7YÐ
ZÑ
ZÔ
Z€CØVÐY[×Y`ÒY`ð  aQð  aQð  IPð  aQñ  aQô  aQñ  ZQô  ZQñ  QØ�WŠWÐEÐE¸WÐEÑEÔEÑEÔEñFØHOñPð Q€Càð Wñ WˆØˆØ(ð 	`ð 	`ˆAØð `ð `�Ø˜w ˜w A˜w˜wœK¨¨T°4¸¨OÔ)<�	��TÝ�"œ&¥¤Ð)}Ð)}Ð)}Ð)}Ð)}Ð)}Ð`cÐ)}Ñ)}Ô)}Ñ!~Ô!~ÑÔñ  Aô  A�Ø—’Ð^°Q¸,Ò5FÐ5F­3¨q©6¬6¨6ÈBÐ^Ð^ÐRSÐ^Ð^Ð^Ð^Ñ_Ô_Ð_Ð_ð`õ ÐKÐK¨RÐ0@°!Ð0@°W¸Q´ZÐ0@Ð0@Ô-A×-HÒ-HÑ-JÔ-JÐKÑKÔKÑKÔKˆØ�
Š
ð  V¨1°Ò+<Ð+<  À"ð  Vð  VÐVWÐXYÔVZð  Vð  VÐefÐghÔeið  Vð  VÐtyð  Vð  Vð  AC÷  AHò  AHð  INñ  AOô  AOð  Vð  Vð  Vñ  	Wô  	Wð  	Wñ  	WØ‡J‚JÐÑ Ô Ð Ø9ð Vð VˆØ8ð 	Vð 	VˆAÝ˜‘Ð!G tÐ!GÐ!G¨q°¬tÐ!GÐ!G°q¸´tÐ!GÐ!GÐ!GÑGˆAØ�xŠx‰zŒzð VØ—
’
ÐT¨A¬FÐTÐT¸1¼6ÐTÐTÐTÑUÔUÐUøð	Vð �9Š9�S‰>Œ>Ðr   Údp_splitÚdpc                 ó°  ‡‡‡‡‡‡‡— t           | › d�z  }|                     ¦   «         sdS t          t          j        |                     ¦   «         ¦  «        ¦  «        }t          d„ |D ¦   «         t          ¬¦  «        Št          t          ¦  «        Š|D ]!}|‰|d         |d         f         |d         <   Œ"t          t           
                    d„ |D ¦   «         ¦  «        ¦  «        Šˆˆˆfd	„t           
                    d
„ |D ¦   «         ¦  «        D ¦   «         }dt          |¦  «        › d�d                     d„ ‰D ¦   «         ¦  «        z   d                     d„ ‰D ¦   «         ¦  «        z   dz   g}‰D �]IŠg }dD ]¦Š‰D ]¡Šˆˆˆˆfd„|D ¦   «         }|rEt          t          j        t          j        t          j        |¦  «        ¦  «        ¦  «        ¦  «        nt          j        }	|                     d‰dk    rt)          |	‰dk    rdnd¦  «        nd› d|	d›d�¦  «         Œ¢Œ§ˆˆˆfd„|D ¦   «         }
|                     d‰dk    rdnd› d‰› dt+          d „ |
D ¦   «         ¦  «        › dt-          d!„ |
D ¦   «         d"¬#¦  «        d$›dt+          d%„ |
D ¦   «         ¦  «        › dd                     |¦  «        › d�¦  «         �ŒK|                     d&¦  «         d'd                     d(„ ‰D ¦   «         ¦  «        z   dz   }|                     d)|z   ¦  «         |D ]BŠ|                     d*‰› d�d                     ˆˆˆfd+„‰D ¦   «         ¦  «        z   dz   ¦  «         ŒC|                     d&¦  «         |D ]WŠ‰D ]RŠt           d,z  |› d-‰› d-‰› d.�z  }|                     ¦   «         r&|                     d/|j        › d0|j        › d1�¦  «         ŒSŒXd2                     |¦  «        S )3zc../report/<csv_name>.csv: a partition rule's configurations against the greedy split (the package).z.csvr¦   c                 ó   — h | ]
}|d          ’ŒS r†   r   r   s     r   r-   zdp_section.<locals>.<setcomp>ÿ   r¨   r   r5   Úconfigr)   r*   c              3   ó&   K  — | ]}|d          V — ŒdS )r  Nr   r   s     r   r<   zdp_section.<locals>.<genexpr>  s&   è è € Ð ;Ð ;°  8¤Ð ;Ð ;Ð ;Ð ;Ð ;Ð ;r   c                 óP   •‡— g | ]!Št          ˆˆˆfd „‰D ¦   «         ¦  «        ¯‰‘Œ"S )c              3   óX   •K  — | ]$}‰‰                      |‰d          fi ¦  «        v V — Œ%dS )rN   Nr¾   ©r   r3   rr   rs   rC   s     €€€r   r<   z(dp_section.<locals>.<listcomp>.<genexpr>  sE   øè è € ÐFzÐFzÐmnÀqÈBÏFÊFÐTUÐW^Ð_aÔWbÐScÐegÑLhÔLhÐGhÐFzÐFzÐFzÐFzÐFzÐFzr   rË   )r   rC   rr   rs   rt   s    @€€€r   r   zdp_section.<locals>.<listcomp>  sC   øø€ Ð{Ð{Ð{�!Å3ÐFzÐFzÐFzÐFzÐFzÐFzÐryÐFzÑFzÔFzÑCzÔCzÐ{ˆAÐ{Ð{Ð{r   c              3   ó&   K  — | ]}|d          V — ŒdS r‚   r   r   s     r   r<   zdp_section.<locals>.<genexpr>  rÎ   r   z<p class='mut'>z© objects complete.</p><div class='wrap'><table><tr><th class='l'>partition</th><th>parts</th><th>worst part miss<br>(layer heights)</th><th>parts over<br>0.25 layer</th>r$   c              3   ó"   K  — | ]
}d |› d�V — ŒdS r8   r   r:   s     r   r<   zdp_section.<locals>.<genexpr>  r¬   r   c              3   ó"   K  — | ]
}d |› d�V — ŒdS r>   r   r:   s     r   r<   zdp_section.<locals>.<genexpr>  r®   r   r¯   r?   c                 óì   •— g | ]p}t          ‰d ‰f         |         ‰         ¦  «        dk    ¯)t          ‰‰‰f         |         ‰         ¦  «        t          ‰d ‰f         |         ‰         ¦  «        z  ‘ŒqS )Úgreedyr   rG   )r   rC   r;   rs   r3   r¿   s     €€€€r   r   zdp_section.<locals>.<listcomp>  s~   ø€ Ð~Ð~Ð~ÐPQÕ]bÐceÐfnÐpqÐfqÔcrÐstÔcuÐvwÔcxÑ]yÔ]yÐ|}Ò]}Ð]}•u˜R  1 œX aœ[¨œ^Ñ,Ô,­u°R¸À!¸´_ÀQÔ5GÈÔ5JÑ/KÔ/KÑKÐ]}Ð]}Ð]}r   rJ   r  r@   r   r�   rK   rL   rM   c                 ó<   •— g | ]}‰‰‰d          f         |         ‘ŒS )rN   r   )r   rC   rr   rs   r3   s     €€€r   r   zdp_section.<locals>.<listcomp>  s+   ø€ Ð2Ð2Ð2¨ˆb��G˜B”K�Ô  Ô#Ð2Ð2Ð2r   rY   rD   rZ   r[   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS rP   rR   r   s     r   r<   zdp_section.<locals>.<genexpr>  s3   è è € Ða~Ða~ÐvwÕbeÐfgÐhoÔfpÑbqÔbqÐa~Ða~Ða~Ða~Ða~Ða~r   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS )Úworst_lhNrG   r   s     r   r<   zdp_section.<locals>.<genexpr>  s.   è è € Ð@Ð@¸�u Q z¤]Ñ3Ô3Ð@Ð@Ð@Ð@Ð@Ð@r   r   rU   r]   c              3   ó@   K  — | ]}t          |d          ¦  «        V — ŒdS )Úover_025NrR   r   s     r   r<   zdp_section.<locals>.<genexpr>  s3   è è € Ð^~Ð^~ÐvwÕ_bÐcdÐeoÔcpÑ_qÔ_qÐ^~Ð^~Ð^~Ð^~Ð^~Ð^~r   r_   z<tr><th class='l'>object</th>c              3   ó"   K  — | ]
}d |› d�V — ŒdS )z<th>z<br>parts / worst</th>Nr   r·   s     r   r<   zdp_section.<locals>.<genexpr>  s/   è è € Ð4gÐ4gÐZ[Ð5U¸AÐ5UÐ5UÐ5UÐ4gÐ4gÐ4gÐ4gÐ4gÐ4gr   rÑ   rÀ   c           
   3   ó®   •K  — | ]O}d ‰|‰d         f         ‰         d         › dt          ‰|‰d         f         ‰         d         ¦  «        d›d�V — ŒPdS )r\   rN   rQ   z / r!  r]   rM   NrG   r  s     €€€r   r<   zdp_section.<locals>.<genexpr>  sŠ   øè è € ð ;|ð ;|ØnoÐi�2�a˜ œ�nÔ% aÔ(¨Ô1ÐiÐiµe¸B¸qÀ'È"Ä+¸~Ô<NÈqÔ<QÐR\Ô<]Ñ6^Ô6^ÐiÐiÐiÐið;|ð ;|ð ;|ð ;|ð ;|ð ;|r   r’   rñ   r  r•   r–   r—   r`   )r   r   rl   r   r   r   rb   r1   r   ra   r˜   rp   rc   r0   rf   rg   rh   ri   rj   rk   r'   rn   ro   r”   rž   )Úcsv_nameÚprefixr   rq   r   rx   rv   rw   rz   r{   r|   ru   r  r;   rr   rs   r3   rt   r¿   rC   s                @@@@@@@r   Ú
dp_sectionr(  ù   sK  øøøøøøø€ å�HÐ"Ð"Ð"Ñ"€AØ�8Š8‰:Œ:ð $Ø#Ð#Ý•”˜qŸvšv™xœxÑ(Ô(Ñ)Ô)€DÝÐ/Ð/¨$Ð/Ñ/Ô/µSÐ9Ñ9Ô9€GÝ	•TÑ	Ô	€BØð 5ð 5ˆØ34ˆˆ1ˆXŒ;˜˜'œ
Ð"Ô# A h¤KÑ0Ð0Ý•4—=’=Ð ;Ð ;°dÐ ;Ñ ;Ô ;Ñ;Ô;Ñ<Ô<€GØ{Ð{Ð{Ð{Ð{Ð{•t—}’}Ð$?Ð$?¸$Ð$?Ñ$?Ô$?Ñ?Ô?Ð{Ñ{Ô{€DðZ�S ™YœYð Zð Zð Zà�WŠWÐDÐD¸GÐDÑDÔDÑDÔDñEàGIÇwÂwÐNÐNÐw~ÐNÑNÔNÑGÔGñ@ð CJñJð K€Cð ð 	\ñ 	\ˆØˆØ(ð 	~ð 	~ˆAØð ~ð ~�Ø~Ð~Ð~Ð~Ð~Ð~Ð~ÐUYÐ~Ñ~Ô~�Ø;>ÐJ•E�"œ&¥¤­¬°©¬Ñ!5Ô!5Ñ6Ô6Ñ7Ô7Ð7ÅBÄF�Ø—’Ð|ÐWXÐ\dÒWdÐWd­3¨q¸!¸yº.¸.°$°$ÈdÑ+SÔ+SÐ+SÐjlÐ|Ð|ÐpqÐ|Ð|Ð|Ð|Ñ}Ô}Ð}Ð}ð~ð 3Ð2Ð2Ð2Ð2Ð2¨TÐ2Ñ2Ô2ˆØ�
Š
ð [¨1°ª=¨=  ¸bð [ð [ÐRSð [ð [Õ^aÐa~Ða~Ð{}Ða~Ña~Ôa~Ñ^~Ô^~ð [ð [ÝÐ@Ð@¸RÐ@Ñ@Ô@È!ÐLÑLÔLð  [ð[ð [Ý[^Ð^~Ð^~Ð{}Ð^~Ñ^~Ô^~Ñ[~Ô[~ð[ð [ð FH÷  FMò  FMð  NSñ  FTô  FTð[ð [ð [ñ 	\ô 	\ð 	\ñ 	\à‡J‚JÐÑ Ô Ð Ø*¨R¯WªWÐ4gÐ4gÐ_fÐ4gÑ4gÔ4gÑ-gÔ-gÑgÐjqÑq€DØ‡J‚JÐ*¨TÑ1Ñ2Ô2Ð2Øð Gð GˆØ�
Š
Ð0¨Ð0Ð0Ð0°2·7²7ð ;|ð ;|ð ;|ð ;|ð ;|ð ;|Øszð;|ñ ;|ô ;|ñ 4|ô 4|ñ |ð FñFñ 	Gô 	Gð 	Gð 	Gà‡J‚JÐÑ Ô Ð Øð Vð VˆØð 	Vð 	VˆAÝ˜‘ FÐ!>Ð!>¨QÐ!>Ð!>°Ð!>Ð!>Ð!>Ñ>ˆAØ�xŠx‰zŒzð VØ—
’
ÐT¨A¬FÐTÐT¸1¼6ÐTÐTÐTÑUÔUÐUøð	Vð �9Š9�S‰>Œ>Ðr   c                  óú  — t          ¦   «         } t          d„ | D ¦   «         t          ¬¦  «        }t          t                               d„ | D ¦   «         ¦  «        ¦  «        }d                     d„ |D ¦   «         ¦  «        }d                     g d‘t          › ‘d‘t          j	        d	¦  «        › ‘d
‘t          | ¦  «        › ‘d‘t          |¦  «        › ‘d‘t          › ‘d‘| rt          | |¦  «        nd› ‘d‘t          ¦   «         › ‘d‘t          dz                       ¦   «         r.t!          j        t          dz                       ¦   «         ¦  «        nd› ‘d‘t'          ¦   «         › ‘d‘t)          ¦   «         › ‘d‘t+          ¦   «         › ‘d‘t-          ¦   «         › ‘d‘t-          dd¦  «        › ‘d‘t-          dd¦  «        › ‘d‘|› ‘d‘t/          | |¦  «        › ‘d‘¦  «        }t          dz                       |¦  «         d S ) Nc                 ó   — h | ]
}|d          ’ŒS r†   r   r   s     r   r-   zmain.<locals>.<setcomp>#  r¨   r   r5   c              3   ó&   K  — | ]}|d          V — ŒdS r‚   r   r   s     r   r<   zmain.<locals>.<genexpr>$  s&   è è € Ð8Ð8¨a˜a œkÐ8Ð8Ð8Ð8Ð8Ð8r   rº   c              3   ó(   K  — | ]}d |› d|› d�V — ŒdS )z
<a href='#rK   z</a>Nr   )r   rC   s     r   r<   zmain.<locals>.<genexpr>%  s6   è è € Ð;Ð;°Ð, Ð,Ð, QÐ,Ð,Ð,Ð;Ð;Ð;Ð;Ð;Ð;r   r$   z¬<!doctype html><html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1"><title>Partition: degree sweep</title><style>z\</style></head><body>
<h1>Partition: longer parts, higher height degree</h1>
<p class="mut">z%Y-%m-%d %H:%Mu™    Â· fcp v5.31 (CUDA), package untouched (KAPPA patched in the process) Â·
<code>scripts/degree_sweep.py</code> â†’ <code>report/degree_sweep.csv</code> (z rows, uÀ    objects) Â·
Chamfer: mean of both directions, % of the diagonal; &gt;30Â°: share of decoded-surface samples whose face normal is over
30Â° from the nearest clean-mesh sample's (unsigned)</p>
u#  
<h2>Summary: geometric mean over the objects of the ratio to the default</h2>
<p class="mut">Default row shaded (<code>tracked-fit</code>, Îº 1e2, M 24). Green: 2 % better, red: 2 % worse. Parts and
encode time summed over the objects; longest deg: the largest degree any part reached.</p>
z<p>no rows yet</p>a8  
<h2>The two effects apart: the cut decision and the stored basis</h2>
<p class="mut"><code>scripts/split_2x2.py</code>: tracked-fit's cut decision with the default or a high cap (fewer cuts), and the
stored height basis with the default or a high cap (higher degrees). Ratios to default / default (shaded).</p>
u&  
<h2>Why the elephant is cut so much</h2>
<div class="box">17 tracks, 27 parts: every extra part comes from one track, the body (layers 6-99), cut into 11 slabs. Three or
four of its cuts sit on real events (a step of 0.2-0.5 in the ring coefficients, a jump of the perimeter: legs at 13, the
leg tops at 26-30, the head at 50-51, the trunk at 91). The others (19, 36, 61, 70, 77, 85) sit on smooth stretches (steps
0.01-0.05). There the cut test, the fit's worst miss <i>in coefficients</i>, is 2.5-4 times the miss <i>in shape</i>
(nearest-point RMS between the fitted ring and the sliced ring): 14-26 0.029 against 0.0072, 31-50 0.0115 against 0.0038,
61-89 0.031 against 0.0096 (tolerance 0.01). The rest is the parametrization sliding along the ring (tangential drift of
the arc-length start), which moves no surface. Across the head (36-89) both are large (0.149 / 0.045): a real cut.
A higher degree removes some of these cuts only by following the drift too.</div>
<p class="mut"><code>scripts/body_track.py elephant</code> â†’ <code>report/elephant_body.txt</code> (per layer: rings in the
slice, area, perimeter, coefficient step; then the coefficient and shape misses of the stretches).</p>
<pre style="font-size:12px;max-height:420px;overflow:auto;background:#fff;border:1px solid var(--line);padding:8px">zelephant_body.txtaú  </pre>
<h2>Step 2: the fit test in shape, not in coefficients</h2>
<p class="mut"><code>scripts/shape_test.py</code>: tracked-fit unchanged (tracking, cut search, step rule, tolerance 0.01,
default cap) except that a fit follows its part when every ring is within the tolerance <i>in shape</i> (nearest-point RMS
between the fitted and the sliced ring, both ways) instead of in coefficients. Green / red: shape better / worse than coef.
Renders: <code>shape-fit</code> images in each object's section.</p>
u?  
<div class="box"><b>Step 2, result.</b> (After a fix: the first run measured to the nearest <i>sample</i> of the other ring,
which leaves a floor of up to half a sample spacing, about the tolerance on a big ring, and cut more; now to the polyline.)
The shape test cuts less (124 parts against 134: elephant 27 â†’ 23, shoe 22 â†’ 17, dress 17 â†’ 16, horse 18 â†’ 17, bowl_gso
6 â†’ 5) at the same Chamfer (Ã— 0.997 / 1.000 / 1.001 at 256 / 1024 / 6144). Normals: better at 256 on the elephant and the
shoe, worse at 6144 (elephant, shoe, horse about +9 %; bowl_gso Ã— 1.9). The bowl shows why: the foot (6-14) and the waist
(15-26) become one part, and its fit leaves horizontal ripples at the foot, still at 6144 atoms. Every ring is within 0.01
in shape, but 0.01 is 0.64 of a layer height (2 / 128): a miss that alternates from layer to layer at that size tilts the
surface by tens of degrees. A tolerance on distance alone allows it; the coefficient test caught it by being stricter for
another reason. Next: a slope test besides the distance (the change of the miss between neighbouring rings, against the
layer height).</div>
<h2>Which parts fit their shape</h2>
<p class="mut"><code>scripts/fit_audit.py</code>: per part, the worst shape distance over its layers between the sliced ring
and the ring given back at the layer centre, in <b>layer heights</b> (0.0172 canonical; the cut tolerance 0.01 is 0.58 of
one). Counts of parts by their worst miss. "full fit": all degrees of the part's height basis (what the cut test judges).
Images: per object and cut test, the four parts that miss most: equivalent radius sqrt(area / pi) along the part (sliced,
full fit, 6144, 1024 atoms) and the miss per layer.</p>
<div class="box"><b>What it shows.</b> 6144 atoms give back the full fit (the budget is not what limits a part there); 1024
does not (elephant parts 0.5-2 layer heights off). Most parts fit to under a tenth of a layer. The waves are where a part
holds a corner or a step: the polynomial rings around it with a period of two or three layers across the whole part
(bowl_gso, shape test: the foot, layers 6-26, holds the bottom edge at layers 6-8, the radius 5 â†’ 27 layer heights in two
layers, then a gentle flare; its miss alternates 0.1 / 0.28 up to layer 26 and peaks at 0.52 at the corner. The corner
cannot be cut off: it is two layers from the end and pieces are at least FIT_MIN = 4). With the coefficient test every part
of the ten stays within 0.38 of a layer (dino 0.38, dress 0.31, the rest 0.25 or less); the shape test at the same 0.01
lets elephant, bowl_gso and shoe parts go to 0.5 (a step at the head, the leg tops, the foot). The coefficient test is,
in shape, about three times stricter than its number: it cuts the corners and steps, and the smooth drifting stretches too.
So the knob is the tolerance in shape: a fraction of a layer.</div>
uÊ  
<h2>The dino's body part: the height polynomial</h2>
<p class="mut"><code>scripts/part_profile.py dino 1e4 50</code> and <code>dino 1e2 24</code>: the largest part, the sliced rings at
the layer centres (dots) and the stored polynomial drawn continuously at 1024 and 6144 atoms (equivalent radius, five single
coefficients, the shape miss at the centres).</p>
<div class="box"><b>With the ground truth</b> (grey: the mesh sectioned at 10 heights per layer, the part's ring; bottom panel,
lines: the polynomial against it at every height, dots: against the sliced rings at the centres).
<b>Inside (41-65)</b> the true section is smooth and the 6144 polynomial follows it to about 0.12 of a layer between the
centres too (0.05-0.08 at them); at 1024 it is 0.4-0.65 everywhere: the budget, not the partition.
<b>The top end (66-70)</b> is a real event: the true section jumps at 66.4 (radius 16.1 â†’ 17.9 â†’ 16.7, x centroid -5 â†’ -9.5
â†’ -7.5) and again at 68.2 (16.5 â†’ 17.6): something joins the body ring, twice, between layers. The part runs on through it
in both settings (a cut there would leave 2 layers, FIT_MIN = 4), and no polynomial follows a step: 1.5 layer heights off
between the centres at 6144, though 0.07 at them.
<b>The bottom end (39-40)</b> is smooth in truth; with KAPPA 1e4 the polynomial swings there anyway (more than 2 layers off
between the first centres; beyond the end centres up to 193 layer heights of radius): the ill-conditioning KAPPA 1e2
prevents. The default follows it.
Note: the SDF decode does not read the polynomial between the centres (it interpolates the rings' signed distance), so the
lines between the dots are the polynomial's behaviour, not the mesh's.</div>
<img src="img/profile_dino_k10000_M50.png" alt="dino profile KAPPA 1e4" loading="lazy">
<img src="img/profile_dino_k100_M24.png" alt="dino profile default" loading="lazy">
<h2>Why 1024 atoms is wavy, and a smaller dictionary</h2>
<div class="box"><b>The cap on the atom count changes nothing below it</b>: the selection is one projection and one sort, so
<code>MAX_ATOMS</code> = 2048 and decoding 1024 gives the dino's descriptor and mesh bit for bit as 6144 does. The waves at
1024 are the selection's: it keeps the atoms of largest energy (185 of 1021 values in the dino's body part, scattered over
degrees 0-16), so the error left is the sum of the dropped degree polynomials, an oscillation along the height
(0.4-0.6 of a layer). <b>A smaller dictionary</b> (<code>scripts/nm_sweep.py</code>; the cut test fits with the same M, so
a lower M also cuts more): lowering N loses the angular detail (8 / 8: Chamfer 1.07-1.17 times, normals 1.6-1.8 times at
1024 / 2048; the battery and the open box worst); the dino's body at N 8, M 8 is smooth along the height at 1024 (degrees up
to 4 kept) but 0.35-0.55 of a layer off the ground truth, and 0.25-0.5 still at 6144: 8 harmonics cannot draw its section
(the dots there are the N 8 rings, not the truth). Keeping N 16 and lowering M only: Chamfer within 0.4 % at every budget;
normals over 30Â° 8 % fewer at 256 (M 12 or 8), 4-10 % more at 1024 / 2048; elephant better (42.5 â†’ 37.2 % at 1024, M 8),
dress worse. A lower degree trades the waves for more parts; at 1024 the error stays about the same size.</div>
a<  
<img src="img/profile_dino_k100_N8_M8.png" alt="dino profile N8 M8" loading="lazy">
<h2>Step 3: the fewest parts for a tolerance</h2>
<p class="mut"><code>scripts/dp_split.py</code>: each track partitioned by dynamic programming into the fewest pieces (at
least FIT_MIN = 4 layers) whose full fit misses no ring by more than the tolerance; among those the least total squared miss
(cuts on the events). <code>dp-coef</code>: the package's measure and tolerance (coefficients, 0.01), so its difference from
<code>greedy</code> (the package) is the search alone; <code>dp-shape-t</code>: the miss in shape, the tolerance t layer
heights. Worst part miss: over all parts of all objects, the full fit's worst ring, in shape (layer heights). Ratios to
greedy. Renders at 1024 atoms below the tables (6144 in <code>img/</code>).</p>
a§  
<h2>Step 4: cut where the shape jumps between neighbouring rings</h2>
<p class="mut"><code>scripts/ring_steps.py</code>: along each track (before any cut), the shape change from one ring to the
next (each ring evaluated at 256 points from its Fourier series, the RMS distance of each one's points to the other's
polyline, both ways: no fit, and no dependence on where a ring starts), log scale, with the package's cuts (red).
<code>scripts/spike_split.py</code>: a cut where that step is at least 2.5 times the median of the steps within 4 layers
on either side and at least one layer height; pieces down to 2 layers. <code>spike</code>: nothing else;
<code>spike+fit</code>: then the package's cut search inside any piece whose fit still misses by more than 0.25 of a layer
in shape.</p>
<div class="box">The events stand out as spikes over a slowly varying baseline (0.02-1.5 layer heights). The dino's long
track is cut by the package on its spikes already (11.5, 29.5, 38.5, 68.5; 66.5 not, as it would leave 2 layers). The
elephant's body has spikes at 8, 13, 26, 30, 50-51, 64, 89, 91, 96, and the package cuts on some (13, 51, 91), between 26 and
30, and on flat stretches at 19, 36, 61, 70, 77; 64, 89, 96 not. The bowl's wall is smooth from 9 to 114 (falling from 1 to
0.02 as it turns vertical); its spikes are the bottom edge (6-8, up to 15 layer heights) and the rim (115+), and the
package's cuts at 14.5 and 26.5 sit on the smooth stretch, fencing off the bottom edge that is too close to the end to cut.
First three objects: spikes alone leave the bowl's bottom edge inside (between the track's first two rings: a cut would
leave one ring; 14.8 layer heights off) and an elephant piece at 0.47; with the check: elephant 27 parts (0.21), bowl 5
(0.10, one fewer than the package), dino 28 (0.24 against the package's 25 at 0.38: the two-layer pieces at its joins).</div>
<img src='img/steps_elephant.png' alt='steps elephant' loading='lazy'><img src='img/steps_dino.png' alt='steps dino' loading='lazy'><img src='img/steps_bowl_gso.png' alt='steps bowl_gso' loading='lazy'><img src='img/steps_horse.png' alt='steps horse' loading='lazy'><img src='img/steps_shoe.png' alt='steps shoe' loading='lazy'>
Úspike_splitÚspikeuV  
<h2>Step 5: cut only when coefficients AND shape miss</h2>
<p class="mut"><code>scripts/and_test.py</code>: the package's cut search unchanged; a piece is cut only when its fit misses
a ring by more than 0.01 in coefficients (the points at the same t) and by more than t layer heights in shape (closest
points). Sliding along the ring (large in coefficients, small in shape) no longer cuts.</p>
<div class="box">It changes little: 134 parts â†’ 133 (t = 0.15, 0.2), 129 (0.25), 128 (0.3); Chamfer within 0.2 % at every
budget, normals within 1.5 %. Only a handful of the package's cuts come from sliding: the rest are misses of more than 0.3 of
a layer in shape, real changes the polynomial does not follow. With the cut test as the lever, there is little room to
make parts bigger at the same accuracy.</div>
<div class="box"><b>Why so little</b> (<code>scripts/and_scatter.py</code>: every piece the package's cut search tests, its
fit's worst miss in coefficients and in shape). 144 pieces tested on the ten meshes, 60 cut. The shape miss is about half
the coefficient miss (median 0.48; 10-90 % 0.27-0.73), and the points sit close to that line: a piece that fails the
coefficient test (over 0.58 of a layer) is almost always over 0.3 of a layer in shape too. Of the 60 cuts, the shape miss
is under 0.15 for 1, under 0.25 for 5, under 0.3 for 6, under 0.4 for 9, under 0.58 (the same number as the coefficient
tolerance) for 12. AND spares only those; the rest are real shape misses.</div>
<img src="img/and_scatter.png" alt="coefficient and shape miss of every tested piece" loading="lazy" style="max-width:720px">
Úand_testÚandu  
<h2>The mug's handle: where coefficients and shape part ways</h2>
<p class="mut"><code>scripts/mug_handle.py mug</code>: along the body track, the step between neighbouring rings in
coefficients (points at the same t: what the fit sees) and in shape (closest points), with the package's cuts; below, the
rings around the four largest steps (start point dotted; the slice's other rings, the handle, in grey).</p>
<div class="box">Layers 28-38: the handle's root grows out of the body ring as a lobe; the coefficient step (about 3 layer
heights) is 2.7 times the shape step (1.1): the lobe adds length and every point slides. The package does not cut there:
the fit follows it, and the body part 6-38 holds the whole root. 38 â†’ 39: the lobe pinches off and becomes its own ring (the
handle hole appears): the body ring loses a lobe of about 8 layer heights in one layer, shape step 7.8 (19 in
coefficients), and the package cuts exactly there. 94 â†’ 95 and 101 â†’ 102: the handle joins from above in one layer (4.3) and
pinches off again (5.6): cuts at 93 and 102. The rim (119 â†’ 121): 47 in coefficients against 5 in shape (the start point
jumps), then a real jump of 31: cut at 113. The cuts are on real jumps of the outline, which both measures see; where only
the coefficients jump, the fit follows, or a real jump is next to it. To keep the handle region in the body's part, the part
would have to hold a lobe that vanishes within one layer: no height polynomial can, whatever the cut rule. The way out is
the tracking: the lobe as its own part from where it starts to grow (a ring split at its neck).</div>
<img src="img/handle_mug.png" alt="mug handle steps" loading="lazy">
<h2>Step 6: rings split at their necks before tracking (prototype)</h2>
<p class="mut"><code>scripts/neck_split.py mug</code>: every solid ring cut at its narrowest neck (the pair of points with the
least chord / shorter arc, under 0.3, chord inside, both pieces at least 3 % of the area), then the package's tracking,
Fourier and cut rule unchanged.</p>
<div class="box">Mug: 4 tracks â†’ 12, 8 parts â†’ 16 (worst part miss 0.15 â†’ 0.18 of a layer). The handle becomes three parts
(lower root 33-39, handle 40-95, upper root 96-100), but the body is still cut at 33 and 96: the neck forms only once the
lobe is longer than it is wide, so the body ring still holds the short bump at 28-32 and loses it at 33 (a smaller jump,
still cut). The rim's thin lip (120-121) is shredded into 7 parts. To work, a split found at one layer would have to be
carried down the track to the layers where the lobe is still a bump (two passes), and thin rings (rims, walls) kept whole.
Not run on the other objects.</div>
<img src="img/neck_mug_package_a6144.png" alt="mug package" loading="lazy">
<img src="img/neck_mug_neck_a6144.png" alt="mug rings split at necks" loading="lazy">
<h2>Step 7: momentum, the body goes on and the lobe is peeled off (prototype, mug)</h2>
<p class="mut"><code>scripts/momentum.py mug</code>: after tracking, a long solid track is fitted along the height on the layers
it follows; at the others the clean body is interpolated (PCHIP per coefficient) from the undisturbed layers on either side.
Where a ring is the clean ring plus a lobe (reaching 2 layer heights out, meeting the clean ring along at most 40 % of it),
the track keeps ring AND clean ring and the lobe (widened 1.5 layer heights into the body, so the parts overlap) goes to the
track it touches (the handle). Then the package's cut rule.</p>
<div class="box">The body is one part from the base to layer 96, through the lower handle attachment (the package: 6-38,
39-92, 93-101); the lower root joins the handle's track (one cut left at 39, where the handle hole opens: a real ledge).
The upper attachment only partly (the body flares towards the rim there; the body cut at 97). 9 parts against 8, worst part
miss 0.14 against 0.15. Accuracy: Chamfer 0.296 / 0.228 / 0.223 against 0.282 / 0.225 / 0.220 at 256 / 1024 / 6144; normals
over 30Â° 13.8 / 2.8 / 1.9 % against 12.7 / 0.96 / 0.52 %. The overlap costs it: the decoder's signed distance at a layer is
to the nearest ring edge, the lobe's edges inside the body included, and near the junction those inner edges bend the field.
Parts that overlap are inside for the decoder, but its distance assumes rings that do not. Making this pay would take a
union distance in the decoder (each part's own distance, then the largest), on NumPy, numba and CUDA, bit for bit.</div>
<img src="img/momentum_mug_package_a6144.png" alt="mug package" loading="lazy">
<img src="img/momentum_mug_momentum_a6144.png" alt="mug momentum" loading="lazy">
<h3>With the union distance in the decoder (worktree <code>../fcp_devel_union</code>, branch <code>union-sdf</code>)</h3>
<div class="box">Decoder: the distance at a layer is measured only to segments on the region's boundary (a segment whose
midpoint the other rings put inside the region on both of its sides is left out; the parity unchanged); one host flag table,
the same on NumPy, numba and CUDA; disjoint or nested rings unchanged; all 281 tests pass. On the mug the flags work (the
buried segments at the lower root, 28-38) and the bad normals there are gone. What is left is the upper attachment
(95-101), right where the body flares towards the rim: the clean body predicted from below does not flare, so part of what
is peeled is a band around the rim, not the handle. Peeled patchily (95, 100, 101): 9 parts, normals over 30Â° 2.8 / 2.0 %
at 1024 / 6144 against 0.97 / 0.57; peeled whole (95-101): 8 parts with the body 6-102 one part, but Chamfer 0.75 against
0.22 (the band, drawn with 16 harmonics, wanders into the cavity). The lower attachment shows the idea works where the body
is predictable; near the rim it does not yet.</div>
<img src="img/momentum_union_mug_momentum_a6144.png" alt="mug momentum, union decoder" loading="lazy">
<h2>v6</h2>
<p>The v6 work (the evaluation on meshes and clouds, the short-track filter, <code>atoms="auto"</code>, lobe parts) has its own
report: <a href="../../fcp_2910_v6/report/index.html"><code>fcp_2910_v6/report/index.html</code></a>.</p>
<h2>Per object</h2><p>zl</p>
<p class="mut">Green / red: better / worse than the default row by 2 % (Chamfer) or 5 % (normals).</p>
z
</body></html>z
index.html)r   rb   r1   rl   ra   r˜   rc   ÚCSSÚtimeÚstrftimerp   ÚNOTESr   rÄ   r   r   r™   rš   Ú	read_textrß   rø   r  r(  r¤   Ú
write_text)rq   rr   rx   ÚnavÚpages        r   Úmainr9  !  s˜  € Ý‰6Œ6€DÝÐ/Ð/¨$Ð/Ñ/Ô/µSÐ9Ñ9Ô9€GÝ•—’Ð8Ð8°4Ð8Ñ8Ô8Ñ8Ô8Ñ9Ô9€DØ
�(Š(Ð;Ð;°dÐ;Ñ;Ô;Ñ
;Ô
;€CðE÷ Eò Eð Eð Eð EÝqtðEð Eð Eð Eõ ”Ð.Ñ/Ô/ðEð Eð Eð Eõ QTÐTXÑPYÔPYð	Eð Eð Eð Eõ cfÐfjÑbkÔbkð	Eð Eð Eð Eõ ðEð Eð Eð Eð  Ð9…ˆˆwÑÔÐÐ%9ðEð Eð Eð Eõ �„ðEð Eð Eð Eõ6 rxð  {Nñ  rN÷  qVò  qVñ  qXô  qXð  v`Õuyô  vAõ  CIð  L_ñ  C_÷  Bjò  Bjñ  Blô  Blñ  vmô  vmð  vmð  ^`ð7Eð Eð Eð EõB �„ðCEð Eð Eð Eõx �„ðyEð Eð Eð Eõx �„ðyEð Eð Eð EõJ �„ðKEð Eð Eð Eõp ˆM˜7Ñ#Ô#ðqEð Eð Eð EõP ˆJ˜ÑÔðQEð Eð Eð EðD ðEEð Eð Eð EõH ˆD�'ÑÔðIEð Eð Eð Eñ Eô E€DõL ˆlÑ×&Ò& tÑ,Ô,Ð,Ð,Ð,r   Ú__main__)r   )r  r  )Ú__doc__r   r™   r2  Úcollectionsr   Úpathlibr   Únumpyrf   Ú__file__ÚresolveÚparentr   re   r1  r4  r   r   r'   r   r¤   rÄ   rß   rø   r  r(  r9  Ú__name__r   r   r   ú<module>rC     st  ððð ð €
€
€
Ø €€€Ø €€€Ø #Ð #Ð #Ð #Ð #Ð #Ø Ð Ð Ð Ð Ð à Ð Ð Ð à	ˆˆh‰Œ×	Ò	Ñ	!Ô	!Ô	(Ô	/°(Ñ	:€Ø#€ð€ð	€ð$eð eð eð
)ð )ð )ðKð Kð Kð Kðð ð ð8ð ð ð<" ð " ð " ðJ ð  ð  ðFð ð ð<ð ð ð>%ð %ð %ð %ðPK-ð K-ð K-ð\ ˆzÒÐØ€D�F„F€F€F€Fð Ðr   