Hello,
I would like to compare the names of the layers present on several files in the same directory.
For this I made a code in Python which works but I get blank lines between each data.
I tried to add the newline=‘’ argument in the open function but Rhino said: ‘open() got unexpected keyword argument ‘newline’’
import rhinoscriptsyntax as rs
import os
import Rhino
import csv
# Chemin du repertoire contenant les fichiers .3dm
folder_path = "C:\Users\Utilisateur\AppData\Roaming\Z-Kreat\Moules_simp"
Fichiers = []
Calque = []
Calques = []
# Parcourir les fichiers dans le repertoire
for filename in os.listdir(folder_path):
# Verifier que le fichier est un fichier .3dm
if filename.endswith(".3dm"):
# Ouvrir le fichier
file_path = os.path.join(folder_path, filename)
rs.DocumentModified(False) # Desactive la sauvegarde auto
rs.Command("_-Open " + '"' + file_path + '"' + " _Enter") # Ouvre le fichier
rs.Command("_-SelAll _Enter") # Selectionne tous les objets
rs.Command("_-Properties _Enter") # Ouvre la fenetre des proprietes
Fichiers.append(filename)
#list of layer names
layers = rs.LayerIds()
# Recuperer les noms des calques
for layer in layers:
Calque=[(rs.LayerName(layer))]
Calques.append(Calque)
print(Fichiers)
print(Calques)
with open('Calques.csv',"w", newline='') as f:
writer = csv.writer(f)
writer.writerow(Fichiers)
writer.writerows(Calques)
Maybe it’s fixed by Iron Python supporting unicode natively under the hood, but the Python 2 csv module doesn’t add enough value to justify its criminal lack of support for unicode. To write a csv file with no commas in the entries, the simplest thing to do is:
with open('Calques.csv',"w", newline='') as f:
f.write(','.join(Fichiers))
f.write(','.join(Calques))
newline is only a supported keyword argument for open in Python 3:
Rhino runs Iron Python 2.7 (largely compliant with CPython 2.7’s core modules):
import rhinoscriptsyntax as rs
import os
import Rhino
# Chemin du repertoire contenant les fichiers .3dm
folder_path = r"C:\Users\User\Desktop\CSV_Test"
fichiers = []
calques = []
rs.EnableRedraw(False)
# Parcourir les fichiers dans le repertoire
for filename in os.listdir(folder_path):
# Verifier que le fichier est un fichier .3dm
if filename.endswith(".3dm"):
# Ouvrir le fichier
file_path = os.path.join(folder_path, filename)
rs.DocumentModified(False) # Desactive la sauvegarde auto
rs.Command("_-Open " + '"' + file_path + '"' + " _Enter") # Ouvre le fichier
rs.Command("_-SelAll _Enter") # Selectionne tous les objets
rs.Command("_-Properties _Enter") # Ouvre la fenetre des proprietes
fichiers.append(filename)
# Recuperer les noms des calques
for layer_name in rs.LayerNames(): calques.append(layer_name)
#print(fichiers)
#print(calques)
with open(r'C:\Users\User\Desktop\CSV_Test\calques.csv',"w") as f:
f.write(','.join(fichiers)+"\n")
f.write('\n'.join(calques))
You might need to replace
f.write(','.join(fichiers)+"\n")
with f.write(';'.join(fichiers)+"\n")
if you need semicolon separated values instead of comma separated values.
Not sure either why you need the lines to select all objects or open Properties, this should not affect anything concerning the export of the file or layer names…
You are right I don’t need the lines to select the objects nor to open the properties window.
In fact what I’m looking for is to have on the first line the names of each file and below in column the layers present in each file.
It will be easier to control the layers of each file.
For the moment I get the first line with the file names but all the layers are in a single column the first.
OK, that’s a bit more complicated, as a .csv is written row by row (line by line) with the separators on each line making the columns, one will have to re-matrix everything to write the lines that way. I can try later (have to go out now). Otherwise you need a real Excel writing tool.
OK, this was fun to figure out - never wrote a nested .csv export before… Try this out and let me know what you think.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rhinoscriptsyntax as rs
import os
import Rhino
# Chemin du repertoire contenant les fichiers .3dm
folder_path = r"C:\Users\user\Desktop\CSV_Test"
fichiers = []
calques = []
rs.EnableRedraw(False)
#créer un compteur pour trouver la la liste de calques la plus longue
max_layer_count=1
# Parcourir les fichiers dans le repertoire
for filename in os.listdir(folder_path):
# Verifier que le fichier est un fichier .3dm
if filename.endswith(".3dm"):
# Créer le cheminement
file_path = os.path.join(folder_path, filename)
# Desactive la sauvegarde auto
rs.DocumentModified(False)
# Ouvre le fichier
rs.Command("_-Open " + '"' + file_path + '"' + " _Enter")
#rajouter le nom du fichier à la liste de fichiers
fichiers.append(filename)
#rajouter la liste les noms des calques du fichier
#pour une liste en ordre alphabétique mettre True au lieu de False
layer_names=rs.LayerNames(False)
#mettre a jour max_layer count
if len(layer_names)>max_layer_count: max_layer_count=len(layer_names)
calques.append(layer_names)
#nous avons maintenant deux listes parallèles:
# - les noms de fichiers
# - une liste des les listes(liste imbriquée/nested list) de calques par fichier
# - plus la longueur de la liste de calques la plus longue
#print "Max layer count={}".format(max_layer_count) #debug
#ouvrir le fichier .csv
with open(r'C:\Users\Mitch\Desktop\CSV_Test\calques.csv',"w") as f:
#ecrire la première ligne (noms de fichiers/colonnes)
f.write(','.join(fichiers)+"\n")
#Nous avons maintenant besoin d'une clause "try except", car certains
#fichiers auront probablement une liste de calques plus longue que d'autres.
for i in range(max_layer_count):
layer_name_list=[]
for j in range(len(fichiers)):
try:
layer_name=calques[j][i]
except:
#null-->la liste des calques de ce fichier est plus courte que
#la valeur actuelle de "i" - donc pour créer une case blanche,
#on va mettre un "empty string"
layer_name=""
#rajouter le nom du calque a la liste
layer_name_list.append(layer_name)
#maintenant on a toute la ligne avec les evtls. cases blanches, écrire
#print ','.join(layer_name_list) #debug
f.write(','.join(layer_name_list)+"\n")
rs.EnableRedraw(True)