Spaces:
Running on Zero
Running on Zero
File size: 4,428 Bytes
3a8a707 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | import os
import numpy as np
import pandas as pd
import ezdxf
from pathlib import Path
from scipy.spatial import KDTree
def fit_and_solve_closed_polynomial(pts: np.ndarray) -> dict:
"""
Fits 5 points into a 2D quadric polynomial curve: Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0
Returns solved algebraic coefficients and roots for the dataset.
"""
if len(pts) < 5:
# Pad with zeros if fewer than 5 points exist
return {"A": 0.0, "B": 0.0, "C": 0.0, "D": 0.0, "E": 0.0, "F": 0.0, "root_x": 0.0, "root_y": 0.0}
x = pts[:, 0]
y = pts[:, 1]
# Form design matrix for implicit conic curve fitting: Ax^2 + Bxy + Cy^2 + Dx + Ey = 1 (F = -1)
M = np.column_stack([x**2, x * y, y**2, x, y])
rhs = np.ones(len(pts))
try:
# Solve algebraic coefficients via least squares SVD
coeffs, _, _, _ = np.linalg.lstsq(M, rhs, rcond=None)
A, B, C, D, E = coeffs
F = -1.0
except Exception:
A, B, C, D, E, F = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
# Solve critical manifold center point (root solutions where derivatives = 0)
# dP/dx = 2Ax + By + D = 0 ; dP/dy = Bx + 2Cy + E = 0
det = 4 * A * C - B**2
if abs(det) > 1e-6:
root_x = (B * E - 2 * C * D) / det
root_y = (B * D - 2 * A * E) / det
else:
root_x, root_y = np.mean(x), np.mean(y)
return {
"poly_A": float(A),
"poly_B": float(B),
"poly_C": float(C),
"poly_D": float(D),
"poly_E": float(E),
"poly_F": float(F),
"root_x": float(root_x),
"root_y": float(root_y)
}
def process_mesh(input_csv_path: str, dxf_dir_path: str, max_faces=500, precision=2) -> pd.DataFrame:
"""
Reads DXF files, interpolates closed curves from 5 nearest neighbor points,
solves quadric polynomials, and returns the solved polynomial dataset.
"""
print(f" -> Processing Polynomial Geometry directly from DXF: {dxf_dir_path}")
dxf_dir = Path(dxf_dir_path)
if not dxf_dir.exists():
raise FileNotFoundError(f"DXF directory not found at {dxf_dir}")
all_points = []
dxf_files = sorted(list(dxf_dir.glob("*.dxf")))
if len(dxf_files) > 60:
dxf_files = dxf_files[::2]
for dxf_file in dxf_files:
try:
frame_id = int(''.join(filter(str.isdigit, dxf_file.stem)) or 0)
doc = ezdxf.readfile(dxf_file)
msp = doc.modelspace()
entities = msp.query('LINE')
sampling_rate = 2 if len(entities) > 500 else 1
for i, entity in enumerate(entities):
if i % sampling_rate != 0:
continue
all_points.append({'t': frame_id, 'x': entity.dxf.start.x, 'y': entity.dxf.start.y, 'z': entity.dxf.start.z})
all_points.append({'t': frame_id, 'x': entity.dxf.end.x, 'y': entity.dxf.end.y, 'z': entity.dxf.end.z})
except Exception:
continue
if not all_points:
raise ValueError("No valid point geometry vectors could be parsed from DXF layers.")
df_vertices = pd.DataFrame(all_points)
solved_dataset_rows = []
for frame_id, group in df_vertices.groupby('t'):
if len(group) < 5:
continue
pts_2d = group[['x', 'y']].drop_duplicates().values
if len(pts_2d) < 5:
continue
# Construct KD-Tree to locate 5 closest points for interpolated closed curves
tree = KDTree(pts_2d)
visited = set()
for idx, pt in enumerate(pts_2d):
if idx in visited or len(solved_dataset_rows) >= max_faces:
continue
# Query 5 nearest neighbors to form interpolated closed boundary loop
distances, indices = tree.query(pt, k=min(5, len(pts_2d)))
cluster_pts = pts_2d[indices]
# Solve quadric polynomial equations for the closed boundary
poly_sol = fit_and_solve_closed_polynomial(cluster_pts)
poly_sol['frame_id'] = frame_id
poly_sol['mean_z'] = float(group['z'].mean())
solved_dataset_rows.append(poly_sol)
# Compile solved polynomial representations directly into pandas dataset
dataset_df = pd.DataFrame(solved_dataset_rows)
print(f" ✅ Generated {len(dataset_df)} solved polynomial curves for dataset.")
return dataset_df |