This commit is contained in:
IDONTSUDO 2024-06-19 15:23:01 +03:00
parent 53fe9bf51a
commit 81238c5182
74 changed files with 8646 additions and 52 deletions

View file

@ -0,0 +1,37 @@
import { Scene, Engine, MeshBuilder, FreeCamera, HemisphericLight, Vector3, SceneLoader } from 'babylonjs';
import { GLTFFileLoader, STLFileLoader } from 'babylonjs-loaders';
export class BabylonRepository {
engine: Engine;
canvas: HTMLCanvasElement;
scene: Scene;
constructor(canvas: HTMLCanvasElement) {
this.engine = new Engine(canvas, true);
this.scene = this.CreateScene();
this.engine.runRenderLoop(() => {
this.scene.render();
});
const Camera = new FreeCamera("camera", new Vector3(0, 1, -5), this.scene);
Camera.attachControl();
const light = new HemisphericLight("light", new Vector3(0, 1, 0), this.scene);
light.intensity = 0.5;
//3D Object
// const ground = MeshBuilder.CreateGround("ground", { width: 10, height: 10 }, this.scene);
// const sphereball = MeshBuilder.CreateSphere("sphereball", { diameter: 1 }, this.scene);
// sphereball.position = new Vector3(0, 1, 0)
SceneLoader.RegisterPlugin(new GLTFFileLoader())
SceneLoader.RegisterPlugin(new STLFileLoader());
}
CreateScene(): Scene {
const scene = new Scene(this.engine);
return scene;
}
load = (url: string) => {
SceneLoader.LoadAssetContainer(url)
}
}

View file

