29
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."
28
Panneau routier D21b
Rhino3D, Architecture
13 mai 2020

Panneau D21b et générateur de textes

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.

27
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
26
Plaque minéralogique alsacienne pour 3D
Rhino3D, Cad
10 avr 2020

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.

Plaque alsacienne
Plaque alsacienne
25
Extraire des objets 3D d'un élément Unityweb
Web
3 avr 2020

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 ».

Unity Assets Bundle Extractor
Unity Assets Bundle Extractor

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.

24
Sélectionner les courbes entièrement superposées (ou sous-courbes) avec Rhino Python
Rhino3D, Python
26 oct 2019
SelOverlappingCrvs.py démo

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)
23
Structure de blog en PHP et Javascript avec Cockpit
Php, Javascript, Web
15 sept 2019

Cockpit est un très bon CMS (headless), mais qui possède malheureusement une documentation presque aussi faible que PyQGIS. Pour mémoire et aide, je publie ci-dessous un bout de code PHP qui permet de récupérer les données d'une collection Cockpit et les afficher sur une page. C'est très basique, mais même cela n'est pas la doc.

<?php
require_once("path/to/cockpit/bootstrap.php");


$page = 0;
$articlePerPage = 3;

$posts = cockpit('collections')->find('journal', [
   'limit' => $articlePerPage,
   'skip' => $articlePerPage*$page,
   'sort' => ["date"=>-1], //sorted by user defined "date" entry ; ["_created"=>-1] for last articles created first ; ["_o"=>1] for custom-order
   'filter' => ["tags"=>"myTag"]
]);

if (empty($posts)) {
    echo "Il n'y a pas de billets dans ce journal.".PHP_EOL;
} else {
    foreach ($posts as $post) {
      $title = $post["title"];
      $titleSlug = $post["title_slug"];
      $date = $post["date"];
      $tags = $post["tags"];
      $content = $post["content"];

      echo "
<article>
  <h3>".$title." (".$titleSlug.")</h3>
  <h4>".$date.". # Tags : ".implode(", ",$tags)."</h4>
".$content."
</article>
      ".PHP_EOL;
    }
}
?>

Et voici la même chose avec REST API et XMLHttpRequest en Javascript. La documentation propose d'utiliser fetch mais cette méthode n'est pas supportée par d'anciens navigateurs (Blackberry OS 10 par exemple). Il faut générer un jeton (token) adéquat depuis l'interface d'administration de Cockpit. Le jeton étant ici affiché en clair, pour des raisons évidentes de sécurité, il faut configurer un jeton en lecture seule et uniquement pour la collection recherchée. Voir la documentation Cockpit à ce sujet.

var container = document.getElementById("blog");
var ajaxReady = true; //avoids sending two requests at the same time

function nextPosts() {
  if(ajaxReady) {
    ajaxReady = false;

    // Request
    var request = new XMLHttpRequest();
    request.open('POST', 'path/to/cockpit/api/collections/get/name-of-your-collection?token=YOUR-READ-ONLY-TOKEN', true);
    request.onload = function() {
      var data = JSON.parse(this.response);
      if (request.status >= 200 && request.status < 400) {
        var posts = data["entries"];
        var totalPosts = data["total"];

        for (var i in posts) {
          var post = posts[i];

          // Post elements
          const article = document.createElement("article");

          const articleTitle = document.createElement("h3");
          articleTitle.textContent = post.title;

          const articleDateAndTags = document.createElement("h4");

          var subtitle = post.date + "# Tags : ";
          for (var j in post.tags) {
              var t = post.tags[j] + ",";
              subtitle += t;
          }
          articleDateAndTags.innerHTML = subtitle;

        // Assembly
        article.appendChild(articleTitle);
        article.appendChild(articleDateAndTags);
          article.innerHTML += post.content;

          // Append article to page
          container.appendChild(article);

          postPosition += 1;

          if(postPosition >= totalPosts) {
            console.log("Fin des articles");
          }
        }
        ajaxReady = true;

      } else { 
        console.log("Error");
      }
    }

    // Request's body
    var requestBody = JSON.stringify({
        limit: postsPerLoad,
        skip: postPosition,
        sort: {date:-1},
        filter: {tag:"myTag"}
    });

    // Send request
    request.setRequestHeader('Content-Type', 'application/json');
    request.send(requestBody);
  }
}

nextPosts();
22
PHP Simple HTML Dom compatible PHP 7.3
Php, Web
28 août 2019

Simple_html_dom est un très bon outil (je l'utilise par exemple pour cine-ics), mais il n'est plus mis à jour. Entre passant à PHP 7.3 on a donc quelque problèmes de compatibilité.

En suivant quelques indications trouvées ça et sur StackOverflow, j'ai modifié à minima la librairie pour la faire fonctionner sous PHP 7.3. Aucune garantie si ces modifications causent des problèmes par ailleurs.

Voici le fichier : simple_html_dom_php73.zip.

Pour information, c'est principalement le support pour les offset négatif de la fonction file_get_contents à partir de PHP 7.1 qui semble être la cause des problèmes. La librairie Simple_html_dom utilisait des offsets négatifs comme raccourci de code pour spécifiait des valeurs nulles.

21
La maîtrise d'ouvrage en RDA
Cinema, Architecture
17 juil 2019
Die Architekten, 1990, Peter Kahane (DEFA)
20
La visite de l'appartement type
Cinema, Architecture
18 déc 2018
Le Coup de sirocco, Alexandre Arcady (1979)
Sallah Shabbati, Ephraim Kishon (1964). NB : c'est le plus grand succès du cinéma israélien