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")
... 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.
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."
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.
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
Si vous en avez assez d'avoir des voitures immatriculées à Stuttgart ou dans le pays imaginaire du fournisseur de votre modèle 3D de voiture, voici deux Bitmaps de plaque alsacienne calibrées pour les modèles Dosch Design et 3D Squirrel.
Il est possible d'extraire des fichiers 3D en .obj
depuis un objet UnityWeb présent sur un site Web. L'opération grâce à deux outils que sont QuickBMS et Unity Assets Bundle Extrator. Je les ai compilé dans leur version Windows 64-bits dans ce dossier. Pour l'exemple, nous allons prendre le générateur 3D UnityWeb du site du fabricant de luminaires GHM. Si vous êtes intéressés par leur modèles, j'ai téléchargés et compilé l'ensemble des mats d'éclairage GHM et Eclatec (non classés) en fichier OBJ.
Pour commencer, on se rend sur la page qui contient l'élément UnityWeb. Dans l'inspecteur de page Web (F12 sur le navigateur) on cherche à l'onglet Réseau un fichier du type .webgl.data.unityweb
et on le télécharge. Ce fichier est en réalité un fichier compressé, que l'on peut décompresser avec Winrar, tout en gardant la même extension.
Il s'agit maintenant de convertir le fichier .unityweb
décompressé en ficher .unity3d
. Pour cela on utilisera QuickBMS. QuickBMS va tout d'abord demander un script d'extraction, on cherchera le fichier unityweb.bms
fournit dans le dossier plus haut. Puis il va demander un fichier UnityWeb source et l'on pointera vers le fichier que nous venons de décompresser avec Winrar. On obtiendra bien un fichier du type data.unity3d
.
On lance ensuite Unity Assets Bundle Extractor et l'on ouvre ce dernier fichier. On accepte de décompresser (encore) le fichier, que l'on peut renommer data_unpack.unity3d
. Ensuite, le menu déroulant présente la liste des ressources dans le fichier Unity3d. Les modèles 3D sont dans les ressources en .assets
. Séléctionnez en une et cliquez sur « Info », dans l'exemple GHM celui qui nous intéresse est ressources.assets
. Séléctionnez la dernière base de données disponible dans la liste lorsque l'on vous le demande, dans mon cas il s'agit « U2019.2.0f1 ».
La liste des fichiers à extraire s'affiche enfin. On cherche les fichiers de type Mesh. On en sélectionne un ou plusieurs puis fait Plugins > « Export to .obj » pour les exporter en .obj
.
Permet de révéler, entre deux jeux d'objets, les courbes qui sont entièrement superposées à d'autres et qui sont donc équivalentes à des sous-courbes. Cela exclu les intersections en un point et les superposition partielles.
import rhinoscriptsyntax as rs
polylines = rs.GetObjects("Select a set of curves")
subCrvs = rs.GetObjects("Select a set of curves to check for full overlapping with first set")
safeList = []
if subCrvs and polylines:
for subCrv in subCrvs:
overlap = None
for polyline in polylines:
if overlap == None:
intersections = rs.CurveCurveIntersection(subCrv, polyline)
if intersections != None:
for intersection in intersections:
if intersection[0] == 2: #checks for overlap and not point intersection
if intersection[5] == rs.CurveDomain(subCrv)[0] and intersection[6] == rs.CurveDomain(subCrv)[1]: #checks for full overlap and not partial
overlap = True
break
if overlap == True:
safeList.append(subCrv)
rs.SelectObjects(safeList)