@ -22,7 +22,8 @@ import {
MeshBasicMaterial,
PlaneGeometry,
BoxGeometry,
AxesHelper
AxesHelper,
MeshStandardMaterial
} from "three";
import { TypedEvent } from "../helper/typed_event";
import { Result } from "../helper/result";
@ -187,6 +188,15 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
new Quaternion(0, 0, 0, 0)
);
}
load(path: string, name: string, loadCallback?: Function) {
this.loader(
'http://localhost:4001/1dfc4e1a-9c1a-4fa2-96b2-19c86acb6ea4/assets/libs/objects/untitled.glb',
loadCallback ? loadCallback : () => { },
name,
);
}
setTransformMode(mode?: SceneMode) {
switch (mode) {
@ -347,7 +357,10 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
case "glb":
this.glbLoader.load(
url,
(result) => { },
(result) => {
this.scene.add(result.scene)
},
(err) => { }
);
break;
@ -373,14 +386,28 @@ export class CoreThreeRepository extends TypedEvent<BaseSceneItemModel> {
case "dae":
this.daeLoader.load(
url,
(result) => { },
(result) => {
this.scene.add(result.scene.children[0])
},
(err) => { }
);
break;
case "stl":
this.stlLoader.load(
url,
(result) => { },
(result) => {
const material = new MeshStandardMaterial({
color: 'red',
metalness: 0.35,
roughness: 1,
opacity: 1.0,
transparent: false,
});
const mesh = new Mesh(result, material);
this.scene.add(mesh);
},
(err) => { }
);

Binary file not shown.

View file

@ -17,11 +17,11 @@ import {
StickObjectsMarkingScreenPath,
} from "../../features/_stick_objects_marking/stick_objects_marking_screen";
import { DataSetScreen, DatasetsScreenPath } from "../../features/dataset/dataset_screen";
import DetailsScreen, { DetailsScreenPath } from "../../features/details/details_screen";
import { AssemblesScreen, AssemblesScreenPath } from "../../features/assembles/assembles_screen";
import { SimulationScreen, SimulationScreenPath } from "../../features/simulations/simulations_screen";
import { EstimateScreen, EstimateScreenPath } from "../../features/estimate/estimate_screen";
import { SkillPath, SkillScreen } from "../../features/skils/skills_screen";
import { DetailsScreenPath, DetailsScreen } from "../../features/details/details_screen";
const idURL = ":id";

View file

@ -6,12 +6,12 @@ import { LoadingOutlined } from "@ant-design/icons";
import React from "react";
import { SceneManagerPath } from "../../../features/scene_manager/presentation/scene_manager";
import { AssemblesScreenPath } from "../../../features/assembles/assembles_screen";
import { DetailsScreenPath } from "../../../features/details/details_screen";
import { SimulationScreenPath } from "../../../features/simulations/simulations_screen";
import { EstimateScreenPath } from "../../../features/estimate/estimate_screen";
import { BehaviorTreeBuilderPath } from "../../../features/behavior_tree_builder/presentation/behavior_tree_builder_screen";
import { SkillPath as SkillScreenPath } from "../../../features/skils/skills_screen";
import { UiBaseError } from "../../model/ui_base_error";
import { DetailsScreenPath } from "../../../features/details/details_screen";
export interface IBlockProps {
name: string;
isActive: boolean;

View file

@ -0,0 +1,13 @@
import { HttpMethod, HttpRepository } from "../../core/repository/http_repository";
import { UUID } from "../all_projects/data/project_repository";
export interface Parts {
name: string;
part_path: string;
material_path: string;
httpUrl: string;
}
export class DetailsHttpRepository extends HttpRepository {
getAllDetails = async () => this._jsonRequest<Parts[]>(HttpMethod.GET, '/projects/assets/')
}

View file

@ -1,8 +1,125 @@
import * as React from "react";
import { observer } from "mobx-react-lite";
import { DetailsStore } from "./details_store";
import { MainPage } from "../../core/ui/pages/main_page";
import React, { useEffect } from "react";
import { CoreText, CoreTextType } from "../../core/ui/text/text";
export interface IDetailsScreenProps {}
export const DetailsScreenPath = "/detail";
export default function DetailsScreen(props: IDetailsScreenProps) {
return <MainPage page={"Детали"}></MainPage>;
}
export const DetailsScreenPath = "/details";
export const DetailsScreen = observer(() => {
const [store] = React.useState(() => new DetailsStore());
React.useEffect(() => {
store.loadScene(canvasRef.current!);
})
const canvasRef = React.useRef<HTMLCanvasElement>(null);
return (
<MainPage
page={"Детали"}
panelStyle={{ overflowX: "auto" }}
bodyChildren={
<canvas ref={canvasRef} style={{ overflow: "hidden", width: '100%' }} />
}
panelChildren={
<>
{store.detailsViewModel.map((el) => (
<div onClick={() => store.selectedDetail(el.label)} style={{ margin: 5, cursor: "pointer" }}>
<div style={el.selected ? { width: "100%", background: "#E8DEF8", borderRadius: 100 } : {}}>
<CoreText
style={{ textAlign: "start", padding: 10, paddingLeft: 40 }}
type={CoreTextType.large}
text={el.label}
/>
</div>
</div>
))}
</>
}
/>
);
});
// /* state-layer */
// /* Auto layout */
// display: flex;
// flex-direction: row;
// align-items: center;
// padding: 16px 24px 16px 16px;
// gap: 12px;
// width: 256px;
// height: 56px;
// /* Inside auto layout */
// flex: none;
// order: 0;
// align-self: stretch;
// flex-grow: 1;
// /* Icon */
// width: 24px;
// height: 24px;
// /* Inside auto layout */
// flex: none;
// order: 0;
// flex-grow: 0;
// /* icon */
// position: absolute;
// left: 25%;
// right: 25%;
// top: 25%;
// bottom: 25%;
// /* M3/sys/light/on-secondary-container */
// background: #1D192B;
// /* Label */
// width: 160px;
// height: 20px;
// /* M3/label/large - prominent */
// font-family: 'Roboto';
// font-style: normal;
// font-weight: 600;
// font-size: 14px;
// line-height: 20px;
// /* identical to box height, or 143% */
// letter-spacing: 0.1px;
// /* M3/sys/light/on-secondary-container */
// color: #1D192B;
// /* Inside auto layout */
// flex: none;
// order: 1;
// flex-grow: 1;
// /* Badge label text */
// width: 8px;
// height: 20px;
// /* M3/label/large - prominent */
// font-family: 'Roboto';
// font-style: normal;
// font-weight: 600;
// font-size: 14px;
// line-height: 20px;
// /* identical to box height, or 143% */
// text-align: right;
// letter-spacing: 0.1px;
// /* M3/sys/light/on-secondary-container */
// color: #1D192B;
// /* Inside auto layout */
// flex: none;
// order: 2;
// flex-grow: 0;

View file

@ -0,0 +1,57 @@
import makeAutoObservable from "mobx-store-inheritance";
import { CoreError, UiErrorState } from "../../core/store/base_store";
import { NavigateFunction } from "react-router-dom";
import { DetailsHttpRepository, Parts } from "./details_http_repository";
import { CoreThreeRepository } from "../../core/repository/core_three_repository";
import { Color } from "three";
import { BabylonRepository } from "../../core/repository/babylon_repository";
interface IDetailViewModel {
label: string;
selected: boolean;
httpUrl: string;
}
export class DetailsStore extends UiErrorState<CoreError> {
detailsViewModel: IDetailViewModel[] = [];
parts: Parts[] = [];
detailsHttpRepository: DetailsHttpRepository = new DetailsHttpRepository();
coreThereRepository?: CoreThreeRepository;
babylonRepository?: BabylonRepository;
constructor() {
super();
makeAutoObservable(this);
this.init();
}
errorHandingStrategy = (error: CoreError) => { };
init = async (navigate?: NavigateFunction | undefined): Promise<void> => {
await this.mapOk("parts", this.detailsHttpRepository.getAllDetails());
this.detailsViewModel = this.parts.map((el) => {
return {
label: el.name,
selected: false,
httpUrl: el.httpUrl,
};
});
};
selectedDetail = (label: string) => {
this.detailsViewModel.map((el) => {
el.selected = false;
return el;
});
this.detailsViewModel.map((el) => {
if (el.label.match(label)) {
el.selected = true;
this.babylonRepository?.load(el.httpUrl)
return el;
}
});
};
loadScene = async (ref: HTMLCanvasElement) => {
this.babylonRepository = new BabylonRepository(ref);
};
}

View file

@ -0,0 +1,11 @@
import { Result } from "../../core/helper/result";
export class NumberTriviaModel {
constructor() {}
isValid(): Result<string, void> {
return Result.ok();
}
static empty() {
return new NumberTriviaModel();
}
}

View file

@ -70,6 +70,7 @@ export class SceneMangerStore extends UiErrorState<HttpError> {
loadSceneRobossemblerAsset(name: string) {
try {
const assetPath = this.robossemblerAssets?.getAssetPath(name) as string;
this.coreThereRepository?.loader(assetPath, this.loaderWatcher, name);
this.visibleSaveButton();
} catch (error) {

View file

@ -1,7 +1,6 @@
import React from "react";
import ReactDOM from "react-dom/client";
import "reflect-metadata";
import "antd/dist/antd.min.css";
import ReactDOM from "react-dom/client";
import { extensions } from "./core/extensions/extensions";
import { SocketLister } from "./features/socket_lister/socket_lister";
import { RouterProvider } from "react-router-dom";