added collision conversion
This commit is contained in:
100
app/api/convert/route.ts
Normal file
100
app/api/convert/route.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import { spawn } from "child_process";
|
||||
import { writeFile, readFile, mkdir, unlink } from "fs/promises";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import path from "path";
|
||||
import os from "os";
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
try {
|
||||
const formData = await req.formData();
|
||||
const file = formData.get("file") as File;
|
||||
|
||||
if (!file) {
|
||||
return NextResponse.json({ error: "No file provided" }, { status: 400 });
|
||||
}
|
||||
|
||||
// 1. Setup workspace
|
||||
const tempDir = path.join(os.tmpdir(), "xgrids-pipeline");
|
||||
await mkdir(tempDir, { recursive: true });
|
||||
|
||||
// FIX: Sanitize filename to avoid shell/path issues with spaces
|
||||
const safeName = file.name.replace(/[^a-z0-8.]/gi, "_").toLowerCase();
|
||||
const timestamp = Date.now();
|
||||
const inputPath = path.join(tempDir, `${timestamp}_${safeName}`);
|
||||
|
||||
// Ensure we replace the extension correctly for the output
|
||||
const outputPath = inputPath.replace(/\.(lcc|lci)$/i, ".ply");
|
||||
|
||||
const scriptPath = path.join(
|
||||
process.cwd(),
|
||||
"scripts",
|
||||
"preprocess",
|
||||
"convert_lci_to_ply.py",
|
||||
);
|
||||
|
||||
// 2. Write the file
|
||||
const buffer = Buffer.from(await file.arrayBuffer());
|
||||
await writeFile(inputPath, buffer);
|
||||
|
||||
// 3. Execute Python
|
||||
return new Promise<NextResponse>((resolve) => {
|
||||
// spawn handles arguments as an array, which is safer than exec for spaces
|
||||
const pythonProcess = spawn("python3", [
|
||||
scriptPath,
|
||||
inputPath,
|
||||
outputPath,
|
||||
]);
|
||||
|
||||
let errorOutput = "";
|
||||
pythonProcess.stderr.on("data", (data) => {
|
||||
errorOutput += data.toString();
|
||||
});
|
||||
|
||||
pythonProcess.on("close", async (code) => {
|
||||
if (code !== 0) {
|
||||
console.error("Python Error:", errorOutput);
|
||||
// Cleanup input even on failure
|
||||
await unlink(inputPath).catch(() => {});
|
||||
return resolve(
|
||||
NextResponse.json(
|
||||
{
|
||||
error: `Python script failed with code ${code}. ${errorOutput}`,
|
||||
},
|
||||
{ status: 500 },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const plyBuffer = await readFile(outputPath);
|
||||
|
||||
// Cleanup
|
||||
await Promise.all([
|
||||
unlink(inputPath).catch(() => {}),
|
||||
unlink(outputPath).catch(() => {}),
|
||||
]);
|
||||
|
||||
resolve(
|
||||
new NextResponse(plyBuffer, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream",
|
||||
"Content-Disposition": `attachment; filename="${file.name.replace(/\.[^/.]+$/, "")}.ply"`,
|
||||
},
|
||||
}),
|
||||
);
|
||||
} catch (e) {
|
||||
resolve(
|
||||
NextResponse.json(
|
||||
{ error: "Failed to read generated PLY file" },
|
||||
{ status: 500 },
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.error("API Route Error:", error);
|
||||
return NextResponse.json({ error: error.message }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user