Automatisation de publication sur Autocad
Cad, Python
24 fév 2021
Ce script Python génère un fichier SCR contenant les instructions Autocad pour la publication de tous les DSD du dossier courant. Pour charger ce fichier SCR dans Autocad, il faut utiliser la commande scr
, indisponible sur Autocad LT.
#! python3
#creates a SCR file containing the Autocad commands to publish all DSD files in the current folder. The SCR file must be manually loaded in Autocad.
import os
dirpath = "."
files = os.listdir(dirpath)
scrFileName = str(os.getcwd().split(os.sep)[-1])+"_DSD.scr"
out = ""
out += "filedia 0\n"
for file in files:
fileFull = os.path.abspath(os.path.join(dirpath, file))
root, extension = os.path.splitext(fileFull)
if extension == ".dsd":
out += "-publish "+str(fileFull)+"\n"
out += "filedia 1"
with open(scrFileName, 'w') as outputFile:
outputFile.write(out)
Pour que les DSD génèrent les fichiers PDF avec le bon nom dans le bon dossier il faut les configurer comme suit depuis la fenêtre de publication d'Autocad (commande publish
) :
- Options de publication > Configurer le dossier
- Options de publication > Décocher "Prompt for name" et entrer le nom du fichier PDF désiré
- Bien écraser le DSD après ces règlages.
Convertir tout un dossier de fichiers FLAC en MP3 avec ffmpeg
Windows
1er fév 2021
Même si on a raté le train, il n'est pas déraisonnable de chercher à attraper le suivant. Ainsi, il faut se mettre à Powershell. D'autant que le nouveau Terminal de Windows 10 nous le propose par défaut.
Voici une commande pour convertir tous les fichiers d'un dossier contenant des FLAC en MP3, avec ffmpeg
.
gci -filter *.flac -file | Foreach-Object {ffmpeg -i $_.FullName -ab 320k -map_metadata 0 -id3v2_version 3 "$($_.BaseName).mp3"}
La commande fonctionne avec tout type de fichier que ffmpeg
pourrait réussir à convertir en MP3 et génère simplement une erreur lorsqu'elle recontre un fichier qu'elle ne peut pas traiter.
Configurer les matériaux de tous les objets en "par calque" avec Rhino Python
Python, Rhino3D
26 oct 2020
import rhinoscriptsyntax as rs
import Rhino.DocObjects
def loopBlock(block):
objectsInBlock = rs.BlockObjects(rs.BlockInstanceName(block))
for obj in objectsInBlock:
if rs.ObjectType(obj) != 4096:
action(obj)
else:
loopBlock(obj)
def action(object):
rhino_object = rs.coercerhinoobject(object)
rhino_object.Attributes.MaterialSource = Rhino.DocObjects.ObjectMaterialSource.MaterialFromLayer
rhino_object.CommitChanges()
rs.UnselectAllObjects()
objs = rs.AllObjects(include_lights=True, include_grips=True, include_references=True)
if objs:
for obj in objs:
if rs.ObjectType(obj) == 4096: #block
loopBlock(obj)
else:
action(obj)
else:
print "No objects selectable."
Ce script profite de la routine permettant d'appliquer une action sur tous les objets, même ceux situés à l'intérieur de blocs. Il offre un service bien utile lorsqu'on importe de la géométrie d'un autre modeleur (comme SketchUp par exemple) qui insiste pour configurer tous les matériaux par objet.
On remarquera l'usage de la fonction rs.coercerhinoobject()
qui permet de passer du GUID d'un objet à l'objet Rhino lui même. Ce passage est nécessaire pour utiliser les fonctions de l'API RhinoCommon.
Mise à jour : cette fonction est maintenant intégrée à CHL Tools (0.3)
Le voisin NIMBY
Architecture, Cinema
7 oct 2020
Aspirateur des images du site Baunetz
Web, Python
30 sept 2020
Script Python pour automatiser le téléchargement des images des galeries du site d'architecture Baunetz et Baunetz Architekten. Nécessite Python et les librairies Requests et BeautifulSoup (commandes pip
dans le code ci-dessous).
#! python3
import re
import shutil
import requests # "pip install requests" to install package
from bs4 import BeautifulSoup # "pip install beautifulsoup4" to install package
headers = {'User-Agent': 'Mozilla/5.0'}
inputURL = input("Adresse de la page Baunetz à aspirer :")
#Functions
def downloadFile(url):
url = url.replace("\\","")
filename = url.split("/")[-1]
responseImg = requests.get(url, stream=True)
with open(filename, 'wb') as out_file:
shutil.copyfileobj(responseImg.raw, out_file)
del responseImg
def batchDownload(urls):
print (len(urls),"image(s) trouvée(s).")
c = 1
for url in urls:
downloadFile(url)
print("Téléchargement", c, "/", (len(urls)))
c += 1
#Patterns
patternBaunetz = re.compile("^https?://(www.)?baunetz.de/meldungen/([^.]*).html$")
patternBaunetzArchitekten = re.compile("^https?://(www.)?baunetz-architekten.de/([^/]*)/([^/]*)/projekt/([^/]*)$")
# Baunetz
if patternBaunetz.match(inputURL):
response = requests.get(inputURL, headers=headers)
soup = BeautifulSoup(response.text,"html.parser")
scriptTags = soup.find_all("script")
for scriptTag in scriptTags:
s = str(scriptTag)
if s.find("xxlGalerie.xxlimages") >= 0:
urls = re.findall(r"'url': '(https?://[^']*)'",s)
batchDownload(urls)
del response
else:
print("L'adresse ne correspond pas à une page Baunetz.")
#Baunetz Architekten
if patternBaunetzArchitekten.match(inputURL):
urls = []
response = requests.get(inputURL, headers=headers)
soup = BeautifulSoup(response.text,"html.parser")
#cover img
coverImg = soup.select("div.project-detail-image img")
url = coverImg[0].get("data-src")
urls.append(url)
#imgs on landing page
galleryImgs = soup.select("div.project-detail-gallery__image img")
for img in galleryImgs:
url = img.get("data-src")
urls.append(url)
#more imgs link (completes the slideshow)
moreImgs = soup.select("div[data-additional-images]")
s = str(moreImgs[0].get("data-additional-images"))
moreImgsUrls = re.findall(r'"src":"(https:[^"]*)',s)
for moreImgsUrl in moreImgsUrls:
urls.append(moreImgsUrl)
batchDownload(urls)
del response
else:
print("L'adresse ne correspond pas à une page Baunetz Architekten.")
# End
input("Press Enter to close")
Michel Piccoli sait défendre ses plans
Cinema, Architecture
25 juil 2020
Convertir un PDF en plusieurs PNG avec anticrénélage
Windows, Cad
26 juin 2020
... pour éviter d'avoir à utiliser l'export d'Acrobat qui n'intègre pas d'anticrénélage (anti-aliasing). Cela permet également de gérer les fonds transparents.
Installer ImageMagick, sélectionner l'installation avec la prise en compte des anciennes commandes (notamment convert
). Puis installer Ghostscript. Dans une fenêtre de commande :
convert -density 300 doc.pdf out.png
Modifier -density
pour gérer la résolution.
Actions sur des objets à l'intérieur de blocs dans Rhino
Python, Rhino3D
16 mai 2020
Extrait de code Python pour appliquer une action sur tous les objets d'un calque Rhino, y compris ceux à l'intérieur de blocs – voire de blocs dans d'autres blocs. Les objets à l'intérieur de blocs restant inacessibles pour l'utilisateur, on ne peut pas leur appliquer des commandes de type macro avec rs.Command()
mais uniquement des fonctions Python.
import rhinoscriptsyntax as rs
def loopBlock(block):
objectsInBlock = rs.BlockObjects(rs.BlockInstanceName(block))
for obj in objectsInBlock:
if rs.ObjectType(obj) != 4096:
action(obj)
else:
loopBlock(obj)
def action(object):
rs.ObjectColor(object, [255,100,100]) # or anything else
rs.UnselectAllObjects()
layers = rs.GetLayers("Select Layers")
if layers:
objs = rs.AllObjects(include_lights=True, include_grips=True, include_references=True)
if objs:
for obj in objs:
if rs.ObjectLayer(obj) in layers:
if rs.ObjectType(obj) == 4096: #block
loopBlock(obj)
else:
action(obj)
else:
print "No objects on that layer."
else:
print "No layer selected."
Panneau routier D21b
Rhino3D, Architecture
13 mai 2020
Modèle 3D d'un panneau routier de type D21b. Il s'agit de ceux qui servent d'indication de direction et qui sont parmis les plus fréquents. C'est un ajout très bénéfique aux scènes 3D pour donner du réalisme, de même que le reste du mobilier urbains. Précedemment j'avais diffusé des modèles de mats d'éclairage qui peuvent également servir.
L'archive contient un modèle Rhino (.3dm) avec les panneaux gauche, droite, une et deux lignes. Il y a également un générateur de textures pour le texte de signalisation sous la forme d'un fichier Illustrator (.ai).
L'ensemble est téléchargeable ici.
Récupérer et afficher des singletons avec l'API REST de Cockpit
Javascript, Web
13 avr 2020
Cette fonction ajoute au DOM de la page le contenu d'un singleton Cockpit. Il sera intégré à l'intérieur d'un élément HTML pré-existant, qui servira de conteneur. On passe uniquement le nom du singleton
et le container
à la fonction. Attention, dans cet exemple, le singleton ne doit contenir qu'un seul champ appelé content
. Ne pas oublier de remplacer l'adresse menant vers votre installation de Cockpit et votre jeton (ou token, en anglais) pour l'API.
function printSingleton(container, singleton) { //supports only: singleton with one HTML field named "content"
if(ajaxReady) {
ajaxReady = false;
console.log("Printing singleton : ", singleton);
// Prepare Request
var request = new XMLHttpRequest();
request.open('POST', 'https://YOURWEBISTE.COM/COCKPIT/singletons/get/' + singleton + '?token=YOUR_TOKEN', true);
request.onload = function() {
var data = JSON.parse(this.response);
if (request.status >= 200 && request.status < 400) {
container.innerHTML = data.content;
ajaxReady = true;
} //end request if status=OK
else { // error management, doesn't seem to work
console.log("Cannot load singleton.");
var error = document.createElement("div");
error.textContent("Impossible de charger l'élément.");
container.appendChild(error);
}
} // end request function
// Send request
request.setRequestHeader('Content-Type', 'application/json');
request.send();
} // end if ajaxReady
} // end function
Pour que la requête puisse être autorisée, il faudra également configurer l'API de Cockpit (Settings > API Access > Rules) en y ajoutant la règle suivante :
/api/singletons/get