Spaces:
Runtime error
Runtime error
import random | |
import shutil | |
import sys | |
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeSolid | |
from OCC.Core.BRepCheck import BRepCheck_Analyzer | |
from OCC.Core.IGESControl import IGESControl_Reader | |
from OCC.Core.Interface import Interface_Static | |
from OCC.Core.STEPControl import STEPControl_Reader, STEPControl_Writer, STEPControl_AsIs | |
from OCC.Core.StepData import StepData_StepModel | |
from OCC.Core.TopAbs import TopAbs_SOLID, TopAbs_COMPOUND, TopAbs_SHELL, TopAbs_FACE, TopAbs_EDGE | |
from OCC.Extend.DataExchange import read_step_file | |
from OCC.Core.ShapeFix import ShapeFix_ShapeTolerance | |
import os | |
import argparse | |
import glob | |
from tqdm import tqdm | |
from matplotlib import pyplot as plt | |
import numpy as np | |
from diffusion.utils import get_primitives | |
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE" | |
Interface_Static.SetIVal("read.precision.mode", 1) | |
Interface_Static.SetRVal("read.precision.val", 1e-1) | |
# Interface_Static.SetIVal("read.stdsameparameter.mode", 1) | |
# Interface_Static.SetIVal("read.surfacecurve.mode", 3) | |
# | |
# Interface_Static.SetCVal("write.step.schema", "DIS") | |
Interface_Static.SetIVal("write.precision.mode", 2) | |
Interface_Static.SetRVal("write.precision.val", 1e-1) | |
# Interface_Static.SetIVal("write.surfacecurve.mode", 1) | |
def check_step_valid_soild(step_file, precision=1e-1, return_shape=False): | |
try: | |
shape = read_step_file(str(step_file), as_compound=False, verbosity=False) | |
except: | |
if return_shape: | |
return False, None | |
else: | |
return False | |
if shape.ShapeType() != TopAbs_SOLID: | |
if return_shape: | |
return False, shape | |
else: | |
return False | |
shape_tol_setter = ShapeFix_ShapeTolerance() | |
shape_tol_setter.SetTolerance(shape, precision) | |
analyzer = BRepCheck_Analyzer(shape) | |
is_valid = analyzer.IsValid() | |
if return_shape: | |
return is_valid, shape | |
return is_valid | |
def load_data_with_prefix(root_folder, prefix, folder_list_txt=None): | |
data_files = [] | |
folder_list = [] | |
if folder_list_txt is not None: | |
with open(folder_list_txt, "r") as f: | |
folder_list = f.read().splitlines() | |
# Walk through the directory tree starting from the root folder | |
for root, dirs, files in os.walk(root_folder): | |
if folder_list_txt is not None and os.path.basename(root) not in folder_list: | |
continue | |
is_found = False | |
for filename in files: | |
# Check if the file ends with the specified prefix | |
if filename.endswith(prefix): | |
file_path = os.path.join(root, filename) | |
is_found = True | |
data_files.append(file_path) | |
if not is_found: | |
print(f"No {prefix} file found in {root}") | |
return data_files | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument("--data_root", type=str, required=True) | |
parser.add_argument("--prefix", type=str, required=False, default="") | |
parser.add_argument("--only_success", action="store_true", default=False) | |
args = parser.parse_args() | |
data_root = args.data_root | |
only_success = args.only_success | |
folders = [f for f in os.listdir(data_root) if os.path.isdir(os.path.join(data_root, f))] | |
if args.prefix: | |
step_file_list = load_data_with_prefix(os.path.join(data_root, args.prefix), ".step") | |
assert len(step_file_list) > 0 | |
print(f"Checking CAD solids in {args.prefix}...") | |
isvalid = check_step_valid_soild(step_file_list[0], is_set_gloabl=True) | |
print("Valid" if isvalid else "Invalid") | |
exit(0) | |
step_file_list = load_data_with_prefix(data_root, ".step") | |
print(f"Total sample features: {len(folders)}") | |
print(f"Total CAD solids: {len(step_file_list)}") | |
print("Start checking CAD solids...") | |
exception_folders = [] | |
exception_out_root = data_root + "_exception" | |
if os.path.exists(exception_out_root): | |
shutil.rmtree(exception_out_root) | |
os.makedirs(exception_out_root, exist_ok=False) | |
# Load cad data | |
valid_count = 0 | |
pbar = tqdm(step_file_list) | |
num_faces = [] | |
num_edges = [] | |
for step_file in pbar: | |
is_valid, shape = check_step_valid_soild(step_file, return_shape=True) | |
if os.path.exists(os.path.join(os.path.dirname(step_file), "success.txt")) and not is_valid: | |
folder_name = os.path.basename(os.path.dirname(step_file)) | |
exception_folders.append(folder_name) | |
shutil.copytree(os.path.dirname(step_file), os.path.join(exception_out_root, folder_name)) | |
if is_valid: | |
if only_success and not os.path.exists(os.path.join(os.path.dirname(step_file), "success.txt")): | |
continue | |
valid_count += 1 | |
num_faces.append(len(get_primitives(shape, TopAbs_FACE))) | |
num_edges.append(len(get_primitives(shape, TopAbs_EDGE)) // 2) | |
pbar.set_postfix({"valid_count": valid_count}) | |
# else: | |
# print(f"Invalid CAD solid: {step_file}") | |
fig, ax = plt.subplots(1, 2, layout="constrained") | |
ax[0].set_title("Num. faces") | |
ax[1].set_title("Num. edges") | |
hist_f, bin_f = np.histogram(num_faces, bins=5, range=(0, 30)) | |
hist_e, bin_e = np.histogram(num_edges, bins=5, range=(0, 50)) | |
# Normalize | |
hist_f = hist_f / np.sum(hist_f) | |
hist_e = hist_e / np.sum(hist_e) | |
ax[0].plot(bin_f[:-1], hist_f, "-") | |
ax[1].plot(bin_e[:-1], hist_e, "-") | |
ax[0].set_aspect(1. / ax[0].get_data_ratio()) | |
ax[1].set_aspect(1. / ax[1].get_data_ratio()) | |
plt.savefig(data_root + "_num_faces_edges.png", dpi=600) | |
print(f"Number of valid CAD solids: {valid_count}") | |
print(f"Valid rate: {valid_count / len(folders) * 100:.2f}%") | |
if len(exception_folders) > 0: | |
with open(os.path.join(exception_out_root, "exception_folders.txt"), "w") as f: | |
for folder in exception_folders: | |
f.write(folder + "\n") | |
print(f"Exception folders are saved to {exception_out_root}") | |
if len(exception_folders) == 0: | |
shutil.rmtree(exception_out_root) | |
print("No exception folders found.") | |