Created
November 23, 2018 00:47
-
-
Save leblanc-simon/fa9fba9b8ceea66f3c00e243740a2cdd to your computer and use it in GitHub Desktop.
Gestion des fichiers pour le calcul et l'optimisation des découpes de morceaux de bois
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function buildDxf($original_datas) { | |
$template = ' 0 | |
SECTION | |
2 | |
HEADER | |
9 | |
$ACADVER | |
1 | |
AC1009 | |
0 | |
ENDSEC | |
0 | |
SECTION | |
2 | |
ENTITIES | |
0 | |
LINE | |
8 | |
0 | |
62 | |
8 | |
10 | |
0 | |
20 | |
0 | |
11 | |
0 | |
21 | |
%length | |
0 | |
LINE | |
8 | |
0 | |
62 | |
8 | |
10 | |
0 | |
20 | |
0 | |
11 | |
100 | |
21 | |
0 | |
0 | |
LINE | |
8 | |
0 | |
62 | |
8 | |
10 | |
100 | |
20 | |
0 | |
11 | |
100 | |
21 | |
%length | |
0 | |
LINE | |
8 | |
0 | |
62 | |
8 | |
10 | |
100 | |
20 | |
%length | |
11 | |
0 | |
21 | |
%length | |
0 | |
ENDSEC | |
0 | |
EOF'; | |
$datas = []; | |
$directory = __DIR__.'/wood'; | |
if (false === is_dir($directory)) { | |
mkdir($directory, 0755); | |
} | |
// Clear all files | |
$files = glob($directory.'/*'); | |
foreach ($files as $file) { | |
if (true === is_file($file)) { | |
unlink($file); | |
} | |
} | |
// build datas | |
foreach ($original_datas as $original_data) { | |
list($length, $number) = $original_data; | |
if (false === isset($datas[$length])) { | |
$datas[$length] = 0; | |
} | |
$datas[$length] += $number; | |
} | |
// build DXF files | |
foreach ($datas as $length => $number) { | |
$dxf_content = str_replace('%length', $length, $template); | |
file_put_contents($directory.'/'.$number.'-'.$length.'.dxf', $dxf_content); | |
} | |
// build ZIP | |
$dxf_files = glob($directory.'/*.dxf'); | |
$zip = new ZipArchive(); | |
if (true !== $zip->open($directory.'/dxf.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE)) { | |
die('Impossible to create ZIP file'); | |
} | |
foreach ($dxf_files as $dxf_file) { | |
if (false === $zip->addFile($dxf_file, basename($dxf_file))) { | |
die('Impossible to create ZIP file'); | |
} | |
} | |
$zip->close(); | |
return $directory.'/dxf.zip'; | |
} | |
function getDimension($zip_file) | |
{ | |
$svg_directory = __DIR__.'/wood/svg'; | |
if (false === is_dir($svg_directory)) { | |
mkdir($svg_directory, 0755, true); | |
} | |
// Clear all files | |
$files = glob($svg_directory.'/*'); | |
foreach ($files as $file) { | |
if (true === is_file($file)) { | |
unlink($file); | |
} | |
} | |
// unzip file | |
$zip = new ZipArchive(); | |
if (true !== $zip->open($zip_file)) { | |
die('Impossible to open zip file'); | |
} | |
if (false === $zip->extractTo($svg_directory)) { | |
die('Impossible to extract zip file'); | |
} | |
$svgs = glob($svg_directory.'/*.svg'); | |
$pieces = []; | |
foreach ($svgs as $svg) { | |
if (0 === preg_match('/([0-9]+)\.svg$/', basename($svg), $matches)) { | |
die('pas de nombre :('); | |
} | |
$number = (int) $matches[1]; | |
$parts = []; | |
$piece_length = 0; | |
// Récupération des tailles | |
$dom = new DOMDocument(); | |
$dom->load($svg); | |
$paths = $dom->getElementsByTagName('path'); | |
foreach ($paths as $path) { | |
$dimensions = $path->getAttribute('d'); | |
if (0 === preg_match('/M\s+[0-9]+\s+[0-9]+\s+L\s+[0-9]+\s+([0-9]+)\s+L\s+[0-9]+\s+([0-9]+)\s+L/', $dimensions, $matches)) { | |
die('impossible d\'extraire la dimension :('); | |
} | |
$length = (int) $matches[2] - (int) $matches[1]; | |
if (4000 === $length || 3000 === $length) { | |
// c'est la pièce entière babache ! | |
$piece_length = $length; | |
continue; | |
} | |
$parts[] = $length; | |
} | |
$pieces[basename($svg)] = [ | |
'number' => $number, | |
'parts' => $parts, | |
'length' => $piece_length, | |
]; | |
} | |
// Petit affichage très joli | |
$return_string = ''; | |
$three_meter_nb_pieces = 0; | |
$four_meter_nb_pieces = 0; | |
foreach ($pieces as $piece) { | |
$sizes = implode(', ', $piece['parts']); | |
$return_string .= sprintf( | |
'%d planche%s de %d mètres, découper %d morceaux de : %s', | |
$piece['number'], | |
1 === $piece['number'] ? '' : 's', | |
$piece['length'] / 1000, | |
count($piece['parts']), | |
$sizes | |
)."\n"; | |
if (3000 === $piece['length']) { | |
$three_meter_nb_pieces += $piece['number']; | |
} elseif (4000 === $piece['length']) { | |
$four_meter_nb_pieces += $piece['number']; | |
} | |
} | |
$return_string .= "Nombre de planches de 3 mètres à commander : $three_meter_nb_pieces\n"; | |
$return_string .= "Nombre de planches de 4 mètres à commander : $four_meter_nb_pieces\n"; | |
return $return_string; | |
} | |
$message = ''; | |
if (true === isset($_SERVER['REQUEST_METHOD']) && 'POST' === $_SERVER['REQUEST_METHOD']) { | |
if (true === isset($_FILES) && true === isset($_FILES['svgs'])) { | |
// Envoi du ZIP contenant les SVG | |
$filename = __DIR__.'/svg.zip'; | |
if (true === file_exists($filename)) { | |
unlink($filename); | |
} | |
if (false === move_uploaded_file($_FILES['svgs']['tmp_name'], $filename)) { | |
die('Error while move file'); | |
} | |
$message = getDimension($filename); | |
unlink($filename); | |
} else { | |
// Envoi des mesures | |
$original_datas = []; | |
foreach ($_POST['length'] as $index => $length) { | |
if (true === empty($length) || true === empty($_POST['number'][$index])) { | |
continue; | |
} | |
$original_datas[] = [ | |
$length, | |
$_POST['number'][$index], | |
]; | |
} | |
$zip_file = buildDxf($original_datas); | |
$link = str_replace(__DIR__, '.', $zip_file); | |
$message = ' | |
Télécharger le fichier contenant les DXF : <a href="'.$link.'">'.basename($zip_file).'</a> | |
Il faut utiliser ces fichiers sur le site <a href="https://demo.powernestlib.com/" target="_blank" rel="nofollow noreferrer noopener">https://demo.powernestlib.com/</a> | |
Le nombre d\'éléments à indiquer sur le site est la première partie du nom du fichier. | |
'; | |
} | |
} | |
?><!DOCTYPE html> | |
<html lang="fr"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Optimisation des découpes</title> | |
<style> | |
fieldset { | |
margin-bottom: 2rem; | |
} | |
.button { | |
margin-top: 1rem; | |
} | |
.form { | |
margin-top: 1rem; | |
} | |
.message { | |
margin-bottom: 2rem; | |
background: lightgreen; | |
padding: 1rem; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Optimisation des découpes</h1> | |
<?php if (false === empty($message)) { ?> | |
<div class="message"><?php echo nl2br(trim($message)); ?></div> | |
<?php } ?> | |
<form method="post"> | |
<fieldset> | |
<legend>Prise de mesure</legend> | |
<div class="add"><button id="add_measure">Ajouter une mesure</button></div> | |
<div class="form" id="form_pieces"> | |
<div class="piece"> | |
<label for="length_0">Longeur</label> | |
<input type="number" step="1" min="0" max="4000" id="length_0" name="length[]" required> | |
<label for="number_0">Nombre d'éléments</label> | |
<input type="number" step="1" min="1" id="number_0" name="number[]" required> | |
<button class="remove">Supprimer</button> | |
</div> | |
</div> | |
<div class="button"> | |
<input type="submit" name="submit" value="Récupérer les DXF"> | |
</div> | |
</fieldset> | |
</form> | |
<form method="post" enctype="multipart/form-data"> | |
<fieldset> | |
<legend>Calcul des découpes</legend> | |
<div class="form"> | |
<label for="svgs">Fichier ZIP contenant les SVG (venant de <a href="https://www.dxfconverter.org/" target="_blank" rel="nofollow noreferrer noopener">https://www.dxfconverter.org/</a>)</label> | |
<input type="file" name="svgs" id="svgs"> | |
</div> | |
<div class="button"> | |
<input type="submit" name="submit" value="Voir les découpes à réaliser"> | |
</div> | |
</fieldset> | |
</form> | |
<script> | |
let nbPieces = 1; | |
let formTemplate = `<div class="piece"> | |
<label for="length_%num%">Longeur</label> | |
<input type="number" step="1" min="0" max="4000" id="length_%num%" name="length[]" required> | |
<label for="number_%num%">Nombre d'éléments</label> | |
<input type="number" step="1" min="1" id="number_%num%" name="number[]" required> | |
<button class="remove">Supprimer</button> | |
</div>`; | |
document.getElementById('add_measure').addEventListener('click', function (event) { | |
event.preventDefault(); | |
let formPiece = document.getElementById('form_pieces'); | |
const replaceRegex = new RegExp('%num%', 'g'); | |
formPiece.insertAdjacentHTML('beforeend', formTemplate.replace(replaceRegex, nbPieces)); | |
nbPieces++; | |
}, false); | |
document.addEventListener('click', function (event) { | |
if (false === event.target.classList.contains('remove')) { | |
return; | |
} | |
event.preventDefault(); | |
event.target.parentNode.remove(); | |
}, false); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment