同步更改数据
This commit is contained in:
1 parent
ecb58b2f59
commit
33ba8bb357
21 files changed
+2019471
-62
No files matched your search
@@ -0,0 +1 @@
|
||||
libs/__pycache__
|
||||
+25
-5
@@ -18,17 +18,37 @@ ali_oss = {
|
||||
oss_bucket = oss2.Bucket(oss2.Auth(ali_oss['access_key_id'], ali_oss['access_key_secret']), ali_oss['endpoint'], ali_oss['bucket_name'])
|
||||
|
||||
redis_remote = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6)
|
||||
redis_local = redis.Redis(host='172.16.20.13', password='ph2008', port=6379, db=0)
|
||||
redis_local_common = redis.Redis(host='172.16.20.13', password='ph2008', port=6379, db=1)
|
||||
redis_local = redis.Redis(host='172.31.1.254', password='', port=6379, db=0)
|
||||
redis_local_common = redis.Redis(host='172.31.1.254', password='', port=6379, db=1)
|
||||
mysql_local = {
|
||||
"host": "172.16.20.13",
|
||||
"port": 3306,
|
||||
"host": '172.31.1.254',#"172.16.20.13",
|
||||
"port": 23306,
|
||||
"user": "pi",
|
||||
"password": "ph2008",
|
||||
"db": "suwa3d",
|
||||
"charset": "utf8mb4"
|
||||
}
|
||||
|
||||
|
||||
|
||||
mysql_gpu = {
|
||||
"host": 'rm-uf64l0683d2t2jt1c3o.mysql.rds.aliyuncs.com',
|
||||
"port": 3306,
|
||||
"user": "airepair",
|
||||
"password": "Ai_repair@suwa3d",
|
||||
"db": "ai_repair",
|
||||
"charset": "utf8"
|
||||
}
|
||||
|
||||
mysql_dong = {
|
||||
"host": "172.31.1.254",
|
||||
"port": 13306,
|
||||
"user": "api",
|
||||
"password": "api2022",
|
||||
"db": "new_suwa3d",
|
||||
"charset": "utf8mb4"
|
||||
}
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
workdir = 'D:\\'
|
||||
sharedir = 'E:\\'
|
||||
@@ -137,4 +157,4 @@ high_host = ["R11","R12"]
|
||||
low_host = ["R13","R14","R15","R16","R17"]
|
||||
|
||||
#不参与贴图的照片,使用的时候还需要增加指令 python main_step1.py 123 no_texture
|
||||
noTextureColorPics = ["13", "23", "31", "52", "72", "82", "142", "173"] # 昆山老數據不慘與貼圖["134","135","136","142","143","14","15","16","24","25","26","44","45"]
|
||||
noTextureColorPics = ["13", "23", "31", "52", "72", "82", "142", "173"] #["134","135","136","142","143","14","15","16","24","25","26","44","45"]
|
||||
@@ -307,3 +307,27 @@ def diff_time(start_time):
|
||||
m, s = divmod(diff, 60)
|
||||
return f'{int(m)}分{int(s)}秒'
|
||||
|
||||
def down_obj_from_oss_for_fix(workdir, pid, action):
|
||||
if os.path.exists(os.path.join(workdir, action, pid)):
|
||||
print(f'目录{os.path.join(workdir, action, pid)}已存在,跳过')
|
||||
return
|
||||
else:
|
||||
os.makedirs(os.path.join(workdir, action, pid))
|
||||
|
||||
# 根据前缀获取文件列表
|
||||
prefix = f'objs/{action}/{pid}/'
|
||||
filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix)
|
||||
print('正在下载:', prefix)
|
||||
obj_filename = ""
|
||||
for file in filelist:
|
||||
filename = file.key.split('/')[-1]
|
||||
if filename.endswith(f'{pid}.obj') == False:
|
||||
continue
|
||||
|
||||
if filename.endswith('.obj'):
|
||||
obj_filename = filename
|
||||
|
||||
# print('正在下载:', file.key)
|
||||
localfile = os.path.join(workdir, action, pid, filename)
|
||||
config.oss_bucket.get_object_to_file(file.key, localfile)
|
||||
return obj_filename
|
||||
@@ -0,0 +1,213 @@
|
||||
# mysql数据库常用任务函数封装
|
||||
import pymysql, socket, time
|
||||
import config
|
||||
|
||||
#公共连接库
|
||||
def pymysqlAlias():
|
||||
return pymysql.connect(
|
||||
host=config.mysql_dong['host'],
|
||||
port=config.mysql_dong['port'],
|
||||
user=config.mysql_dong['user'],
|
||||
password=config.mysql_dong['password'],
|
||||
db=config.mysql_dong['db'],
|
||||
charset=config.mysql_dong['charset'],)
|
||||
|
||||
|
||||
# 获取新的任务
|
||||
def get_task_by_level():
|
||||
try:
|
||||
with pymysqlAlias() as conn:
|
||||
cursor = conn.cursor()
|
||||
sql = f'select pid from pid_base_fix where status = 0 order by level desc, id asc limit 1'
|
||||
# print(f'sql: {sql}')
|
||||
cursor.execute(sql)
|
||||
data = cursor.fetchone()
|
||||
if data:
|
||||
return data[0]
|
||||
else:
|
||||
return ''
|
||||
except Exception as e:
|
||||
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} get_task_by_level()异常: {str(e)}")
|
||||
return ''
|
||||
|
||||
|
||||
# 开始任务
|
||||
def update_fix_status(pid,status):
|
||||
try:
|
||||
with pymysqlAlias() as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
hostname = socket.gethostname()
|
||||
sql = f'update pid_base_fix set status = {status},createTime = now(), updateTime = now() where status = 0 and pid = {pid}'
|
||||
print(f'开始任务sql: {sql}')
|
||||
cursor.execute(sql)
|
||||
conn.commit()
|
||||
except Exception as e:
|
||||
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行update_fix_status()异常: {str(e)}")
|
||||
|
||||
|
||||
# # 获取新的任务
|
||||
# def get_task(task_type):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
# sql = f'select task_key from tasks where status = 0 order by priority desc, id asc limit 1 for update'
|
||||
# # print(f'sql: {sql}')
|
||||
# cursor.execute(sql)
|
||||
# data = cursor.fetchone()
|
||||
# if data:
|
||||
# return data[0]
|
||||
# else:
|
||||
# return ''
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行get_task({task_type})异常: {str(e)}")
|
||||
# return ''
|
||||
|
||||
# # 新增新的任务
|
||||
# def add_task(data):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
|
||||
# #判断是否是昆山教学的,是的话优先级设置为默认
|
||||
# if data["psid"] == '85':
|
||||
# sql = f'insert into tasks (task_type, task_key,studio_id) values ("{data["task_type"]}", "{data["task_key"]}","{data["psid"]}")'
|
||||
# else:
|
||||
# sql = f'insert into tasks (task_type, task_key, priority,studio_id) values ("{data["task_type"]}", "{data["task_key"]}", {data["priority"]},"{data["psid"]}")'
|
||||
# # print(f'sql: {sql}')
|
||||
# cursor.execute(sql)
|
||||
# conn.commit()
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行add_task({data})异常: {str(e)}")
|
||||
|
||||
# #新增任务到分布式处理任务表中 {"task_type":key,"task_key":pid,"psid":psid}
|
||||
# def add_task_distributed(data):
|
||||
# flag = isInTaskDistributed(data["task_key"])
|
||||
# if flag:
|
||||
# return "already"
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
# sql = f'insert into task_distributed (task_type, task_key, priority,created_at,studio_id) values ("{data["task_type"]}", "{data["task_key"]}", "{data["priority"]}","{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}","{data["psid"]}")'
|
||||
# cursor.execute(sql)
|
||||
# conn.commit()
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行add_task_distributed({data})异常: {str(e)}")
|
||||
|
||||
|
||||
# # 开始任务
|
||||
# def start_task(data):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
|
||||
# hostname = socket.gethostname()
|
||||
# sql = f'update tasks set status = 1, hostname = "{hostname}", started_at = now(), updated_at = now() where status = 0 and task_key = {data["task_key"]}'
|
||||
# print(f'开始任务sql: {sql}')
|
||||
# cursor.execute(sql)
|
||||
# conn.commit()
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行start_task({data})异常: {str(e)}")
|
||||
|
||||
# # 完成任务
|
||||
# def finish_task(data):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
|
||||
# hostname = socket.gethostname()
|
||||
# sql = f'update tasks set status = 2, hostname = "{hostname}", finished_at = now(), updated_at = now() where status = 1 and task_key = "{data["task_key"]}" '
|
||||
# # print(f'sql: {sql}')
|
||||
# cursor.execute(sql)
|
||||
# conn.commit()
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行finish_task({data})异常: {str(e)}")
|
||||
|
||||
# # 根据影棚ID 获取影棚的配置,如果没有指定的配置,则返回默认配置
|
||||
# def get_floor_sticker_distances(psid):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
# sql = f'select a.studio_id,value from floor_sticker_link_studio as a left join floor_sticker_distances as b on a.floor_name = b.name where a.studio_id in (0,{psid})'
|
||||
|
||||
# cursor.execute(sql)
|
||||
# result = cursor.fetchall()
|
||||
|
||||
# if len(result) == 1:
|
||||
# return result[0][1]
|
||||
|
||||
# if len(result) == 2:
|
||||
# for item in result:
|
||||
# if str(item[0]) == str(psid):
|
||||
# return item[1]
|
||||
# return "error-配置异常,该影棚有多个地贴配置"
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行get_floor_sticker_distances()异常: {str(e)}")
|
||||
# return "error"
|
||||
|
||||
# #判断是否要走新的建模系统
|
||||
# def is_new_make_psid(psid):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
# sql = f'select count(*) from new_make_psid where studio_id = {psid}'
|
||||
# print(f'sql: {sql}')
|
||||
# cursor.execute(sql)
|
||||
# result = cursor.fetchone()
|
||||
# if result[0] > 0:
|
||||
# return True
|
||||
# else:
|
||||
# return False
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行is_new_make_psid()异常: {str(e)}")
|
||||
# return "error"
|
||||
|
||||
# #判断影棚是否走的新的建模系统,不是的话修改成走新的建模系统
|
||||
# def change_to_new_make_psid(psid):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
# sql = f'select count(*) from new_make_psid where studio_id = {psid}'
|
||||
# cursor.execute(sql)
|
||||
# result = cursor.fetchone()
|
||||
# if result[0] == 0:
|
||||
# sql = f'insert into new_make_psid (studio_id,createTime) values ({psid},now())'
|
||||
# cursor.execute(sql)
|
||||
# conn.commit()
|
||||
# print(f'修改影棚{psid}为走新的建模系统')
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行change_to_new_make_psid()异常: {str(e)}")
|
||||
# return "error"
|
||||
|
||||
|
||||
# #判断影棚走分布式的建模系统 还是走原来的建模系统
|
||||
# def isStudioConfigDistribute(psid):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
# sql = f'select count(*) from studio_config_distribute where studio_id = {psid} and status = 1'
|
||||
# cursor.execute(sql)
|
||||
# result = cursor.fetchone()
|
||||
# if result[0] == 0:
|
||||
# return False
|
||||
# else:
|
||||
# return True
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行change_to_new_make_psid()异常: {str(e)}")
|
||||
# return "error"
|
||||
|
||||
# #判断是否已经存在了
|
||||
# def isInTaskDistributed(task_key):
|
||||
# try:
|
||||
# with pymysqlAlias() as conn:
|
||||
# cursor = conn.cursor()
|
||||
# sql = f'select count(*) from task_distributed where status = 0 and task_key = "{task_key}"'
|
||||
# cursor.execute(sql)
|
||||
# result = cursor.fetchone()
|
||||
# if result[0] == 0:
|
||||
# return False
|
||||
# else:
|
||||
# return True
|
||||
# except Exception as e:
|
||||
# print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行isInTaskDistributed()异常: {str(e)}")
|
||||
# return "error"
|
||||
@@ -0,0 +1,273 @@
|
||||
import os, sys, time, argparse, requests, json, re, oss2
|
||||
import bpy, bmesh
|
||||
import open3d as o3d
|
||||
import numpy as np
|
||||
# import cupy as cp
|
||||
from mathutils import Matrix
|
||||
import math
|
||||
import logging
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def remove_nan_verts(obj):
|
||||
'''删除模型中空坐标的顶点'''
|
||||
# obj = bpy.context.active_object
|
||||
if obj.mode == 'EDIT':
|
||||
bm = bmesh.from_edit_mesh(obj.data)
|
||||
else:
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(obj.data)
|
||||
|
||||
nans = [v for v in bm.verts if any(c != c for c in v.co)]
|
||||
bmesh.ops.delete(bm, geom=nans, context='VERTS')
|
||||
|
||||
degenerates = [f for f in bm.faces if len(f.verts) < 3]
|
||||
bmesh.ops.delete(bm, geom=degenerates, context='FACES')
|
||||
if obj.mode == 'EDIT':
|
||||
bmesh.update_edit_mesh(obj.data)
|
||||
else:
|
||||
bm.to_mesh(obj.data)
|
||||
obj.data.update()
|
||||
|
||||
print("NAN vertices and degenerate faces removed.")
|
||||
|
||||
def getHeadCount(pid):
|
||||
get_printinfo_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/printInfo'
|
||||
res = requests.get(get_printinfo_url, params={'id': pid})
|
||||
print('get_printinfo_url:', res.url)
|
||||
print('res:', res.text)
|
||||
if res.status_code != 200:
|
||||
print('获取人数失败,程序退出')
|
||||
exit(1)
|
||||
res = json.loads(res.text)
|
||||
return res['data']['headcount']
|
||||
|
||||
def get_obj_bake_vertex_ply(obj_filepath, save_ply_path):
|
||||
start_time = time.time()
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Getting ply vertex from {obj_filepath}')
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.ops.object.select_by_type(type='MESH')
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
bpy.ops.wm.obj_import(filepath=obj_filepath)
|
||||
|
||||
obj_original = [obj for obj in bpy.data.objects if obj.type == 'MESH'][0]
|
||||
bpy.context.view_layer.objects.active = obj_original
|
||||
obj_original.select_set(True)
|
||||
pid = obj_original.name
|
||||
|
||||
obj_num_vertices = len(obj_original.data.vertices)
|
||||
# print(f"模型 {pid} 顶点数量:", len(obj_original.data.vertices))
|
||||
|
||||
# 选择新分离出来的网格对象,并将该对象设为进活动对象
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj_original
|
||||
obj_original.select_set(True)
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Split foot time: ', time.time() - start_time)
|
||||
start_time = time.time()
|
||||
|
||||
# 表面细分Subdivision Surface,如果细分后定点数目大于目标数目,停止循环细分
|
||||
# target_verts = len(obj_original.data.vertices) * 8
|
||||
try:
|
||||
target_verts = getHeadCount(pid) * 2000000
|
||||
except TypeError as e:
|
||||
return 0
|
||||
|
||||
mesh_data = obj_original.data
|
||||
obj_original_name = obj_original.name
|
||||
|
||||
# Blender 网格对象的顶点数据转换为 Open3D 格式
|
||||
o3d_mesh = o3d.geometry.TriangleMesh()
|
||||
o3d_mesh.vertices = o3d.utility.Vector3dVector([v.co for v in mesh_data.vertices])
|
||||
o3d_mesh.triangles = o3d.utility.Vector3iVector([f.vertices for f in mesh_data.polygons])
|
||||
o3d_mesh.compute_vertex_normals() # 计算顶点法线
|
||||
|
||||
# open3d 细分操作
|
||||
for i in range(2, 8):
|
||||
mesh_subdivided = o3d_mesh.subdivide_loop(number_of_iterations=i)
|
||||
subdivision_vertex_count = len(mesh_subdivided.vertices)
|
||||
if subdivision_vertex_count > target_verts:
|
||||
break
|
||||
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Subdivision time: ', time.time() - start_time)
|
||||
start_time = time.time()
|
||||
|
||||
# open3d 减面操作
|
||||
# 官网文档介绍简化网格不能保证一定会达到这个数字
|
||||
target_triangles = target_verts * 2
|
||||
mesh_smp = mesh_subdivided.simplify_quadric_decimation(target_number_of_triangles=target_triangles)
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Decimation time: ', time.time() - start_time)
|
||||
start_time = time.time()
|
||||
|
||||
# 将open3d网格转换回blender网格
|
||||
o3d_to_blender_mesh = bpy.data.meshes.new(name=f"{obj_original_name}_decimation")
|
||||
o3d_to_blender_mesh.from_pydata(mesh_smp.vertices, [], mesh_smp.triangles)
|
||||
o3d_to_blender_mesh.update()
|
||||
obj_open3d = bpy.data.objects.new(f"{obj_original_name}_decimation", o3d_to_blender_mesh)
|
||||
# 设置新对象的位置和旋转信息,等于原始模型的信息
|
||||
obj_open3d.location = obj_original.location
|
||||
obj_open3d.rotation_euler = obj_original.rotation_euler
|
||||
obj_open3d.scale = obj_original.scale
|
||||
bpy.context.collection.objects.link(obj_open3d)
|
||||
# 开始将obj_mesh的贴图颜色烘焙到open3d模型上
|
||||
# 复制对象作为罩体
|
||||
obj_cage = obj_open3d.copy()
|
||||
obj_cage.data = obj_open3d.data.copy()
|
||||
bpy.context.collection.objects.link(obj_cage)
|
||||
obj_cage.name = f"{obj_original_name}_cage"
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj_open3d
|
||||
obj_open3d.select_set(True)
|
||||
bpy.ops.object.mode_set(mode='EDIT')
|
||||
bpy.context.scene.tool_settings.use_uv_select_sync = True # 同步3D_View和UV编辑模式选中顶点部分
|
||||
bpy.ops.uv.smart_project()
|
||||
bpy.ops.uv.select_overlap()
|
||||
bpy.ops.uv.unwrap(method='ANGLE_BASED', margin=0)
|
||||
bpy.ops.uv.select_all(action='SELECT')
|
||||
bpy.ops.uv.average_islands_scale()
|
||||
bpy.ops.uv.pack_islands(margin=0)
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
# 新建open3d模型的材质
|
||||
open3dMat = bpy.data.materials.new(name='Mat_open3d')
|
||||
obj_open3d.data.materials.append(open3dMat)
|
||||
open3dMat.use_nodes = True
|
||||
nodes = open3dMat.node_tree.nodes
|
||||
prin_bsdf_node = nodes.get("Principled BSDF")
|
||||
# 创建新的贴图对象
|
||||
tex_image_node = nodes.new("ShaderNodeTexImage")
|
||||
tex_image = bpy.data.images.new(name="o3d_teximage", width=8192, height=8192)
|
||||
tex_image_node.image = tex_image
|
||||
tex_image_node.location = (-400, 200)
|
||||
tex_image_node.select = True # 节点选中状态
|
||||
tex_image_node.select = True # 节点为活动状态
|
||||
links = open3dMat.node_tree.links
|
||||
bpy.context.object.active_material = open3dMat
|
||||
bpy.ops.object.material_slot_select()
|
||||
bpy.ops.object.material_slot_assign()
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Prepare bake data time: ', time.time() - start_time)
|
||||
start_time = time.time()
|
||||
# 烘焙操作
|
||||
bpy.context.scene.render.engine = 'CYCLES'
|
||||
bpy.context.scene.cycles.device = 'GPU'
|
||||
bpy.context.scene.cycles.preview_samples = 1
|
||||
bpy.context.scene.cycles.samples = 1
|
||||
bpy.context.scene.cycles.bake_type = 'DIFFUSE'
|
||||
bpy.context.scene.render.bake.use_pass_direct = False
|
||||
bpy.context.scene.render.bake.use_pass_indirect = False
|
||||
bpy.context.scene.render.bake.use_pass_color = True
|
||||
bpy.context.scene.render.bake.use_selected_to_active = True
|
||||
bpy.context.scene.render.bake.use_cage = True
|
||||
bpy.context.scene.render.bake.cage_object = bpy.data.objects[obj_cage.name]
|
||||
bpy.context.scene.render.bake.target = 'IMAGE_TEXTURES'
|
||||
# 添加置换修改器,不能应用
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj_cage
|
||||
obj_cage.select_set(True)
|
||||
bpy.ops.object.modifier_add(type='DISPLACE')
|
||||
bpy.context.object.modifiers["Displace"].mid_level = 0.995
|
||||
bpy.ops.object.modifier_apply(modifier="Displace")
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj_original
|
||||
obj_original.select_set(True)
|
||||
bpy.context.view_layer.objects.active = obj_open3d
|
||||
obj_open3d.select_set(True)
|
||||
bpy.ops.object.bake(type='DIFFUSE') # 开始 Bake
|
||||
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Bake DIFFUSE time: ', time.time() - start_time)
|
||||
start_time = time.time()
|
||||
|
||||
links.new(tex_image_node.outputs[0], prin_bsdf_node.inputs[0])
|
||||
|
||||
bpy.data.objects.remove(obj_original, do_unlink=True)
|
||||
bpy.data.objects.remove(obj_cage, do_unlink=True)
|
||||
|
||||
# 添加颜色属性
|
||||
bpy.ops.geometry.color_attribute_add()
|
||||
# 节点的创建:
|
||||
# nodes = bpy.context.active_object.active_material.node_tree.nodes
|
||||
# links = bpy.context.active_object.active_material.node_tree.links
|
||||
tex_coord = nodes.new("ShaderNodeTexCoord")
|
||||
Mapping = nodes.new('ShaderNodeMapping')
|
||||
vertex_color = nodes.new("ShaderNodeVertexColor")
|
||||
tex_coord.location = (-800, 600)
|
||||
Mapping.location = (-500, 200)
|
||||
vertex_color.location = (-200, 800)
|
||||
|
||||
# 节点之间的连接:
|
||||
# 纹理坐标的UV 连接 映射的矢量;映射的矢量 连接 纹理贴图的矢量;原理化BSDF删除;纹理贴图的矢量 连接 表(曲)面。
|
||||
links.new(tex_coord.outputs[2], nodes['Mapping'].inputs[0])
|
||||
links.new(Mapping.outputs[0], nodes['Image Texture'].inputs[0])
|
||||
principled_bsdf = nodes.get("Principled BSDF")
|
||||
nodes.remove(principled_bsdf)
|
||||
links.new(nodes['Image Texture'].outputs[0], nodes['Material Output'].inputs[0])
|
||||
|
||||
# 4.渲染烘焙相关操作
|
||||
bpy.context.scene.render.engine = 'CYCLES'
|
||||
bpy.context.scene.cycles.device = 'GPU'
|
||||
bpy.context.scene.cycles.preview_samples = 1
|
||||
bpy.context.scene.cycles.samples = 1
|
||||
bpy.context.scene.cycles.bake_type = 'EMIT'
|
||||
bpy.context.scene.render.bake.use_selected_to_active = False
|
||||
bpy.context.scene.render.bake.target = 'VERTEX_COLORS'
|
||||
bpy.ops.object.bake(type='EMIT') # 开始 Bake
|
||||
|
||||
# 连接节点 Color Attribute 和 节点 Material Output
|
||||
links.new(nodes['Color Attribute'].outputs[0], nodes['Material Output'].inputs[0])
|
||||
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Bake EMIT time: ', time.time() - start_time)
|
||||
start_time = time.time()
|
||||
|
||||
# 清除顶点为nan的无效数据
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj_open3d
|
||||
obj_open3d.select_set(True)
|
||||
remove_nan_verts(obj_open3d)
|
||||
|
||||
# 5.输出模型
|
||||
# bpy.ops.wm.save_as_mainfile(filepath='/data/datasets/plys/121614.bend')
|
||||
bpy.ops.wm.ply_export(filepath=save_ply_path, apply_modifiers=True, export_selected_objects=True, export_uv=False,
|
||||
export_normals=False, export_colors='SRGB', export_triangulated_mesh=False, ascii_format=True)
|
||||
bpy.data.objects.remove(obj_open3d, do_unlink=True)
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Save ply time: ', time.time() - start_time)
|
||||
|
||||
return obj_num_vertices
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# workdir = '/data/datasets/suwa_cut/data/auto/'
|
||||
# output = '/data/datasets/plys/auto/'
|
||||
workdir = 'G:\obj_fix\print'
|
||||
output = 'G:\obj_fix\ply\whole_obj_bake_vertex_high_ply'
|
||||
directory = f'G:\obj_fix/print/right'
|
||||
#遍历获取 G:\obj_fix\print\right 目录的文件,根据文件名获取 pid
|
||||
for file_name in os.listdir(directory):
|
||||
# 获取文件的完整路径
|
||||
file_path = os.path.join(directory, file_name)
|
||||
# 检查是否是文件
|
||||
if os.path.isfile(file_path):
|
||||
#
|
||||
arrFileName = file_name.split('_')
|
||||
pid = arrFileName[0]
|
||||
if int(pid) == 0:
|
||||
continue
|
||||
|
||||
print(f"File: {file_name}, PID: {pid}")
|
||||
|
||||
#判断文件是否存在
|
||||
file_path = os.path.join(output, f'{pid}.ply')
|
||||
if os.path.exists(file_path) and os.path.isfile(file_path):
|
||||
print("文件已存在,跳过循环!!!")
|
||||
continue
|
||||
|
||||
obj_filepath = os.path.join(workdir, f'{pid}/{pid}.obj')
|
||||
save_ply_path = os.path.join(output, f'{pid}.ply')
|
||||
if not os.path.exists(obj_filepath):
|
||||
print(f"{obj_filepath} 文件不存在,跳过循环!!!")
|
||||
continue
|
||||
|
||||
obj_num_vertices = get_obj_bake_vertex_ply(obj_filepath, save_ply_path)
|
||||
if obj_num_vertices == 0:
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 模型 {pid} 程序getHeadCount()无法找到模型人数!总共运行时间: ', time.time() - start_time0)
|
||||
logging.info(f'模型 {pid} 顶点数量: {obj_num_vertices},程序getHeadCount()无法找到模型人数!,程序总共运行时间: {time.time() - start_time0:.2f} 秒')
|
||||
continue
|
||||
@@ -0,0 +1,296 @@
|
||||
import platform,sys,redis,time,requests,json,atexit
|
||||
sys.path.append('../libs/')
|
||||
|
||||
import config,libs,libs_db_temp,common
|
||||
|
||||
import os, sys, time, argparse, requests, json, re, oss2
|
||||
import bpy
|
||||
import open3d as o3d
|
||||
import shutil
|
||||
import psutil
|
||||
# 下载 obj mtl jpg 文件 修正obj 的贴地板 及身高尺寸 生成预览图
|
||||
|
||||
#文件存储lua路径
|
||||
diskName = "G:\\"
|
||||
filePath = "G://obj_fix/auto"
|
||||
#获取真实身高
|
||||
def get_real_height(input_path):
|
||||
get_real_height_url = 'https://mp.api.suwa3d.com/api/physical/infoByPid'
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Getting real height from {input_path}')
|
||||
pid = re.findall(r'(\d+)', input_path)[0]
|
||||
print(f'pid: {pid}')
|
||||
res = requests.get(get_real_height_url, params={'pid': pid})
|
||||
res = json.loads(res.text)
|
||||
if res['code'] == -1:
|
||||
print(f'Error: {res["message"]}, return default height 160')
|
||||
return 160
|
||||
height = res['data']['height']
|
||||
if height == 0:
|
||||
print(f'Error: height=0, return default height 160')
|
||||
return 160
|
||||
print(f'height: {height}')
|
||||
return height
|
||||
|
||||
|
||||
def base_fix(input_path):
|
||||
if not os.path.exists(input_path):
|
||||
print(f'Error: {input_path} does not exist.')
|
||||
return "error"
|
||||
|
||||
bpy.ops.wm.read_homefile()
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
bpy.ops.wm.obj_import(filepath=input_path)
|
||||
bpy.context.scene.unit_settings.scale_length = 1
|
||||
bpy.context.scene.unit_settings.length_unit = 'CENTIMETERS'
|
||||
bpy.context.scene.unit_settings.mass_unit = 'GRAMS'
|
||||
|
||||
obj = bpy.context.selected_objects[0]
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
|
||||
# 脚底贴地
|
||||
bpy.ops.object.align(align_mode='OPT_1', relative_to='OPT_1', align_axis={'Z'})
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
real_height = get_real_height(input_path)
|
||||
print(obj.dimensions)
|
||||
scale = real_height / obj.dimensions[2] / 100 # 除以100是因为单位是厘米
|
||||
bpy.context.object.scale = (scale, scale, scale)
|
||||
bpy.context.object.rotation_euler = (0, 0, 0)
|
||||
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME', center='MEDIAN')
|
||||
bpy.context.object.location[0] = 0 # 移动到特定位置(1m, 1m)是为了让human3d可以正确识别
|
||||
bpy.context.object.location[1] = 0
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
# # bpy.ops.wm.save_mainfile(filepath=args.input_path.replace('.obj', '.blend'))
|
||||
# output_file = input_path.replace('.obj', 'test.obj')
|
||||
bpy.ops.wm.obj_export(filepath=input_path.replace('.obj', '_base_fix.obj'))
|
||||
return obj
|
||||
|
||||
#检测mtl文件最后一行是否 map_Kd 7126Tex1.jpg
|
||||
def check_mtl(tempMtlFilePath,pid):
|
||||
start_time = time.time()
|
||||
print(f"{pid}-开始检测mtl文件-开始时间-{start_time}")
|
||||
#读取mtl文件
|
||||
if not os.path.exists(tempMtlFilePath):
|
||||
return False
|
||||
with open(tempMtlFilePath, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
if len(lines) > 0:
|
||||
line = lines[-1]
|
||||
print(line)
|
||||
if "map_Kd" in line and f"{pid}Tex1.jpg" in line:
|
||||
print(f"{pid}-检测mtl文件-成功-耗时-{time.time()-start_time}")
|
||||
return True
|
||||
else:
|
||||
#删除最后一行
|
||||
if "map_Kd" in line and f"{pid}.jpg" in line:
|
||||
lines.pop()
|
||||
#最后一行插入 map_Kd 7126Tex1.jpg
|
||||
lines.append(f"map_Kd {pid}Tex1.jpg\n")
|
||||
with open(tempMtlFilePath, 'w', encoding='utf-8') as f:
|
||||
f.writelines(lines)
|
||||
print(f"{pid}-检测mtl文件-成功-耗时-{time.time()-start_time}")
|
||||
return True
|
||||
print(f"{pid}-检测mtl文件-失败-耗时-{time.time()-start_time}")
|
||||
return False
|
||||
|
||||
|
||||
#生成预览图
|
||||
def create_preview(obj_file_path,image_save_path,pid):
|
||||
|
||||
start_time = time.time()
|
||||
print(f"{pid}-开始生成预览图-开始时间-{start_time}")
|
||||
# 加载 OBJ 文件
|
||||
mesh = o3d.io.read_triangle_mesh(obj_file_path,enable_post_processing=True)
|
||||
mesh.compute_vertex_normals()
|
||||
# 创建视觉化窗口
|
||||
# o3d.visualization.MeshColorOption = o3d.visualization.MeshColorOption.Default
|
||||
vis = o3d.visualization.Visualizer()
|
||||
# render = o3d.visualization.RenderOption()
|
||||
width = 800
|
||||
height = 600
|
||||
vis.create_window(width=width, height=height,visible=False)
|
||||
# 添加几何体到视觉化窗口
|
||||
vis.add_geometry(mesh)
|
||||
vis.get_render_option().light_on = True
|
||||
# vis.get_render_option().mesh_color_option = o3d.visualization.MeshColorOption.Default
|
||||
vis.get_render_option().mesh_shade_option = o3d.visualization.MeshShadeOption.Default
|
||||
# render.background_color = [123,251,89] # 将光照强度设置为0.5或更低
|
||||
# vis.get_render_option().ambient_intensity = 0.9 # 设置环境光强度
|
||||
# vis.get_render_option().directional_light = False # 关闭定向光
|
||||
|
||||
# vis.get_render_option().line_width = 2.0
|
||||
# 更新渲染器并捕获屏幕图像
|
||||
vis.update_renderer()
|
||||
vis.poll_events()
|
||||
vis.capture_screen_image(image_save_path)
|
||||
# 关闭窗口
|
||||
vis.destroy_window()
|
||||
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Run time: ', time.time() - start_time)
|
||||
|
||||
time.sleep(2)
|
||||
# 检测图片是否存在
|
||||
if not os.path.exists(image_save_path):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Error: {image_save_path} does not exist.')
|
||||
return False
|
||||
#判断文件夹是否存在
|
||||
if not os.path.exists(f"{filePath}/preview/"):
|
||||
os.makedirs(f"{filePath}/preview/")
|
||||
#图片存在则复制到指定的文件夹中
|
||||
shutil.copy(image_save_path, f"{filePath}/preview/")
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
#检测硬盘容量
|
||||
def check_disk():
|
||||
# 获取硬盘分区列表
|
||||
partitions = psutil.disk_partitions()
|
||||
|
||||
for partition in partitions:
|
||||
print("分区信息",partition)
|
||||
# 获取指定分区(比如'C:')的使用情况
|
||||
if partition.mountpoint == diskName: # 更改为您要检测的硬盘分区
|
||||
usage = psutil.disk_usage(partition.mountpoint)
|
||||
|
||||
free = f'{usage.free / (1024**3):.2f}'
|
||||
free = float(free)
|
||||
print(f"{diskName}剩余容量{free}")
|
||||
if free < 3:
|
||||
print("硬盘空间不足")
|
||||
return False
|
||||
|
||||
# print(f"Total: {usage.total / (1024**3):.2f} GB")
|
||||
# print(f"Used: {usage.used / (1024**3):.2f} GB")
|
||||
# print(f"Free: {usage.free / (1024**3):.2f} GB")
|
||||
# print(f"Percentage: {usage.percent}%")
|
||||
return True
|
||||
|
||||
|
||||
# def traverse_directory(directory):
|
||||
# for root, dirs, files in os.walk(directory):
|
||||
# print(f"当前目录: {root}")
|
||||
# print("子目录: ", dirs)
|
||||
# print("文件: ", files)
|
||||
# print()
|
||||
|
||||
def readTask():
|
||||
#遍历 G:\obj_fix\print\wrong
|
||||
folder_path = 'G:\\obj_fix\print\wrong'
|
||||
arrFiles = []
|
||||
for root, dirs, files in os.walk(folder_path):
|
||||
# print(f"当前目录: {root}")
|
||||
# print("子目录: ", dirs)
|
||||
arrFiles = files
|
||||
# print("文件: ", files)
|
||||
# print()
|
||||
for file in arrFiles:
|
||||
if file.endswith('_ok.png'):
|
||||
#提取pid
|
||||
pid = file.split('_')[0]
|
||||
print(pid)
|
||||
base_fix(f'{filePath}/{pid}/{pid}_new.obj')
|
||||
|
||||
|
||||
return
|
||||
#读取数据库的任务
|
||||
pid="164"
|
||||
base_fix(f'{filePath}/{pid}/{pid}_new.obj')
|
||||
|
||||
#生成预览图
|
||||
#res = create_preview(f'{filePath}/{pid}/{pid}_new.obj',f'{filePath}/{pid}/{pid}_preview.png',pid)
|
||||
|
||||
return
|
||||
|
||||
startTimeTask = time.time()
|
||||
|
||||
|
||||
pid = libs_db_temp.get_task_by_level()
|
||||
pid = str(pid)
|
||||
if pid == "":
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 无任务,延时10s')
|
||||
time.sleep(10)
|
||||
return
|
||||
|
||||
if int(pid) == 0:
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 无任务,延时10s')
|
||||
time.sleep(10)
|
||||
return
|
||||
#记录状态为处理中
|
||||
libs_db_temp.update_fix_status(pid,1)
|
||||
|
||||
# #判断对应的文件夹是否存在,存在则删除
|
||||
# if os.path.exists(f'{filePath}/{pid}'):
|
||||
# shutil.rmtree(f'{filePath}/{pid}')
|
||||
|
||||
|
||||
|
||||
# #下载pid的对应的oss端的文件
|
||||
# tempName = libs.down_obj_from_oss_for_fix(filePath, pid, "print")
|
||||
|
||||
# if tempName == "no_file":
|
||||
# #记录状态为异常 -3 文件不存在
|
||||
# libs_db_temp.update_fix_status(pid,-3)
|
||||
# return "error"
|
||||
|
||||
|
||||
# if tempName == "error":
|
||||
# #记录状态为异常 -1
|
||||
# libs_db_temp.update_fix_status(pid,-2)
|
||||
# return "error"
|
||||
|
||||
# if tempName == "":
|
||||
# print("找不到对应的obj文件")
|
||||
# #记录状态为异常 -1
|
||||
# libs_db_temp.update_fix_status(pid,-1)
|
||||
# return
|
||||
|
||||
|
||||
# #处理逻辑
|
||||
# print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+"-"+pid+"-开始执行任务")
|
||||
# try:
|
||||
# res=base_fix(f'{filePath}/{pid}/{pid}.obj')
|
||||
# if res == "error":
|
||||
# #记录状态为异常 -2
|
||||
# libs_db_temp.update_fix_status(pid,-1)
|
||||
# return "error"
|
||||
# #记录状态为成功 2
|
||||
# # libs_db_temp.update_fix_status(pid,2)
|
||||
# except Exception as e:
|
||||
# #状态异常 -2
|
||||
# libs_db_temp.update_fix_status(pid,-1)
|
||||
# return "error"
|
||||
|
||||
# #检测 mtl文件是否有map_Kd 7126Tex1.jpg
|
||||
# res = check_mtl(f'{filePath}/{pid}/{pid}.mtl',pid)
|
||||
# if res == False:
|
||||
# #记录状态为异常 -2
|
||||
# libs_db_temp.update_fix_status(pid,-2)
|
||||
# return "error"
|
||||
# time.sleep(2)
|
||||
|
||||
#生成预览图
|
||||
res = create_preview(f'{filePath}/{pid}/{pid}.obj',f'{filePath}/{pid}/{pid}_preview.png',pid)
|
||||
if not res:
|
||||
#记录状态为异常 -2
|
||||
libs_db_temp.update_fix_status(pid,-2)
|
||||
return "error"
|
||||
libs_db_temp.update_fix_status(pid,2)
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} -任务完美结束总耗时: ', time.time() - startTimeTask)
|
||||
return True
|
||||
|
||||
#程序主入口
|
||||
if __name__ == '__main__':
|
||||
#atexit.register(common.notify,"处理数据校准任务已经停止")
|
||||
pid="90864"
|
||||
base_fix(f'{filePath}/{pid}/{pid}.obj')
|
||||
# readTask()
|
||||
# while True:
|
||||
# pid = readTask()
|
||||
# res = check_disk()
|
||||
# if res == False:
|
||||
# print("硬盘空间不足,无法执行任务")
|
||||
# break
|
||||
@@ -0,0 +1,157 @@
|
||||
import os, sys, time, argparse, requests, json, re, oss2
|
||||
import bpy, bmesh
|
||||
import open3d as o3d
|
||||
import numpy as np
|
||||
# import cupy as cp
|
||||
from mathutils import Matrix
|
||||
import math
|
||||
import logging
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def get_auto_obj_bake_vertex_ply(obj_filepath, save_ply_path):
|
||||
start_time = time.time()
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Getting ply vertex from {obj_filepath}')
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.ops.object.select_by_type(type='MESH')
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
bpy.ops.wm.obj_import(filepath=obj_filepath)
|
||||
|
||||
obj_original = [obj for obj in bpy.data.objects if obj.type == 'MESH'][0]
|
||||
bpy.context.view_layer.objects.active = obj_original
|
||||
obj_original.select_set(True)
|
||||
pid = obj_original.name
|
||||
|
||||
obj_num_vertices = len(obj_original.data.vertices)
|
||||
# print(f"模型 {pid} 顶点数量:", len(obj_original.data.vertices))
|
||||
|
||||
# 选择新分离出来的网格对象,并将该对象设为进活动对象
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
bpy.context.view_layer.objects.active = obj_original
|
||||
obj_original.select_set(True)
|
||||
|
||||
# 添加颜色属性
|
||||
bpy.ops.geometry.color_attribute_add()
|
||||
# 节点的创建:
|
||||
nodes = bpy.context.active_object.active_material.node_tree.nodes
|
||||
links = bpy.context.active_object.active_material.node_tree.links
|
||||
tex_coord = nodes.new("ShaderNodeTexCoord")
|
||||
Mapping = nodes.new('ShaderNodeMapping')
|
||||
vertex_color = nodes.new("ShaderNodeVertexColor")
|
||||
tex_coord.location = (-800, 600)
|
||||
Mapping.location = (-500, 200)
|
||||
vertex_color.location = (-200, 600)
|
||||
|
||||
# 节点之间的连接:
|
||||
# 纹理坐标的UV 连接 映射的矢量;映射的矢量 连接 纹理贴图的矢量;原理化BSDF删除;纹理贴图的矢量 连接 表(曲)面。
|
||||
links.new(tex_coord.outputs[2], nodes['Mapping'].inputs[0])
|
||||
links.new(Mapping.outputs[0], nodes['Image Texture'].inputs[0])
|
||||
principled_bsdf = nodes.get("Principled BSDF")
|
||||
nodes.remove(principled_bsdf)
|
||||
links.new(nodes['Image Texture'].outputs[0], nodes['Material Output'].inputs[0])
|
||||
|
||||
# 4.渲染烘焙相关操作
|
||||
bpy.context.scene.render.engine = 'CYCLES'
|
||||
bpy.context.scene.cycles.device = 'GPU'
|
||||
bpy.context.scene.cycles.preview_samples = 1
|
||||
bpy.context.scene.cycles.samples = 1
|
||||
bpy.context.scene.cycles.bake_type = 'EMIT'
|
||||
bpy.context.scene.render.bake.use_selected_to_active = False
|
||||
bpy.context.scene.render.bake.target = 'VERTEX_COLORS'
|
||||
bpy.ops.object.bake(type='EMIT') # 开始 Bake
|
||||
|
||||
# 连接节点 Color Attribute 和 节点 Material Output
|
||||
links.new(nodes['Color Attribute'].outputs[0], nodes['Material Output'].inputs[0])
|
||||
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Bake EMIT time: ', time.time() - start_time)
|
||||
start_time = time.time()
|
||||
|
||||
# 5.输出模型
|
||||
# bpy.ops.wm.save_as_mainfile(filepath='/data/datasets/plys/121614.bend')
|
||||
bpy.ops.wm.ply_export(filepath=save_ply_path, apply_modifiers=True, export_selected_objects=True, export_uv=False,
|
||||
export_normals=False, export_colors='SRGB', export_triangulated_mesh=False, ascii_format=True)
|
||||
bpy.data.objects.remove(obj_original, do_unlink=True)
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Save ply time: ', time.time() - start_time)
|
||||
|
||||
return obj_num_vertices
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# workdir = '/data/datasets/suwa_cut/data/auto/'
|
||||
# output = '/data/datasets/plys/auto/'
|
||||
workdir = 'G:\obj_fix\print'
|
||||
output = 'G:\obj_fix\ply\whole_obj_bake_vertex_high_ply'
|
||||
directory = f'G:\obj_fix/print/right'
|
||||
#遍历获取 G:\obj_fix\print\right 目录的文件,根据文件名获取 pid
|
||||
for file_name in os.listdir(directory):
|
||||
# 获取文件的完整路径
|
||||
file_path = os.path.join(directory, file_name)
|
||||
# 检查是否是文件
|
||||
if os.path.isfile(file_path):
|
||||
#
|
||||
arrFileName = file_name.split('_')
|
||||
pid = arrFileName[0]
|
||||
if int(pid) == 0:
|
||||
continue
|
||||
|
||||
print(f"File: {file_name}, PID: {pid}")
|
||||
|
||||
#判断文件是否存在
|
||||
file_path = os.path.join(output, f'{pid}.ply')
|
||||
if os.path.exists(file_path) and os.path.isfile(file_path):
|
||||
print("文件已存在,跳过循环!!!")
|
||||
continue
|
||||
|
||||
obj_filepath = os.path.join(workdir, f'{pid}/{pid}.obj')
|
||||
save_ply_path = os.path.join(output, f'{pid}.ply')
|
||||
if not os.path.exists(obj_filepath):
|
||||
print(f"{obj_filepath} 文件不存在,跳过循环!!!")
|
||||
continue
|
||||
|
||||
obj_num_vertices = get_auto_obj_bake_vertex_ply(obj_filepath, save_ply_path)
|
||||
if obj_num_vertices == 0:
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 模型 {pid} 程序getHeadCount()无法找到模型人数!总共运行时间: ', time.time() - start_time0)
|
||||
logging.info(f'模型 {pid} 顶点数量: {obj_num_vertices},程序getHeadCount()无法找到模型人数!,程序总共运行时间: {time.time() - start_time0:.2f} 秒')
|
||||
continue
|
||||
# # 从文件名中提取 pid
|
||||
# pid = extract_pid(file_name)
|
||||
# if pid:
|
||||
# print(f"File: {file_name}, PID: {pid}")
|
||||
# else:
|
||||
# print(f"Unable to extract PID from file: {file_name}")
|
||||
|
||||
|
||||
# return
|
||||
# listdir_pids = os.listdir(workdir)
|
||||
# for pid in listdir_pids:
|
||||
# file_path = os.path.join(output, f'{pid}/{pid}.ply')
|
||||
# if os.path.exists(file_path) and os.path.isfile(file_path):
|
||||
# print("文件已存在,跳过循环!!!")
|
||||
# continue
|
||||
|
||||
# print(pid)
|
||||
# logging.basicConfig(filename=f'/data/datasets/plys/auto_vertex_time.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
# start_time0 = time.time()
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 模型 {pid} 开始运行时间: ', start_time0)
|
||||
# # 判断输出目录是否存在
|
||||
# if not os.path.exists(os.path.join(output, f'{pid}/')):
|
||||
# os.makedirs(os.path.join(output, f'{pid}/'))
|
||||
|
||||
# obj_filepath = os.path.join(workdir, f'{pid}/{pid}_cpd.obj')
|
||||
# save_ply_path = os.path.join(output, f'{pid}/{pid}.ply')
|
||||
# if not os.path.exists(obj_filepath):
|
||||
# print(f"{obj_filepath} 文件不存在,跳过循环!!!")
|
||||
# continue
|
||||
|
||||
# obj_num_vertices = get_auto_obj_bake_vertex_ply(obj_filepath, save_ply_path)
|
||||
# if obj_num_vertices == 0:
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 模型 {pid} 程序getHeadCount()无法找到模型人数!总共运行时间: ', time.time() - start_time0)
|
||||
# logging.info(f'模型 {pid} 顶点数量: {obj_num_vertices},程序getHeadCount()无法找到模型人数!,程序总共运行时间: {time.time() - start_time0:.2f} 秒')
|
||||
# continue
|
||||
|
||||
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 模型 {pid} 顶点数量: {obj_num_vertices} 程序总共运行时间: ', time.time() - start_time0)
|
||||
# logging.info(f'模型 {pid} 顶点数量: {obj_num_vertices},程序总共运行时间: {time.time() - start_time0:.2f} 秒')
|
||||
# # 退出 Blender 并释放资源
|
||||
# bpy.ops.wm.quit_blender()
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import paramiko
|
||||
import os
|
||||
|
||||
# 使用示例
|
||||
sftp_host = "172.31.1.3" # SFTP 服务器地址
|
||||
sftp_port = 22 # SFTP 端口号
|
||||
sftp_user = 'gpu' # SFTP 登录用户名
|
||||
sftp_passwd = '2024' # SFTP 登录密码
|
||||
# 获取当前文件上一层目录,即项目目录 make2 底下
|
||||
local_root_path = "G:\\obj_fix\print"
|
||||
|
||||
# 定义函数来递归遍历文件夹下的所有文件
|
||||
def list_files(directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
yield os.path.join(root, file)
|
||||
|
||||
def sftp_upload(sftp_host, sftp_port, sftp_user, sftp_passwd, local_file, remote_file):
|
||||
# 创建 SSH 客户端对象
|
||||
ssh_client = paramiko.SSHClient()
|
||||
|
||||
try:
|
||||
# 设置自动添加主机密钥
|
||||
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
# 连接到 SFTP 服务器
|
||||
ssh_client.connect(sftp_host, port=sftp_port, username=sftp_user, password=sftp_passwd)
|
||||
|
||||
# 创建 SFTP 客户端对象
|
||||
sftp_client = ssh_client.open_sftp()
|
||||
|
||||
# 判断 local_file 是文件还是目录
|
||||
if os.path.isdir(local_file):
|
||||
try:
|
||||
# 如果远程目录不存在,则创建
|
||||
sftp_client.mkdir(remote_file)
|
||||
except IOError:
|
||||
# 目录已存在,忽略
|
||||
pass
|
||||
|
||||
# 切换至远程目录
|
||||
sftp_client.chdir(remote_file)
|
||||
|
||||
# 遍历本地目录
|
||||
for file_name in os.listdir(local_file):
|
||||
local_path = os.path.join(local_file, file_name)
|
||||
|
||||
if os.path.isfile(local_path):
|
||||
# 如果是文件,上传文件
|
||||
sftp_client.put(local_path, file_name)
|
||||
else:
|
||||
# 如果是文件,直接上传文件
|
||||
sftp_client.put(local_file, remote_file)
|
||||
|
||||
print("上传成功")
|
||||
|
||||
except Exception as e:
|
||||
print(f"上传文件失败:{e}")
|
||||
|
||||
finally:
|
||||
# 关闭 SFTP 客户端和 SSH 连接
|
||||
sftp_client.close()
|
||||
ssh_client.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
nums = 0
|
||||
#遍历 local_root_path 下的所有文件
|
||||
for file_path in list_files(local_root_path):
|
||||
|
||||
if "around" in file_path:
|
||||
continue
|
||||
|
||||
|
||||
if "_old.obj" in file_path:
|
||||
|
||||
|
||||
# if ".obj" not in file_path:
|
||||
# continue
|
||||
|
||||
arrTemp = file_path.split('\\')
|
||||
pid = arrTemp[len(arrTemp)-2]
|
||||
nums += 1
|
||||
|
||||
# # pid = "164"
|
||||
# 本地文件路径
|
||||
dirPath = f'{local_root_path}/{pid}/{pid}.obj'
|
||||
# 远程服务的路径
|
||||
remote_file = f"/data/datasets/obj_fix/{pid}/{pid}.obj"
|
||||
sftp_upload(sftp_host, sftp_port, sftp_user, sftp_passwd, dirPath, remote_file)
|
||||
print(pid,file_path,"---剩余---",524 - nums)
|
||||
@@ -0,0 +1,92 @@
|
||||
import platform,sys,redis,time,requests,json,atexit
|
||||
import os, sys, time, argparse, requests, json, re, oss2
|
||||
import bpy
|
||||
import open3d as o3d
|
||||
import shutil
|
||||
import psutil
|
||||
|
||||
#生成预览图
|
||||
def create_preview(obj_file_path,image_save_path,pid):
|
||||
|
||||
start_time = time.time()
|
||||
print(f"{pid}-开始生成预览图-开始时间-{start_time}")
|
||||
# 加载 OBJ 文件
|
||||
mesh = o3d.io.read_triangle_mesh(obj_file_path,enable_post_processing=True)
|
||||
mesh.compute_vertex_normals()
|
||||
# 创建视觉化窗口
|
||||
# o3d.visualization.MeshColorOption = o3d.visualization.MeshColorOption.Default
|
||||
vis = o3d.visualization.Visualizer()
|
||||
# render = o3d.visualization.RenderOption()
|
||||
width = 50
|
||||
height = 100
|
||||
vis.create_window(width=width, height=height,visible=False)
|
||||
# 添加几何体到视觉化窗口
|
||||
vis.add_geometry(mesh)
|
||||
vis.get_render_option().light_on = True
|
||||
# vis.get_render_option().mesh_color_option = o3d.visualization.MeshColorOption.Default
|
||||
vis.get_render_option().mesh_shade_option = o3d.visualization.MeshShadeOption.Default
|
||||
# render.background_color = [123,251,89] # 将光照强度设置为0.5或更低
|
||||
# vis.get_render_option().ambient_intensity = 0.9 # 设置环境光强度
|
||||
# vis.get_render_option().directional_light = False # 关闭定向光
|
||||
|
||||
# vis.get_render_option().line_width = 2.0
|
||||
# 更新渲染器并捕获屏幕图像
|
||||
vis.update_renderer()
|
||||
vis.poll_events()
|
||||
vis.capture_screen_image(image_save_path)
|
||||
# 关闭窗口
|
||||
vis.destroy_window()
|
||||
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Run time: ', time.time() - start_time)
|
||||
|
||||
time.sleep(2)
|
||||
# 检测图片是否存在
|
||||
if not os.path.exists(image_save_path):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Error: {image_save_path} does not exist.')
|
||||
return False
|
||||
# #判断文件夹是否存在
|
||||
# if not os.path.exists(f"{filePath}/preview/"):
|
||||
# os.makedirs(f"{filePath}/preview/")
|
||||
# #图片存在则复制到指定的文件夹中
|
||||
# shutil.copy(image_save_path, f"{filePath}/preview/")
|
||||
|
||||
|
||||
return True
|
||||
|
||||
# 定义函数来递归遍历文件夹下的所有文件
|
||||
def list_files(directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
yield os.path.join(root, file)
|
||||
|
||||
|
||||
|
||||
#生成预览图
|
||||
|
||||
target_folder = 'G://obj_fix/print/'
|
||||
source_folder = 'G://obj_fix/print/preview'
|
||||
#遍历文件夹下的所有文件
|
||||
nums = 0
|
||||
for file_path in list_files(target_folder):
|
||||
|
||||
|
||||
if ".obj" not in file_path:
|
||||
continue
|
||||
print("文件路径:",file_path)
|
||||
#判断文件是否存在
|
||||
if not os.path.exists(file_path):
|
||||
continue
|
||||
|
||||
print(file_path)
|
||||
arrData = file_path.split('/')
|
||||
pid = arrData[len(arrData)-2]
|
||||
|
||||
|
||||
#判断封面图片是否存在
|
||||
# if os.path.exists(f'{target_folder}/{pid}_preview.png'):
|
||||
# print(f'{pid}_preview.png 已存在,跳过循环!!!')
|
||||
# continue
|
||||
nums += 1
|
||||
print(f"正在处理{pid}","--剩余--",1530 - nums)
|
||||
|
||||
create_preview(f'{file_path}',f'{source_folder}/{pid}_preview.png',pid)
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
import os
|
||||
import shutil
|
||||
#遍历 G:\obj_fix\print\wrong 文件 获取到pid
|
||||
|
||||
workdir = 'G:\obj_fix\print'
|
||||
# output = 'G:\obj_fix\ply\whole_obj_bake_vertex_high_ply'
|
||||
directory = f'G:\obj_fix/print/wrong'
|
||||
#遍历获取 G:\obj_fix\print\right 目录的文件,根据文件名获取 pid
|
||||
|
||||
arrWrongFiles = []
|
||||
for file_name in os.listdir(directory):
|
||||
# # 获取文件的完整路径
|
||||
# file_path = os.path.join(directory, file_name)
|
||||
# # 检查是否是文件
|
||||
# if os.path.isfile(file_path):
|
||||
# #
|
||||
|
||||
arrFileName = file_name.split('_')
|
||||
pid = arrFileName[0]
|
||||
if int(pid) == 0:
|
||||
continue
|
||||
|
||||
arrWrongFiles.append(pid)
|
||||
|
||||
#遍历 G:\obj_fix\print\preview 文件 获取到pid
|
||||
directory = f'G:\obj_fix/print/preview'
|
||||
for file_name in os.listdir(directory):
|
||||
arrFileName = file_name.split('_')
|
||||
pid = arrFileName[0]
|
||||
if int(pid) == 0:
|
||||
continue
|
||||
|
||||
if pid in arrWrongFiles:
|
||||
continue
|
||||
|
||||
#判断right目录中是否已经存在该pid的文件
|
||||
if os.path.exists(f'G:\obj_fix/print/right/{file_name}'):
|
||||
continue
|
||||
|
||||
print("new_pid",pid)
|
||||
#不在arrWrongFiles中的pid,就是正确的pid要复制到right目录
|
||||
filePath = os.path.join(directory, file_name)
|
||||
shutil.copy(filePath, f'G:\obj_fix/print/right/{file_name}')
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
31013
|
||||
78387
|
||||
40918
|
||||
71701
|
||||
27553
|
||||
58122
|
||||
55114
|
||||
25093
|
||||
9846
|
||||
70756
|
||||
128719
|
||||
17388
|
||||
49934
|
||||
56750
|
||||
71421
|
||||
55844
|
||||
136602
|
||||
136603
|
||||
136925
|
||||
31450
|
||||
71326
|
||||
30624
|
||||
56802
|
||||
4417
|
||||
55367
|
||||
119772
|
||||
75416
|
||||
71422
|
||||
66521
|
||||
26848
|
||||
55083
|
||||
77226
|
||||
42595
|
||||
8141
|
||||
115162
|
||||
66531
|
||||
11997
|
||||
77960
|
||||
115302
|
||||
68700
|
||||
124636
|
||||
79333
|
||||
54701
|
||||
70807
|
||||
65918
|
||||
64088
|
||||
127455
|
||||
71415
|
||||
11797
|
||||
68807
|
||||
115123
|
||||
53804
|
||||
24775
|
||||
75402
|
||||
30663
|
||||
68349
|
||||
44322
|
||||
14301
|
||||
55076
|
||||
14216
|
||||
68699
|
||||
56784
|
||||
55030
|
||||
70532
|
||||
13084
|
||||
48197
|
||||
79263
|
||||
14475
|
||||
44845
|
||||
14094
|
||||
15963
|
||||
29506
|
||||
117004
|
||||
88074
|
||||
49404
|
||||
62516
|
||||
57762
|
||||
76289
|
||||
25568
|
||||
120406
|
||||
9177
|
||||
13073
|
||||
70754
|
||||
55082
|
||||
83698
|
||||
77516
|
||||
125118
|
||||
25043
|
||||
78384
|
||||
71356
|
||||
56559
|
||||
70792
|
||||
68692
|
||||
115028
|
||||
26384
|
||||
8171
|
||||
23805
|
||||
14148
|
||||
82460
|
||||
24765
|
||||
82496
|
||||
115074
|
||||
120416
|
||||
39732
|
||||
45480
|
||||
67655
|
||||
22155
|
||||
77957
|
||||
29507
|
||||
83844
|
||||
56799
|
||||
31596
|
||||
40613
|
||||
24766
|
||||
100270
|
||||
104867
|
||||
21807
|
||||
56781
|
||||
21007
|
||||
136602
|
||||
55011
|
||||
22204
|
||||
77964
|
||||
16074
|
||||
56877
|
||||
68724
|
||||
13160
|
||||
136302
|
||||
83715
|
||||
121495
|
||||
77431
|
||||
12177
|
||||
68906
|
||||
24784
|
||||
30617
|
||||
87849
|
||||
56754
|
||||
55370
|
||||
42781
|
||||
12981
|
||||
70732
|
||||
121614
|
||||
30660
|
||||
8852
|
||||
31012
|
||||
78376
|
||||
75405
|
||||
9023
|
||||
136603
|
||||
69798
|
||||
55092
|
||||
8145
|
||||
71361
|
||||
81419
|
||||
55887
|
||||
83761
|
||||
74624
|
||||
82571
|
||||
15707
|
||||
115228
|
||||
70746
|
||||
83983
|
||||
29805
|
||||
71318
|
||||
135850
|
||||
83759
|
||||
29489
|
||||
63115
|
||||
19338
|
||||
16012
|
||||
29796
|
||||
15012
|
||||
48250
|
||||
8160
|
||||
75408
|
||||
48477
|
||||
68718
|
||||
21780
|
||||
55860
|
||||
77221
|
||||
20197
|
||||
115017
|
||||
86196
|
||||
55730
|
||||
82483
|
||||
64739
|
||||
13154
|
||||
8121
|
||||
22159
|
||||
55372
|
||||
86211
|
||||
44623
|
||||
11845
|
||||
68925
|
||||
106929
|
||||
31010
|
||||
31442
|
||||
71321
|
||||
68940
|
||||
25200
|
||||
50370
|
||||
70729
|
||||
49935
|
||||
68916
|
||||
24780
|
||||
39522
|
||||
42047
|
||||
20675
|
||||
78385
|
||||
68688
|
||||
13120
|
||||
8953
|
||||
33899
|
||||
13692
|
||||
79331
|
||||
76300
|
||||
30638
|
||||
71323
|
||||
19405
|
||||
48880
|
||||
56797
|
||||
56654
|
||||
9181
|
||||
115051
|
||||
46352
|
||||
10873
|
||||
27534
|
||||
55075
|
||||
136357
|
||||
55084
|
||||
11881
|
||||
68735
|
||||
77972
|
||||
8124
|
||||
13161
|
||||
70812
|
||||
30705
|
||||
55081
|
||||
123599
|
||||
31986
|
||||
36791
|
||||
55849
|
||||
47752
|
||||
55021
|
||||
128446
|
||||
30843
|
||||
71407
|
||||
41320
|
||||
57168
|
||||
71395
|
||||
16078
|
||||
20203
|
||||
65653
|
||||
27214
|
||||
52884
|
||||
71404
|
||||
24772
|
||||
115042
|
||||
55090
|
||||
78381
|
||||
43054
|
||||
125097
|
||||
136925
|
||||
68730
|
||||
68821
|
||||
68926
|
||||
61764
|
||||
11676
|
||||
43059
|
||||
98894
|
||||
80445
|
||||
84547
|
||||
83707
|
||||
82435
|
||||
83729
|
||||
82440
|
||||
83712
|
||||
80166
|
||||
80007
|
||||
82481
|
||||
83727
|
||||
85652
|
||||
86232
|
||||
86252
|
||||
83756
|
||||
82511
|
||||
87649
|
||||
82486
|
||||
@@ -0,0 +1,70 @@
|
||||
from flask import Flask, jsonify, request
|
||||
import os
|
||||
from flask_cors import CORS
|
||||
app = Flask(__name__)
|
||||
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
|
||||
|
||||
# 定义函数来递归遍历文件夹下的所有文件
|
||||
def list_files(directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
yield os.path.join(root, file)
|
||||
|
||||
# 更新数据
|
||||
@app.route('/api/data/', methods=['GET'])
|
||||
def update_data():
|
||||
pid = request.args.get('pid')
|
||||
angle = request.args.get('angle')
|
||||
jump = request.args.get('jump')
|
||||
|
||||
if jump == "jump":
|
||||
file_path = f'G:\obj_fix\print\wrong\{pid}_preview.png'
|
||||
if not os.path.exists(file_path):
|
||||
return "file not exists"
|
||||
|
||||
#重命名文件
|
||||
new_file_path = f'G:\obj_fix\print\wrong\{pid}_preview_wait.png'
|
||||
os.rename(file_path, new_file_path)
|
||||
else:
|
||||
if pid == "0":
|
||||
return "pid is 0"
|
||||
|
||||
if str(angle[0]) == "0":
|
||||
return "angle is 0"
|
||||
|
||||
file_path = f'G:\obj_fix\print\wrong\{pid}_preview.png'
|
||||
if not os.path.exists(file_path):
|
||||
return "file not exists"
|
||||
|
||||
#重命名文件
|
||||
new_file_path = f'G:\obj_fix\print\wrong\{pid}_preview_{angle}.png'
|
||||
os.rename(file_path, new_file_path)
|
||||
|
||||
#遍历 G:\obj_fix\print\wrong\ 文件夹下的所有文件
|
||||
for file_path in list_files('G:\obj_fix\print\wrong'):
|
||||
if "_preview.png" not in file_path:
|
||||
continue
|
||||
#获取pid 从 "G:\obj_fix\print\wrong\76289_preview_117.png" 中获取 "76289
|
||||
pid = file_path.split('\\')[-1].split('_')[0]
|
||||
|
||||
return pid
|
||||
|
||||
# #组装链接
|
||||
# url = f'https://mp.suwa3d.com/preview.html?platform=1&id={pid}&size=18cm_x1&angle=1#/'
|
||||
|
||||
# #将 url 写入文件
|
||||
# with open('url.txt', 'a') as f:
|
||||
# f.write(url + '\n')
|
||||
|
||||
|
||||
#return jsonify({'pid': id1, 'angle': id2})
|
||||
# for item in data:
|
||||
# if item['id'] == data_id:
|
||||
# item.update(request.get_json())
|
||||
# return jsonify({'message': 'Data updated successfully'})
|
||||
#return jsonify({'message': 'Data not found'}), 404
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
+2017218
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,54 @@
|
||||
from pathlib import Path
|
||||
import os
|
||||
import shutil
|
||||
# 指定要遍历的文件夹路径
|
||||
folder_path = Path('G://obj_fix/print')
|
||||
|
||||
# 定义函数来递归遍历文件夹下的所有文件
|
||||
def list_files(directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
yield os.path.join(root, file)
|
||||
|
||||
# 指定要遍历的文件夹路径
|
||||
# folder_path = folder_path
|
||||
|
||||
# 使用list_files函数来列出文件夹下的所有文件
|
||||
nums = 0
|
||||
for file_path in list_files(folder_path):
|
||||
|
||||
if "around" in file_path:
|
||||
continue
|
||||
|
||||
|
||||
if "_new.obj" not in file_path:
|
||||
continue
|
||||
|
||||
|
||||
|
||||
|
||||
#提取pid
|
||||
arrTemp = file_path.split('\\')
|
||||
pid = arrTemp[len(arrTemp)-2]
|
||||
|
||||
#判段是否存在 {pid}.obj 文件,存在的话就进行重命名
|
||||
initObjPath = f'G://obj_fix/print/{pid}/{pid}.obj'
|
||||
if not os.path.exists(initObjPath):
|
||||
continue
|
||||
|
||||
#存在的话就重命名文件
|
||||
old_file_path = f'G://obj_fix/print/{pid}/{pid}_old.obj'
|
||||
os.rename(initObjPath, old_file_path)
|
||||
|
||||
|
||||
newObjfilePath = f'G://obj_fix/print/{pid}/{pid}_new.obj'
|
||||
os.rename(newObjfilePath, initObjPath)
|
||||
|
||||
# # 将 new.obj 文件复制到指定的文件夹下 G:\obj_fix\print\{pid}\
|
||||
|
||||
# source_obj = file_path
|
||||
# target_obj = f'G://obj_fix/print/{pid}/{pid}_new.obj'
|
||||
# print(f"当前正在处理{pid}")
|
||||
# shutil.copy(source_obj, target_obj)
|
||||
nums += 1
|
||||
print(pid,file_path,nums)
|
||||
@@ -0,0 +1,33 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
folder_path = 'G:\\obj_fix\print'
|
||||
|
||||
# 遍历文件夹下的所有文件
|
||||
# 定义函数来递归遍历文件夹下的所有文件
|
||||
def list_files(directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
yield os.path.join(root, file)
|
||||
|
||||
nums = 0
|
||||
for file_path in list_files(folder_path):
|
||||
if "_preview.png" not in file_path:
|
||||
continue
|
||||
print(file_path)
|
||||
nums += 1
|
||||
# #提取pid
|
||||
# arrTemp = file_path.split('\\')
|
||||
# pid = arrTemp[len(arrTemp)-2]
|
||||
|
||||
# #判断 G:\obj_fix\print\wrong\ 文件夹里 是否存在 {pid}_preview.png 文件
|
||||
|
||||
# filePath = f'G://obj_fix\print\wrong\{pid}_preview.png'
|
||||
# #不存在跳过
|
||||
# if not os.path.exists(filePath):
|
||||
# continue
|
||||
|
||||
# #存在的话就重命名文件
|
||||
# new_file_path = f'G://obj_fix\print\wrong\{pid}_preview_already_right.png'
|
||||
# os.rename(filePath, new_file_path)
|
||||
print(nums)
|
||||
@@ -0,0 +1,124 @@
|
||||
import numpy as np
|
||||
import open3d as o3d
|
||||
import math,os
|
||||
#矫正模型的方向,目前只支持水平旋转,
|
||||
#55084 55090 55092 55114 55367 55370 55372 55730 55844 55849 56559 56654 56750 75408
|
||||
|
||||
|
||||
|
||||
def rotate_vertex(x, y, z, axis, angle_degrees):
|
||||
"""
|
||||
围绕任意轴旋转顶点。
|
||||
axis是一个表示旋转轴的三元组 (ax, ay, az)。
|
||||
angle_degrees是旋转角度,以度为单位。
|
||||
"""
|
||||
# 将角度转换为弧度
|
||||
angle_radians = math.radians(angle_degrees)
|
||||
|
||||
# 将旋转轴转换为单位向量
|
||||
axis = np.array(axis)
|
||||
axis = axis / np.linalg.norm(axis)
|
||||
|
||||
# 将顶点位置转换为向量
|
||||
v = np.array([x, y, z])
|
||||
|
||||
# 应用罗德里格斯旋转公式
|
||||
v_rotated = (v * math.cos(angle_radians) +
|
||||
np.cross(axis, v) * math.sin(angle_radians) +
|
||||
axis * np.dot(axis, v) * (1 - math.cos(angle_radians)))
|
||||
|
||||
return v_rotated.tolist()
|
||||
|
||||
def transform_obj_file(source_file, target_file, axis, angle_degrees):
|
||||
"""
|
||||
读取 OBJ 文件,应用旋转,然后将结果保存到另一个文件。
|
||||
"""
|
||||
with open(source_file, 'r') as src:
|
||||
lines = src.readlines()
|
||||
|
||||
with open(target_file, 'w') as tgt:
|
||||
for line in lines:
|
||||
if line.startswith('v '):
|
||||
parts = line.split()
|
||||
x, y, z = map(float, parts[1:4])
|
||||
x_new, y_new, z_new = rotate_vertex(x, y, z, axis, angle_degrees)
|
||||
tgt.write(f"v {x_new} {y_new} {z_new}\n")
|
||||
else:
|
||||
tgt.write(line)
|
||||
|
||||
def list_files(directory):
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
yield os.path.join(root, file)
|
||||
|
||||
# # #遍历文件夹下的所有文件
|
||||
# folder_path = 'G://obj_fix/print/wrong'
|
||||
# nums = 0
|
||||
# rotate_axis = (0, 1, 0) # 比如绕X轴旋转
|
||||
# for file_path in list_files(folder_path):
|
||||
# #print(file_path) G://obj_fix/print/around/preview\9023_preview_117.png
|
||||
# if "_preview.png" in file_path:
|
||||
# continue
|
||||
# if "_right.png" in file_path:
|
||||
# continue
|
||||
# if "_wait.png" in file_path:
|
||||
# continue
|
||||
# #获取pid 从 "G://obj_fix/print/around/preview\9023_preview_117.png" 中获取 9023 he 117
|
||||
# arrData = file_path.split('\\')
|
||||
# lastData = arrData[-1]
|
||||
# arrLastData = lastData.split('_')
|
||||
# if len(arrLastData) < 3:
|
||||
# print(lastData)
|
||||
# continue
|
||||
# pid = arrLastData[0]
|
||||
# angle = arrLastData[2].split('.')[0]
|
||||
# #判断 angle 第一个数字是否为 0
|
||||
|
||||
# source_obj = f'G://obj_fix/print/{pid}/{pid}.obj'
|
||||
# target_obj = f'G://obj_fix/print/{pid}/{pid}_new.obj'
|
||||
|
||||
# nums +=1
|
||||
# print(f"当前正在处理{pid},已处理至-{nums}",)
|
||||
# if str(angle[0]) == "0":
|
||||
# rotate_angle = -int(angle)
|
||||
# transform_obj_file(source_obj, target_obj, rotate_axis, rotate_angle)
|
||||
# else:
|
||||
# rotate_angle = int(angle)
|
||||
# transform_obj_file(source_obj, target_obj, rotate_axis, rotate_angle)
|
||||
# print(int(angle))
|
||||
# print(angle,angle[0])
|
||||
|
||||
|
||||
|
||||
# # 加载模型
|
||||
# mesh = o3d.io.read_triangle_mesh(target_obj, enable_post_processing=True)
|
||||
|
||||
# # 创建渲染窗口并添加模型
|
||||
# vis = o3d.visualization.Visualizer()
|
||||
# vis.create_window()
|
||||
# vis.add_geometry(mesh)
|
||||
|
||||
# # 设置渲染参数
|
||||
# render_option = vis.get_render_option()
|
||||
# render_option.point_size = 1.0
|
||||
|
||||
# # 渲染模型
|
||||
# vis.run()
|
||||
# vis.destroy_window()
|
||||
|
||||
|
||||
pid = "90864" # 98894 115123
|
||||
source_obj = f'G://obj_fix/auto/{pid}/{pid}.obj'
|
||||
target_obj = f'G://obj_fix/auto/{pid}/{pid}_90.obj'
|
||||
|
||||
#遍历文件夹下的所有文件 /data/datasets/temp/auto_preview_need_around
|
||||
for file_path in list_files('G://obj_fix/auto'):
|
||||
pid = file_path.split('\\')[-1].split('_')[0]
|
||||
# 使用示例:
|
||||
rotate_axis = (1, 0, 0) # 比如绕X轴旋转 0 x 轴
|
||||
rotate_angle = -90 # 以度为单位
|
||||
transform_obj_file(source_obj, target_obj, rotate_axis, rotate_angle)
|
||||
|
||||
# rotate_axis = (0, 1, 0) # 比如绕X轴旋转 0 x 轴
|
||||
# rotate_angle = 60 # 以度为单位
|
||||
# transform_obj_file(target_obj, target_obj, rotate_axis, rotate_angle)
|
||||
@@ -0,0 +1,52 @@
|
||||
import platform,sys,redis,time,requests,json,atexit
|
||||
sys.path.append('../libs/')
|
||||
|
||||
import config,libs,libs_db_temp,common
|
||||
import oss2,os
|
||||
|
||||
|
||||
# 将本地文件上传到oss 中,并且清除 oss 上的文件
|
||||
|
||||
#文件存储lua路径
|
||||
typeV = "print"
|
||||
filePath = f"G://obj_fix/{typeV}"
|
||||
ossPrefix = f"objs/{typeV}"
|
||||
def readTask():
|
||||
startTimeTask = time.time()
|
||||
#读取数据库的任务
|
||||
# pid = libs_db_temp.get_task_by_status(100) #2 表示该文件已经处理好了
|
||||
# pid = str(pid)
|
||||
pid = "4417"
|
||||
if int(pid) == 0:
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 无任务,延时10s')
|
||||
time.sleep(10)
|
||||
return
|
||||
#检测文件是否存在
|
||||
if not os.path.exists(f"{filePath}/{pid}/{pid}.obj"):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Error: {filePath}/{pid}/{pid}.obj does not exist.')
|
||||
return False
|
||||
|
||||
if not os.path.exists(f"{filePath}/{pid}/{pid}Tex1.jpg"):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Error: {filePath}/{pid}/{pid}.obj does not exist.')
|
||||
return False
|
||||
|
||||
if not os.path.exists(f"{filePath}/{pid}/{pid}.mtl"):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Error: {filePath}/{pid}/{pid}.obj does not exist.')
|
||||
return False
|
||||
|
||||
if not os.path.exists(f"{filePath}/{pid}/{pid}_preview.png"):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Error: {filePath}/{pid}/{pid}.obj does not exist.')
|
||||
return False
|
||||
|
||||
#清空oss上的文件
|
||||
libs.clear_oss_by_pid(f'{ossPrefix}/{pid}')
|
||||
#上传文件到oss
|
||||
libs.upload_obj_to_oss(filePath,typeV,pid)
|
||||
return
|
||||
|
||||
#程序主入口
|
||||
if __name__ == '__main__':
|
||||
#atexit.register(common.notify,"处理数据校准任务已经停止")
|
||||
readTask()
|
||||
# while True:
|
||||
# pid = readTask()
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=100270&size=18cm_x1&angle=1#
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=104867&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=106929&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115017&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115028&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115042&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115051&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115074&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115123&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115162&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115228&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=115302&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=117004&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=119772&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=120406&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=120416&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=121495&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=121614&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=123599&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=124636&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=125097&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=125118&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=127455&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=128446&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=128719&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=13154&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=13160&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=13161&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=135850&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=136302&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=136357&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=136602&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=136603&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=136925&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=13692&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=14094&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=14148&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=14216&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=14301&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=14475&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=15012&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=15707&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=15963&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=16012&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=16074&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=16078&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=17388&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=19338&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=19405&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=20197&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=20203&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=20675&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=21007&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=21780&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=21807&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=22155&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=22159&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=22204&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=23805&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=24765&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=24766&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=24772&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=24775&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=24780&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=24784&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=25043&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=25093&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=25200&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=25568&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=26384&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=26848&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=27214&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=27534&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=27553&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=29489&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=29506&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=29507&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=29796&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=29805&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=30617&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=30624&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=30638&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=30660&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=30663&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=30705&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=30843&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=31010&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=31012&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=31442&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=31450&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=31596&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=31986&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=33899&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=36791&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=39522&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=39732&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=40613&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=40918&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=41320&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=42047&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=42595&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=42781&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=43054&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=43059&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=44322&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=44623&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=44845&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=45480&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=46352&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=47752&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=48197&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=48250&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=48477&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=48880&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=49404&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=49934&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=49935&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=50370&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=52884&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=53804&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=54701&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55011&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55021&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55030&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55075&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55076&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55081&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55082&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55083&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55084&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55090&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55092&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55114&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55367&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55370&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55372&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55730&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55844&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55849&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55860&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=55887&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56559&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56654&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56750&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56754&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56781&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56784&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56797&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56799&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56802&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=56877&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=57168&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=57762&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=58122&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=61764&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=62516&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=63115&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=64088&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=64739&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=65653&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=65918&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=66521&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=66531&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=67655&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68349&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68688&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68692&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68699&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68700&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68718&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68724&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68730&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68735&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68807&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68821&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68906&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68916&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68925&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68926&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=68940&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=69798&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70532&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70729&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70732&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70746&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70754&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70756&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70792&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70807&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=70812&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71318&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71321&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71323&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71326&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71356&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71361&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71395&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71404&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71407&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71415&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71421&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71422&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=71701&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=74624&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=75402&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=75405&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=75408&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=75416&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=76289&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=76300&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77221&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77226&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77431&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77516&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77957&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77960&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77964&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=77972&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=78376&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=78381&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=78384&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=78385&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=79263&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=79331&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=79333&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=80007&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=80166&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=80445&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=81419&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82435&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82440&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82460&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82481&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82483&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82486&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82496&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82511&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=82571&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83698&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83707&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83712&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83715&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83727&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83729&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83756&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83759&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83761&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83844&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=83983&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=84547&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=85652&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=86196&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=86211&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=86232&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=86252&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=87649&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=87849&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=88074&size=18cm_x1&angle=1#/
|
||||
https://mp.suwa3d.com/preview.html?platform=1&id=98894&size=18cm_x1&angle=1#/
|
||||
@@ -1,60 +1,15 @@
|
||||
import os, sys, time, shutil, subprocess, shlex, json
|
||||
import xml.etree.ElementTree as ET
|
||||
import platform
|
||||
if platform.system() == 'Windows':
|
||||
sys.path.append('e:\\libs\\')
|
||||
#sys.path.append('libs')
|
||||
else:
|
||||
sys.path.append('/data/deploy/make3d/make2/libs/')
|
||||
import psutil
|
||||
|
||||
import config, libs, libs_db,common
|
||||
# 获取硬盘分区列表
|
||||
partitions = psutil.disk_partitions()
|
||||
|
||||
for partition in partitions:
|
||||
print("分区信息",partition)
|
||||
# 获取指定分区(比如'C:')的使用情况
|
||||
if partition.mountpoint == 'G:\\': # 更改为您要检测的硬盘分区
|
||||
usage = psutil.disk_usage(partition.mountpoint)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
#遍历oss 指定文件夹下指定日期的文件
|
||||
for obj in config.bucket.list_objects(prefix="auto/"):
|
||||
#判断是否是文件夹 并且 日期是否在 2023-11-08 之后的
|
||||
if obj.key[-1] == "/" and obj.key.split("/")[1] >= "2023-11-08":
|
||||
#判断是否存在这个目录
|
||||
if not os.path.exists(os.path.join(config.workdir,obj.key.split("/")[1])):
|
||||
os.mkdir(os.path.join(config.workdir,obj.key.split("/")[1]))
|
||||
#拷贝文件到本地
|
||||
for obj2 in config.bucket.list_objects(prefix=obj.key):
|
||||
if obj2.key[-1] != "/":
|
||||
print(obj2.key)
|
||||
#判断文件是否存在
|
||||
if not os.path.exists(os.path.join(config.workdir,obj2.key)):
|
||||
#下载文件
|
||||
config.bucket.get_object_to_file(obj2.key,os.path.join(config.workdir,obj2.key))
|
||||
#判断文件是否下载成功
|
||||
if os.path.exists(os.path.join(config.workdir,obj2.key)):
|
||||
print("下载成功")
|
||||
else:
|
||||
print("下载失败")
|
||||
else:
|
||||
print("文件已存在")
|
||||
|
||||
# 解析XML文件
|
||||
# pid = "112322"
|
||||
# file_path = os.path.join(config.workdir, pid, f'{pid}.rcproj')
|
||||
# tree = ET.parse(file_path)
|
||||
# root = tree.getroot()
|
||||
# # 遍历所有的reconstructions节点
|
||||
# for reconstruction in root.findall('reconstructions'):
|
||||
# for component in reconstruction.findall('component'):
|
||||
# if component.find('model') == None:
|
||||
# reconstruction.remove(component)
|
||||
# continue
|
||||
# # 获取所有包含model标签的component节点
|
||||
# components_with_model = [component for component in reconstruction.findall('component') if component.find('model') is not None]
|
||||
# print(components_with_model)
|
||||
# # 如果包含model标签的component节点数量大于1,则按照model数量降序排序
|
||||
# if len(components_with_model) > 1:
|
||||
# components_with_model.sort(key=lambda x: len(x.findall('model')), reverse=False)
|
||||
|
||||
# for i in range(len(components_with_model)-1):
|
||||
# reconstruction.remove(components_with_model[i])
|
||||
|
||||
# # 保存修改后的XML文件
|
||||
# tree.write(file_path)
|
||||
print(f"Total: {usage.total / (1024**3):.2f} GB")
|
||||
print(f"Used: {usage.used / (1024**3):.2f} GB")
|
||||
print(f"Free: {usage.free / (1024**3):.2f} GB")
|
||||
print(f"Percentage: {usage.percent}%")
|
||||
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import oss2
|
||||
|
||||
# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
|
||||
endpoint = 'https://oss-cn-shanghai.aliyuncs.com'
|
||||
# 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
|
||||
access_key_id = 'LTAI5tSj7s2mKZNqamT1x64v'
|
||||
access_key_secret = 'iIqeBLB8R2U72pAwJbZZBB6tuB3ZF9'
|
||||
# 指定文件所在的Bucket名称,例如examplebucket。
|
||||
bucket_name = 'suwa3d-securedata'
|
||||
# Object完整路径,完整路径中不能包含Bucket名称。
|
||||
key = 'photos/141640/photo2/72_8.jpg'
|
||||
|
||||
# 指定Bucket实例,所有文件相关的方法都需要通过Bucket实例来调用。
|
||||
bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
|
||||
|
||||
style = 'image/bodies'
|
||||
# 生成带签名的URL,并指定过期时间为10分钟。过期时间单位为秒。
|
||||
url = bucket.sign_url('GET', key, 10 * 60, params={'x-oss-process': style})
|
||||
print(url)
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
import open3d as o3d
|
||||
from open3d.visualization.gui import Application
|
||||
from open3d.visualization import O3DVisualizer
|
||||
import sys, os
|
||||
|
||||
|
||||
# 假设 obj_file_path 是你的 OBJ 文件路径,image_save_path 是保存图片的路径
|
||||
filePath = "G://obj_fix/print"
|
||||
pid = "8160"
|
||||
obj_file_path = f"{filePath}/{pid}/{pid}.obj"
|
||||
image_save_path = f"{filePath}/{pid}/{pid}_test.png"
|
||||
|
||||
|
||||
|
||||
# import open3d as o3d
|
||||
|
||||
# 加载OBJ文件
|
||||
mesh = o3d.io.read_triangle_mesh(obj_file_path)
|
||||
|
||||
# 创建一个OffscreenRenderer对象
|
||||
renderer = o3d.visualization.rendering.OffscreenRenderer()
|
||||
|
||||
# 创建一个Open3DScene对象
|
||||
scene = o3d.visualization.rendering.Open3DScene()
|
||||
|
||||
# 将几何体添加到场景中
|
||||
scene.add_geometry(mesh)
|
||||
|
||||
# 创建一个材质并应用到几何体上
|
||||
material = o3d.visualization.rendering.MaterialRecord()
|
||||
material.base_color = [1.0, 1.0, 1.0] # 白色材质
|
||||
mesh.materials.append(material)
|
||||
|
||||
# 创建一个灯光对象
|
||||
light = o3d.visualization.rendering.Light()
|
||||
light.type = "directional" # 方向光
|
||||
light.direction = [0.0, -1.0, 0.0] # 光照方向
|
||||
light.color = [1.0, 1.0, 1.0] # 白色光线
|
||||
|
||||
# 将灯光添加到场景中
|
||||
scene.add_light(light)
|
||||
|
||||
# 设置渲染参数
|
||||
renderer.set_scene(scene)
|
||||
|
||||
# 渲染场景
|
||||
image = renderer.render()
|
||||
|
||||
# 显示渲染结果
|
||||
o3d.geometry.image.axial_slice(image, 2, (128, 128, 128))
|
||||
|
||||
# # 计算顶点法线,这对于渲染是非常重要的
|
||||
# mesh.compute_vertex_normals()
|
||||
|
||||
# # 可选:可以对网格进行进一步处理,例如滤波或下采样
|
||||
# # mesh = o3d.geometry.filter_triangle_mesh(mesh, "default")
|
||||
|
||||
# # 创建一个Open3D的可视化对象
|
||||
# vis = o3d.visualization.Visualizer()
|
||||
# vis.create_window()
|
||||
|
||||
# # 将网格添加到可视化对象中
|
||||
# vis.add_geometry(mesh)
|
||||
|
||||
# # 创建一个环境光源
|
||||
# light = get_light_source("default")
|
||||
# light.set_intensity([1.0, 1.0, 1.0]) # 设置光照强度
|
||||
|
||||
# # 将灯光添加到可视化对象中
|
||||
# vis.add_light(light)
|
||||
|
||||
# # 调整灯光位置和方向
|
||||
# light.set_position([0.0, 0.0, 0.0])
|
||||
# light.set_direction([0.0, 0.0, 1.0])
|
||||
# screenshot = vis.capture_screen()
|
||||
# o3d.io.write_image("screenshot.png", screenshot)
|
||||
|
||||
# # 渲染并显示窗口
|
||||
# vis.run()
|
||||
|
||||
|
||||
# # 加载一个点云或者网格
|
||||
# mesh = o3d.io.read_triangle_mesh(obj_file_path)
|
||||
|
||||
# # 创建 O3DVisualizer 实例
|
||||
# vis = o3d.visualization.O3DVisualizer("O3D Visualizer Example", 1024, 768)
|
||||
|
||||
# # 添加几何体到可视化窗口
|
||||
# vis.add_geometry("Mesh", mesh)
|
||||
|
||||
# # 显示可视化窗口
|
||||
# Application.instance.add_window(vis)
|
||||
# Application.instance.run()
|
||||
|
||||
# # Derive the object path set the model, material, and shader
|
||||
# model_dir = sys.argv[1]
|
||||
# model_name = os.path.join(model_dir, os.path.basename(model_dir) + ".obj")
|
||||
# model = o3d.io.read_triangle_mesh(obj_file_path)
|
||||
# material = o3d.visualization.rendering.Material()
|
||||
# material.shader = "defaultLit"
|
||||
|
||||
# # Derive the texture paths
|
||||
# albedo_name = os.path.join(model_dir, "albedo.png")
|
||||
# normal_name = os.path.join(model_dir, "normal.png")
|
||||
# ao_name = os.path.join(model_dir, "ao.png")
|
||||
# metallic_name = os.path.join(model_dir, "metallic.png")
|
||||
# roughness_name = os.path.join(model_dir, "roughness.png")
|
||||
|
||||
# # Check if the textures are available and loads the texture. For example, if metallic exists then load metallic texture
|
||||
# if os.path.exists(albedo_name):
|
||||
# material.albedo_img = o3d.io.read_image(albedo_name)
|
||||
# if os.path.exists(normal_name):
|
||||
# material.normal_img = o3d.io.read_image(normal_name)
|
||||
# if os.path.exists(ao_name):
|
||||
# material.ao_img = o3d.io.read_image(ao_name)
|
||||
# if os.path.exists(metallic_name):
|
||||
# material.base_metallic = 1.0
|
||||
# material.metallic_img = o3d.io.read_image(metallic_name)
|
||||
# if os.path.exists(roughness_name):
|
||||
# material.roughness_img = o3d.io.read_image(roughness_name)
|
||||
|
||||
# # Draw an object named cube using the available model and texture
|
||||
# o3d.visualization.draw([{"name": "cube", "geometry": model, "material": material}])
|
||||
|
||||
Reference in new issue
Block a user