21 changed files with 2019474 additions and 65 deletions
@ -0,0 +1,213 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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}') |
||||
@ -0,0 +1,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 @@
@@ -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) |
||||
@ -0,0 +1,54 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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() |
||||
@ -0,0 +1,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 @@
@@ -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 @@
@@ -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) |
||||
@ -0,0 +1,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}]) |
||||
|
||||
Loading…
Reference in new issue