dxf loader

This commit is contained in:
Poovizhi99 2025-05-26 10:33:27 +05:30
parent d67b1eda8f
commit 218f68b13a
12 changed files with 489 additions and 131 deletions

69
app/package-lock.json generated
View File

@ -27,9 +27,11 @@
"@use-gesture/react": "^10.3.1", "@use-gesture/react": "^10.3.1",
"chart.js": "^4.4.8", "chart.js": "^4.4.8",
"chartjs-plugin-annotation": "^3.1.0", "chartjs-plugin-annotation": "^3.1.0",
"dxf-parser": "^1.1.2",
"glob": "^11.0.0", "glob": "^11.0.0",
"gsap": "^3.12.5", "gsap": "^3.12.5",
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",
"immer": "^9.0.21",
"leva": "^0.10.0", "leva": "^0.10.0",
"mqtt": "^5.10.4", "mqtt": "^5.10.4",
"postprocessing": "^6.36.4", "postprocessing": "^6.36.4",
@ -2021,7 +2023,7 @@
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"@jridgewell/trace-mapping": "0.3.9" "@jridgewell/trace-mapping": "0.3.9"
}, },
@ -2033,7 +2035,7 @@
"version": "0.3.9", "version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10" "@jridgewell/sourcemap-codec": "^1.4.10"
@ -4136,6 +4138,25 @@
"url": "https://github.com/sponsors/gregberge" "url": "https://github.com/sponsors/gregberge"
} }
}, },
"node_modules/@testing-library/dom": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
"@types/aria-query": "^5.0.1",
"aria-query": "5.3.0",
"chalk": "^4.1.0",
"dom-accessibility-api": "^0.5.9",
"lz-string": "^1.5.0",
"pretty-format": "^27.0.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@testing-library/jest-dom": { "node_modules/@testing-library/jest-dom": {
"version": "5.17.0", "version": "5.17.0",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
@ -4247,25 +4268,25 @@
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"dev": true "devOptional": true
}, },
"node_modules/@tsconfig/node12": { "node_modules/@tsconfig/node12": {
"version": "1.0.11", "version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"dev": true "devOptional": true
}, },
"node_modules/@tsconfig/node14": { "node_modules/@tsconfig/node14": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"dev": true "devOptional": true
}, },
"node_modules/@tsconfig/node16": { "node_modules/@tsconfig/node16": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"dev": true "devOptional": true
}, },
"node_modules/@turf/along": { "node_modules/@turf/along": {
"version": "7.2.0", "version": "7.2.0",
@ -9019,7 +9040,7 @@
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true "devOptional": true
}, },
"node_modules/cross-env": { "node_modules/cross-env": {
"version": "7.0.3", "version": "7.0.3",
@ -9896,7 +9917,7 @@
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true, "devOptional": true,
"engines": { "engines": {
"node": ">=0.3.1" "node": ">=0.3.1"
} }
@ -10067,6 +10088,14 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
}, },
"node_modules/dxf-parser": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/dxf-parser/-/dxf-parser-1.1.2.tgz",
"integrity": "sha512-GPTumUvRkounlIazLIyJMmTWt+nlg+ksS0Hdm8jWvejmZKBTz6gvHTam76wRm4PQMma5sgKLThblQyeIJcH79Q==",
"dependencies": {
"loglevel": "^1.7.1"
}
},
"node_modules/earcut": { "node_modules/earcut": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
@ -15181,6 +15210,18 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/loglevel": {
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz",
"integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==",
"engines": {
"node": ">= 0.6.0"
},
"funding": {
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/loglevel"
}
},
"node_modules/loose-envify": { "node_modules/loose-envify": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@ -15259,7 +15300,7 @@
"version": "1.3.6", "version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true "devOptional": true
}, },
"node_modules/makeerror": { "node_modules/makeerror": {
"version": "1.0.12", "version": "1.0.12",
@ -20727,7 +20768,7 @@
"version": "10.9.2", "version": "10.9.2",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"@cspotcode/source-map-support": "^0.8.0", "@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7", "@tsconfig/node10": "^1.0.7",
@ -20770,7 +20811,7 @@
"version": "8.3.4", "version": "8.3.4",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
"dev": true, "devOptional": true,
"dependencies": { "dependencies": {
"acorn": "^8.11.0" "acorn": "^8.11.0"
}, },
@ -20782,7 +20823,7 @@
"version": "4.1.3", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true "devOptional": true
}, },
"node_modules/tsconfig-paths": { "node_modules/tsconfig-paths": {
"version": "3.15.0", "version": "3.15.0",
@ -21278,7 +21319,7 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true "devOptional": true
}, },
"node_modules/v8-to-istanbul": { "node_modules/v8-to-istanbul": {
"version": "8.1.1", "version": "8.1.1",
@ -22337,7 +22378,7 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true, "devOptional": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }

View File

@ -22,10 +22,11 @@
"@use-gesture/react": "^10.3.1", "@use-gesture/react": "^10.3.1",
"chart.js": "^4.4.8", "chart.js": "^4.4.8",
"chartjs-plugin-annotation": "^3.1.0", "chartjs-plugin-annotation": "^3.1.0",
"dxf-parser": "^1.1.2",
"glob": "^11.0.0", "glob": "^11.0.0",
"gsap": "^3.12.5", "gsap": "^3.12.5",
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",
"immer": "^10.1.1", "immer": "^9.0.21",
"leva": "^0.10.0", "leva": "^0.10.0",
"mqtt": "^5.10.4", "mqtt": "^5.10.4",
"postprocessing": "^6.36.4", "postprocessing": "^6.36.4",

View File

@ -1,8 +1,53 @@
import React from "react"; import React, { useEffect, useState } from "react";
import useLayoutStore from "../../store/builder/uselayoutStore"; import useLayoutStore from "../../store/builder/uselayoutStore";
import { useDfxUpload } from "../../store/builder/store";
import DxfParser from "dxf-parser";
import { Box3, BufferGeometry, MathUtils, Vector3 } from "three";
import { getWallPointsFromBlueprint } from "../../modules/builder/dfx/functions/getWallPointsFromBlueprint";
import { convertDXFToThree } from "../../modules/builder/dfx/functions/convertDxfToThree";
// Define types for DXF entities and geometries
const SelectFloorPlan: React.FC = () => { const SelectFloorPlan: React.FC = () => {
const { currentLayout, setLayout } = useLayoutStore(); const { currentLayout, setLayout } = useLayoutStore();
const { setDfxUploaded, setDfxGenerate } = useDfxUpload();
const [parsedFile, setParsedFile] = useState<DXFData>();
const [generate, setGenerate] = useState<boolean>(false);
const handleFileUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (!file || !file.name.endsWith(".dxf")) {
alert("Please upload a valid .dxf file.");
return;
}
const reader = new FileReader();
reader.onload = async (e) => {
const dxfContent = e.target?.result as string;
try {
const parser = new DxfParser();
const parsedData = parser.parse(dxfContent) as DXFData;
const geometries = convertDXFToThree(parsedData);
setParsedFile(parsedData);
setDfxUploaded(geometries);
} catch (error) {
echo.error("Failed to import your .dxf file")
}
};
reader.readAsText(file);
};
useEffect(() => {
if (parsedFile !== undefined)
getWallPointsFromBlueprint({ parsedData: parsedFile, setDfxGenerate })
}, [generate])
return ( return (
<div className="select-floorplane-wrapper"> <div className="select-floorplane-wrapper">
Preset Layouts Preset Layouts
@ -23,9 +68,42 @@ const SelectFloorPlan: React.FC = () => {
> >
Preset 2 Preset 2
</button> </button>
<input
type="file"
id="file-upload"
accept=".dxf"
style={{ display: "none", width: "10px" }}
onChange={handleFileUpload}
/>
<label
htmlFor="file-upload"
className="preset"
style={{
cursor: "pointer",
padding: "10px 48px",
}}
>
Upload
</label>
<button
type="button"
id="generate-upload"
onClick={() => {
setDfxUploaded([])
setGenerate(!generate);
}}
>
Generate
</button>
</div> </div>
</div> </div >
); );
}; };
export default SelectFloorPlan; export default SelectFloorPlan;

View File

@ -49,7 +49,7 @@ import CalculateAreaGroup from "./groups/calculateAreaGroup";
import LayoutImage from "./layout/layoutImage"; import LayoutImage from "./layout/layoutImage";
import AssetsGroup from "./assetGroup/assetsGroup"; import AssetsGroup from "./assetGroup/assetsGroup";
import { Bvh } from "@react-three/drei"; import { Bvh } from "@react-three/drei";
import FindZoneName from "./findZoneName"; import DxfFile from "./dfx/LoadBlueprint";
export default function Builder() { export default function Builder() {
const state = useThree<Types.ThreeState>(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements. const state = useThree<Types.ThreeState>(); // Importing the state from the useThree hook, which contains the scene, camera, and other Three.js elements.
@ -312,9 +312,10 @@ export default function Builder() {
<MeasurementTool /> <MeasurementTool />
<CalculateAreaGroup /> <CalculateAreaGroup />
<FindZoneName />
<NavMesh lines={lines} /> <NavMesh lines={lines} />
<DxfFile lines={lines} dragPointControls={dragPointControls} currentLayerPoint={currentLayerPoint} floorPlanGroupLine={floorPlanGroupLine} floorPlanGroupPoint={floorPlanGroupPoint} setUpdateScene={setUpdateScene} />
<LayoutImage /> <LayoutImage />
</Bvh> </Bvh>
</> </>

View File

@ -0,0 +1,38 @@
import { useEffect } from 'react';
import { useDfxUpload, useToggleView } from '../../../store/builder/store';
import { LineBasicMaterial, Line } from "three";
import loadInitialPoint from '../IntialLoad/loadInitialPoint';
import loadInitialLine from '../IntialLoad/loadInitialLine';
import { TransformControls } from '@react-three/drei';
const DxfFile = ({ floorPlanGroupPoint, currentLayerPoint, dragPointControls, floorPlanGroupLine, lines, setUpdateScene }: any) => {
const { dfxuploaded, dfxWallGenerate } = useDfxUpload();
const { toggleView } = useToggleView();
useEffect(() => {
if (dfxWallGenerate && dragPointControls && floorPlanGroupPoint && currentLayerPoint && floorPlanGroupLine) {
lines.current = dfxWallGenerate;
loadInitialPoint(lines, floorPlanGroupPoint, currentLayerPoint, dragPointControls);
loadInitialLine(floorPlanGroupLine, lines);
setUpdateScene(true);
}
}, [lines, floorPlanGroupLine, floorPlanGroupPoint, currentLayerPoint, dragPointControls, dfxWallGenerate])
return (
<>
{dfxuploaded && dfxuploaded.length > 0 && toggleView && dfxuploaded?.map((geometry: any, index: any) => (
<TransformControls>
<group>
<primitive
key={index}
object={new Line(geometry, new LineBasicMaterial({ color: 'red' }))}
rotation={[-Math.PI / 2, 0, 0]}
/>
</group>
</TransformControls>
))}
</>
);
}
export default DxfFile;

View File

@ -0,0 +1,65 @@
import { BufferGeometry, Vector3 } from "three";
export const convertDXFToThree = (dxfData: DXFData): BufferGeometry[] => {
const geometries: BufferGeometry[] = [];
const UNIT = 1000;
if (dxfData.entities) {
dxfData.entities.forEach((entity) => {
// LINE
if (entity.type === "LINE" && entity.vertices) {
const points = [
new Vector3(entity.vertices[0].x, entity.vertices[0].y, 0),
new Vector3(entity.vertices[1].x, entity.vertices[1].y, 0),
];
const geometry = new BufferGeometry().setFromPoints(points);
geometry.scale(1 / UNIT, 1 / UNIT, 1 / UNIT);
geometries.push(geometry);
}
// LWPOLYLINE
else if (entity.type === "LWPOLYLINE" && entity.vertices) {
const points: Vector3[] = entity.vertices.map(
(v: any) => new Vector3(v.x, v.y, 0)
);
for (let i = 0; i < points.length - 1; i++) {
const segment = [points[i], points[i + 1]];
const geometry = new BufferGeometry().setFromPoints(segment);
geometry.scale(1 / UNIT, 1 / UNIT, 1 / UNIT);
geometries.push(geometry);
}
}
// ARC
else if (
entity.type === "ARC" &&
entity.center &&
entity.radius !== undefined
) {
const { center, radius, startAngle, endAngle } = entity;
if (
center === undefined ||
radius === undefined ||
startAngle === undefined ||
endAngle === undefined
)
return;
const numSegments = 32;
const points: Vector3[] = [];
for (let i = 0; i <= numSegments; i++) {
const t = i / numSegments;
const angle = startAngle + t * (endAngle - startAngle); // linear interpolation
const x = center.x + radius * Math.cos(angle);
const y = center.y + radius * Math.sin(angle);
points.push(new Vector3(x, y, 0));
}
const geometry = new BufferGeometry().setFromPoints(points);
geometry.scale(1 / UNIT, 1 / UNIT, 1 / UNIT);
geometries.push(geometry);
}
});
}
return geometries;
};

View File

@ -0,0 +1,141 @@
import { MathUtils, Vector3, BufferGeometry } from "three";
interface Props {
parsedData: DXFData;
setDfxGenerate: (walls: WallLineVertex[][]) => void;
}
export function getWallPointsFromBlueprint({
parsedData,
setDfxGenerate,
}: Props) {
if (!parsedData.entities) return;
const unit = 1000; // Convert mm to meters
const wallVertex: WallLineVertex[][] = [];
parsedData.entities.forEach((entity: DXFEntity) => {
if (entity.type === "LINE" && entity.vertices) {
const startVec = new Vector3(
entity.vertices[0].x / unit,
0.01,
-entity.vertices[0].y / unit
);
const endVec = new Vector3(
entity.vertices[1].x / unit,
0.01,
-entity.vertices[1].y / unit
);
const existingStart = wallVertex
.flat()
.find((v) => v[0].equals(startVec));
const startPoint: WallLineVertex = existingStart || [
startVec,
MathUtils.generateUUID(),
1,
"WallLine",
];
const existingEnd = wallVertex.flat().find((v) => v[0].equals(endVec));
const endPoint: WallLineVertex = existingEnd || [
endVec,
MathUtils.generateUUID(),
1,
"WallLine",
];
wallVertex.push([startPoint, endPoint]);
} else if (entity.type === "LWPOLYLINE" && entity.vertices) {
let firstPoint: WallLineVertex | undefined;
for (let i = 0; i < entity.vertices.length - 1; i++) {
const startVec = new Vector3(
entity.vertices[i].x / unit,
0.01,
-entity.vertices[i].y / unit
);
const endVec = new Vector3(
entity.vertices[i + 1].x / unit,
0.01,
-entity.vertices[i + 1].y / unit
);
const existingStart = wallVertex
.flat()
.find((v) => v[0].equals(startVec));
const startPoint: WallLineVertex = existingStart || [
startVec,
MathUtils.generateUUID(),
1,
"WallLine",
];
const existingEnd = wallVertex.flat().find((v) => v[0].equals(endVec));
const endPoint: WallLineVertex = existingEnd || [
endVec,
MathUtils.generateUUID(),
1,
"WallLine",
];
wallVertex.push([startPoint, endPoint]);
if (i === 0) firstPoint = startPoint;
if (i === entity.vertices.length - 2 && firstPoint)
wallVertex.push([endPoint, firstPoint]);
}
} else if (entity.type === "ARC") {
const { center, radius, startAngle, endAngle } = entity;
if (
!center ||
radius === undefined ||
startAngle === undefined ||
endAngle === undefined
)
return;
const numSegments = 16;
const angleStep = (endAngle - startAngle) / numSegments;
const arcPoints: Vector3[] = [];
for (let i = 0; i <= numSegments; i++) {
const angle = startAngle + i * angleStep;
const x = center.x + radius * Math.cos(angle);
const y = -center.y + radius * Math.sin(angle);
arcPoints.push(new Vector3(x / unit, 0.01, y / unit));
}
for (let i = 0; i < arcPoints.length - 1; i++) {
const startVec = arcPoints[i];
const endVec = arcPoints[i + 1];
const existingStart = wallVertex
.flat()
.find((v) => v[0].equals(startVec));
const startPoint: WallLineVertex = existingStart || [
startVec,
MathUtils.generateUUID(),
1,
"WallLine",
];
const existingEnd = wallVertex.flat().find((v) => v[0].equals(endVec));
const endPoint: WallLineVertex = existingEnd || [
endVec,
MathUtils.generateUUID(),
1,
"WallLine",
];
wallVertex.push([startPoint, endPoint]);
}
} else {
console.error("Unsupported entity type:", entity.type);
}
});
setDfxGenerate(wallVertex);
}

View File

@ -1,33 +0,0 @@
import React from 'react';
import { useToggleView, useZones } from '../../store/builder/store';
import { Html } from '@react-three/drei';
const FindZoneName = () => {
const { zones } = useZones();
const { toggleView } = useToggleView();
return (
<>
{!toggleView && zones?.map((zone: any) => (
<Html
key={zone.zoneId}
position={[zone.viewPortCenter[0], zone.viewPortCenter[1] + 5.1, zone.viewPortCenter[2]]}
center
distanceFactor={20}
style={{
background: '#6f42c1',
padding: '4px 8px',
borderRadius: '4px',
fontSize: '18px',
color: "white",
width: "100px",
border: '1px solid #ccc'
}}
>
{zone.zoneName}
</Html>
))}
</>
);
}
export default FindZoneName;

View File

@ -50,6 +50,7 @@ const FloorPlanGroup = ({ floorPlanGroup, floorPlanGroupLine, floorPlanGroupPoin
getLines(organization).then((data) => { getLines(organization).then((data) => {
const Lines: Types.Lines = objectLinesToArray(data); const Lines: Types.Lines = objectLinesToArray(data);
console.log('Lines: ', Lines);
// const data = localStorage.getItem("Lines"); // const data = localStorage.getItem("Lines");

View File

@ -459,88 +459,91 @@ interface ShortcutStore {
} }
export const useShortcutStore = create<ShortcutStore>((set) => ({ export const useShortcutStore = create<ShortcutStore>((set) => ({
showShortcuts: false, showShortcuts: false,
setShowShortcuts: (value) => set({ showShortcuts: value }), setShowShortcuts: (value) => set({ showShortcuts: value }),
toggleShortcuts: () => toggleShortcuts: () =>
set((state) => ({ showShortcuts: !state.showShortcuts })), set((state) => ({ showShortcuts: !state.showShortcuts })),
})); }));
export const useMachineCount = create<any>((set: any) => ({ export const useMachineCount = create<any>((set: any) => ({
machineCount: 0, machineCount: 0,
setMachineCount: (x: any) => set({ machineCount: x }), setMachineCount: (x: any) => set({ machineCount: x }),
})); }));
export const useMachineUptime = create<any>((set: any) => ({ export const useMachineUptime = create<any>((set: any) => ({
machineActiveTime: 0, machineActiveTime: 0,
setMachineActiveTime: (x: any) => set({ machineActiveTime: x }), setMachineActiveTime: (x: any) => set({ machineActiveTime: x }),
})); }));
export const useMaterialCycle = create<any>((set: any) => ({ export const useMaterialCycle = create<any>((set: any) => ({
materialCycleTime: 0, materialCycleTime: 0,
setMaterialCycleTime: (x: any) => set({ materialCycleTime: x }), setMaterialCycleTime: (x: any) => set({ materialCycleTime: x }),
})); }));
export const useThroughPutData = create<any>((set: any) => ({ export const useThroughPutData = create<any>((set: any) => ({
throughputData: 0, throughputData: 0,
setThroughputData: (x: any) => set({ throughputData: x }), setThroughputData: (x: any) => set({ throughputData: x }),
})); }));
export const useProductionCapacityData = create<any>((set: any) => ({ export const useProductionCapacityData = create<any>((set: any) => ({
productionCapacityData: 0, productionCapacityData: 0,
setProductionCapacityData: (x: any) => set({ productionCapacityData: x }), setProductionCapacityData: (x: any) => set({ productionCapacityData: x }),
})); }));
export const useProcessBar = create<any>((set: any) => ({ export const useProcessBar = create<any>((set: any) => ({
processBar: [], processBar: [],
setProcessBar: (x: any) => set({ processBar: x }), setProcessBar: (x: any) => set({ processBar: x }),
}));
export const useDfxUpload = create<any>((set: any) => ({
dfxuploaded: [],
dfxWallGenerate: [],
setDfxUploaded: (x: any) => set({ dfxuploaded: x }),
setDfxGenerate: (x: any) => set({ dfxWallGenerate: x }),
})); }));
type InputValuesStore = { type InputValuesStore = {
inputValues: Record<string, string>; inputValues: Record<string, string>;
setInputValues: (values: Record<string, string>) => void; setInputValues: (values: Record<string, string>) => void;
updateInputValue: (label: string, value: string) => void; // <- New updateInputValue: (label: string, value: string) => void; // <- New
}; };
export const useInputValues = create<InputValuesStore>((set) => ({ export const useInputValues = create<InputValuesStore>((set) => ({
inputValues: {}, inputValues: {},
setInputValues: (values) => set({ inputValues: values }), setInputValues: (values) => set({ inputValues: values }),
updateInputValue: (label, value) => updateInputValue: (label, value) =>
set((state) => ({ set((state) => ({
inputValues: { inputValues: {
...state.inputValues, ...state.inputValues,
[label]: value, [label]: value,
}, },
})), })),
})); }));
export interface ROISummaryData { export interface ROISummaryData {
productName: string; productName: string;
roiPercentage: number; roiPercentage: number;
paybackPeriod: number; paybackPeriod: number;
totalCost: number; totalCost: number;
revenueGenerated: number; revenueGenerated: number;
netProfit: number; netProfit: number;
netLoss: number; netLoss: number;
} }
interface ROISummaryStore { interface ROISummaryStore {
roiSummary: ROISummaryData; roiSummary: ROISummaryData;
setRoiSummaryData: (values: ROISummaryData) => void; setRoiSummaryData: (values: ROISummaryData) => void;
} }
export const useROISummaryData = create<ROISummaryStore>((set) => ({ export const useROISummaryData = create<ROISummaryStore>((set) => ({
roiSummary: { roiSummary: {
productName: "", productName: "",
roiPercentage: 0, roiPercentage: 0,
paybackPeriod: 0, paybackPeriod: 0,
totalCost: 0, totalCost: 0,
revenueGenerated: 0, revenueGenerated: 0,
netProfit: 0, netProfit: 0,
netLoss: 0, netLoss: 0,
}, },
setRoiSummaryData: (values) => set({ roiSummary: values }), setRoiSummaryData: (values) => set({ roiSummary: values }),
})); }));
interface CompareStore { interface CompareStore {
comparePopUp: boolean; comparePopUp: boolean;
setComparePopUp: (value: boolean) => void; setComparePopUp: (value: boolean) => void;

View File

@ -1,6 +1,6 @@
import { create } from 'zustand'; import { create } from 'zustand';
type Layout = null | 'layout1' | 'layout2'; type Layout = null | 'layout1' | 'layout2' ;
type LayoutState = { type LayoutState = {
currentLayout: Layout; currentLayout: Layout;

View File

@ -1,31 +1,53 @@
interface Asset { interface Asset {
modelUuid: string; modelUuid: string;
modelName: string; modelName: string;
assetId: string; assetId: string;
position: [number, number, number]; position: [number, number, number];
rotation: [number, number, number]; rotation: [number, number, number];
isLocked: boolean; isLocked: boolean;
isCollidable: boolean; isCollidable: boolean;
isVisible: boolean; isVisible: boolean;
opacity: number; opacity: number;
animations?: string[]; animations?: string[];
animationState?: { animationState?: {
current: string; current: string;
playing: boolean; playing: boolean;
};
eventData?: {
type: string;
point?: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
}; };
eventData?: { points?: {
type: string; uuid: string;
point?: { position: [number, number, number];
uuid: string; rotation: [number, number, number];
position: [number, number, number]; }[];
rotation: [number, number, number]; };
} }
points?: {
uuid: string;
position: [number, number, number];
rotation: [number, number, number];
}[];
}
};
type Assets = Asset[]; type Assets = Asset[];
// DXF Entity Schema
interface DXFEntity {
type: string;
vertices?: { x: number; y: number }[];
center?: { x: number; y: number; z: number };
radius?: number;
startAngle?: number;
endAngle?: number;
}
interface DXFData {
entities?: DXFEntity[];
}
type WallLineVertex = [
Vector3,
string, // uuid
number,
string // "WallLine"
];