Skip to content

Instantly share code, notes, and snippets.

@leblanc-simon
Created November 23, 2018 00:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leblanc-simon/fa9fba9b8ceea66f3c00e243740a2cdd to your computer and use it in GitHub Desktop.
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
<?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