"""
代码前提:
此模块用于,获取指定目录下的所有scenetree.json文件,并生成分层数据,
最后一级子目录下,只有一个scenetree.json文件。
启动代码:
1.
python getFloorsNodes9.py
1.
获取BIM模型的sceneTree.json文件的每一分层的所有节点名及其子节点id,
并写到文件(sceneTree.json目录/floorsNodes/下)。
每一个文件名是分层名,文件内容包含分层名及其子节点id,文件格式是json格式。
文件数据结构类似这样:
{"floorName": "-0.45", "childrenNodesIds": {"289": 0, "13381": 0, "5893179": 0, "40908": 0, "5985307": 0, "68078": 0, "6078149": 0}}
2.
获取所有分层的名字写到文件floorsNames.json。
文件数据结构类似这样:
{"floorsNames": ["-0.45", "室外地坪", "1F", "2F", "3F", "4F", "5F", "6F", "7F", "8F", "9F", "10F", "11F", "12F", "13F", "14F", "15F", "16F", "17F", "18F", "19F", "20F", "RF", "86.9", "88"]}
"""
from pprint import pprint
import json
import os
def readWriteJSONFile(pathFile):
"""
此函数用于,处理一个json文件,把文件中的所有单引号替换成双引号。
"""
with open(pathFile, "r", encoding="utf-8") as f:
floorsNames = f.read()
# print(floorsNames)
floorsNames = floorsNames.replace("'", "\"")
# print(floorsNames)
with open(pathFile, "w", encoding="utf-8") as f:
f.write(floorsNames)
def get_abs_paths(directory, totalPathFiles=[]):
"""
此函数旨在获取directory目录下,所有文件的绝对路径,
并放在totalPathFiles里。
directory下可以同时有目录和文件。
totalPathFiles列表只在函数初始化时创建,分配固定起始地址的存储空间。
"""
FFs = os.listdir(directory)
# print(FFs)
for f in FFs:
totalPathFile = os.path.join(directory, f)
if os.path.isfile(totalPathFile):
# print(totalPathFile)
totalPathFiles.append(totalPathFile)
else:
get_abs_paths(totalPathFile, totalPathFiles)
return totalPathFiles
def mkdirs(path):
# 去除首位空格
path = path.strip()
# 去除尾部 \ 符号
path = path.rstrip("\\")
# 判断路径是否存在
# 存在 True
# 不存在 False
isExists = os.path.exists(path)
# 判断结果
if not isExists:
# 如果不存在则创建目录
# 创建目录操作函数
os.makedirs(path)
# print(path+' 创建成功')
return True
else:
# 如果目录存在则不创建,并提示目录已存在
print(path + ' 目录已存在')
return False
def writeFloor_NodesToFile(floorData, currentDirectory):
"""
此函数用于,把分层节点及其子节点id写到文件,文件名是分层名。
"""
# print(floorData['floorName'])
# mkdirs(currentDirectory + "\\floorsNodes")
with open(currentDirectory + "\\floorsNodes\\" + floorData['floorName'] + '.json', 'wb') as f:
f.write(str(floorData).encode('utf-8'))
def getFloor_Nodes(floor, floorData):
"""
此函数用于,获取一层的数据floorData。
该数据包括该层的层名及其附属节点id。
floorData数据结构类似这样:
{'floorName': '-0.45', 'childrenNodesIds': {'289': 0, '13381': 0, '5893179': 0, '40908': 0, '5985307': 0, '68078': 0, '6078149': 0}}
floor,是分层json对象,是全局变量children数组的成员,数据结构类似这样:
{'children': [{'children': 0,
'id': 289,
'sphere': [0, 0, 0, 0],
'type': 'IfcAnnotation'},
{'children': [{'children': 0,
'id': 13381,
'name': '现场浇注楼梯:楼梯:373762 Run 1',
'sphere': [-2177693.38667827,
4388599.94903105,
4070236.88168458,
1.00933146190932],
'type': 'IfcStairFlight'},
{'children': 0,
'id': 5893179,
'name': '栏杆扶手:1050mm 圆管:374422',
'sphere': [-2177693.85827209,
4388600.89941588,
4070236.65854068,
0.873587672398189],
'type': 'IfcRailing'}],
'id': 13225,
'name': '现场浇注楼梯:楼梯:373762',
'sphere': [0, 0, 0, 0],
'type': 'IfcStair'},
{'children': [{'children': 0,
'id': 40908,
'name': '现场浇注楼梯:楼梯:385103 Run 1',
'sphere': [-2177805.4527059,
4388554.60290546,
4070225.7275786,
0.998299335119483],
'type': 'IfcStairFlight'},
{'children': 0,
'id': 5985307,
'name': '栏杆扶手:1050mm 圆管:385106',
'sphere': [-2177805.91150105,
4388555.52749761,
4070225.48051487,
0.825957508837764],
'type': 'IfcRailing'}],
'id': 40751,
'name': '现场浇注楼梯:楼梯:385103',
'sphere': [0, 0, 0, 0],
'type': 'IfcStair'},
{'children': [{'children': 0,
'id': 68078,
'name': '现场浇注楼梯:楼梯:386551 Run 1',
'sphere': [-2177739.62261367,
4388575.6897725,
4070238.21308496,
0.998299335119483],
'type': 'IfcStairFlight'},
{'children': 0,
'id': 6078149,
'name': '栏杆扶手:1050mm 圆管:386554',
'sphere': [-2177740.08140882,
4388576.61436465,
4070237.96602122,
0.82595750883776],
'type': 'IfcRailing'}],
'id': 67921,
'name': '现场浇注楼梯:楼梯:386551',
'sphere': [0, 0, 0, 0],
'type': 'IfcStair'}],
'id': 115,
'name': '-0.45',
'sphere': [0, 0, 0, 0],
'type': 'IfcBuildingStorey'}
"""
for child in floor['children']:
if child['children'] == 0:
floorData['childrenNodesIds'][str(child['id'])] = 0
else:
getFloor_Nodes(child, floorData)
floorData['floorName'] = floor['name']
def getFloors_Nodes(children, currentDirectory):
"""
此函数用于,获取每一分层的数据,并写入文件。
一个分层数据写到一个文件,文件名为分层名。
文件内容类似这样:
{'floorName': '-0.45', 'childrenNodesIds': {'289': 0, '13381': 0, '5893179': 0, '40908': 0, '5985307': 0, '68078': 0, '6078149': 0}}
"""
mkdirs(currentDirectory + "\\floorsNodes")
# 循环遍历所有的分层
for child in children:
# 每层清空一次floorData,以确保每一层都是自己层的数据。
floorData = {'floorName': 0, 'childrenNodesIds': {}}
# 把floorData作为参数传给函数,填充数据。
# 此函数不用返回,因为floorData就是此处传入的,处理后直接使用即可。
getFloor_Nodes(child, floorData)
# print("floorData:", floorData)
writeFloor_NodesToFile(floorData, currentDirectory)
# break
def getAllFloorsNames_writeToFile(children, pathFile):
"""
此函数用于,获取所有的分层名,并写到文件。
children, 所有分层对象的数组。
pathFile, 要写入文件的绝对路径。
"""
floorsNames = {"floorsNames": []}
for child in children:
floorsNames["floorsNames"].append(child['name'])
# print(floorsNames)
# print(len(floorsNames["floorsNames"]))
with open(pathFile, 'wb') as f:
f.write(str(floorsNames).encode('utf-8'))
readWriteJSONFile(pathFile)
def getChildren(sceneTreeDict):
"""
此函数用于,获取scenetree.json文件的所有层对象的数组,并返回。
sceneTreeDict,是scenetree.json文件的内容的字典形式。
"""
# children = sceneTreeDict['children']
# print(children[0]['name'])
# print(children[0]['name'] == sceneTreeDict['name'])
# print(sceneTreeDict['children'][0]['name'])
if sceneTreeDict['children'][0]['name'] != sceneTreeDict['name']:
# pprint(sceneTreeDict['children'][8])
# print(type(sceneTreeDict['children']))
# print(len(sceneTreeDict['children']))
return sceneTreeDict['children']
else:
return getChildren(sceneTreeDict['children'][0])
def hanldeOneScenetreeFile(scenetreePathFile):
"""
此函数用以处理一个scenetree.json文件,生成分层数据。
scenetreeFilePath,一个scenetree.json文件的绝对路径,
类似这样:
'D:\\Gaoshengjie\\龙哥任务\\BIM分层\\小学\\南站九年一贯制学校风雨操场食堂模型0404\\楼板\\scenetree.json'
"""
# 模型scenetree.json文件的绝对路径。
# modelSceneTree = "scenetree.json"
# 只处理scenetree.json文件。
currentDirectory = '\\'.join(scenetreePathFile.split('\\')[:-1])
# print("currentDirectory:", '\\'.join(scenetreePathFile.split('\\')[:-1]))
if scenetreePathFile.split('\\')[-1] == 'scenetree.json':
print(scenetreePathFile)
# 读取该文件。
with open(scenetreePathFile, "rb") as f:
sceneTreeStr = f.read().decode("utf-8")
# 把js对象null替换成0。以下可作为判断其是否有子节点的条件。
sceneTreeStr2 = sceneTreeStr.replace('null', '0')
# 把字符串对象转换成python的字典对象。
sceneTreeDict = json.loads(sceneTreeStr2)
# print(len(children)) # 25
# len(children)就是层节点的个数。
# 层节点下最后一级节点就是特性(feature)节点。
# children,是一个数组,里边的每一个成员是一个json对象。该对象保存着该模型场景树的(可用来分层的)层节点及其子节点。
# children = sceneTreeDict['children']
# pprint(sceneTreeDict)
# print(type(sceneTreeDict))
children = getChildren(sceneTreeDict)
# print(type(children))
# print(len(children))
# pprint(children[0])
getAllFloorsNames_writeToFile(children, currentDirectory + "\\floorsNames.json")
getFloors_Nodes(children, currentDirectory)
# 以下要对directory目录下的json文件进行修改,把所有的单引号改成双引号。
directory1 = currentDirectory + "\\floorsNodes"
# print("directory1:", directory1)
totalPathFiles = get_abs_paths(directory1, [])
# print("totalPathFiles:", totalPathFiles)
# print(len(totalPathFiles))
print()
for pathFile in totalPathFiles:
# print(pathFile)
readWriteJSONFile(pathFile)
def main(directory):
"""
主函数。
"""
# 以下要获取目标目录下所有的scenetree.json文件的绝对路径的列表。
totalPathFiles = []
get_abs_paths(directory, totalPathFiles)
# print(totalPathFiles)
# print(len(totalPathFiles))
for scenetreePathFile in totalPathFiles:
hanldeOneScenetreeFile(scenetreePathFile)
# break
if __name__ == "__main__":
# 要处理的scenetree.json文件的目录。
directory = r"D:\Gaoshengjie\龙哥任务\BIM分层\小学"
main(directory)
print("done!")
3dtiles getFloorsNodes9.py
最新推荐文章于 2025-05-15 23:42:24 发布
