pull/744/MERGE
ZoeLeeFZ 5 years ago committed by ChenX
parent 13ce190406
commit 9e5f7a5855

@ -0,0 +1,132 @@
import { Intent } from '@blueprintjs/core';
import { Mesh, Vector3 } from 'three';
import { app } from '../ApplicationServices/Application';
import { DisposeThreeObj } from '../Common/Dispose';
import { CylinderHole } from '../DatabaseServices/3DSolid/CylinderHole';
import { Entity } from '../DatabaseServices/Entity/Entity';
import { ExtrudeSolid } from '../DatabaseServices/Entity/Extrude';
import { PromptStatus } from '../Editor/PromptResult';
import { userConfig } from '../Editor/UserConfig';
import { RenderType } from '../GraphicsSystem/RenderType';
import { InterfereModal } from '../UI/Components/Modal/InterfereModal';
import { ModalPosition } from '../UI/Components/Modal/ModalsManage';
import { ColorMaterial } from './../Common/ColorPalette';
import { CSG } from './../csg/core/CSG';
import { CSG2Geometry, Geometry2CSG } from './../csg/core/Geometry2CSG';
import { FastDrillingMeshGeometry } from './../DatabaseServices/3DSolid/CylinderHole';
import { ExtrudeHole } from './../DatabaseServices/3DSolid/ExtrudeHole';
import { SweepSolid } from './../DatabaseServices/3DSolid/SweepSolid';
import { Command } from './../Editor/CommandMachine';
import { AppToaster } from './../UI/Components/Toaster';
//| CylinderHole | ExtrudeHole
export type Solid3D = ExtrudeSolid | SweepSolid | ExtrudeHole;
export class Interfere implements Command
{
async exec()
{
const Filter = {
filterTypes: [ExtrudeHole, ExtrudeSolid, SweepSolid]
};
let enRes = await app.Editor.GetSelection({
Msg: "选择检查干涉的对象",
Filter
});
if (enRes.Status === PromptStatus.Cancel) return;
let ens = enRes.SelectSet.SelectEntityList as Solid3D[];
let set1 = new Set();
let objMap: Map<Mesh, [Solid3D, Solid3D]> = new Map();
const csgCache: WeakMap<Entity, CSG> = new WeakMap();
for (let i = 0; i < ens.length; i++)
{
let e1 = ens[i];
let c1: CSG;
if (csgCache.has(e1))
c1 = csgCache.get(e1);
else
c1 = this.GetCSG(e1);
let obb1 = e1.OBB;
for (let j = i + 1; j < ens.length; j++)
{
let e2 = ens[j];
if (!obb1.intersectsOBB(e2.OBB))
continue;
let c2: CSG;
if (csgCache.has(e2))
c2 = csgCache.get(e2);
else
{
c2 = this.GetCSG(e2);
csgCache.set(e2, c2);
}
if (!c2)
console.error("实体CSG出错");
let c = c1.intersect(c2.transform1(e1.OCSInv.multiply(e2.OCS)));
if (c.polygons.length > 0)
{
set1.add(e1);
set1.add(e2);
let g = CSG2Geometry(c).applyMatrix4(e1.OCS);
g.computeBoundingBox();
if (g.boundingBox.getSize(new Vector3).toArray().every(n => n > 1 - 1e-3))
{
let m = new Mesh(g, ColorMaterial.GetBasicMaterial(1).clone());
objMap.set(m, [e1, e2]);
}
}
}
}
if (objMap.size === 0)
{
AppToaster.show({
message: "未找到干涉对象",
timeout: 2000,
intent: Intent.SUCCESS,
});
return;
}
for (let [o,] of objMap)
{
app.Viewer.Scene.add(o);
}
let oldType = userConfig.RenderType;
userConfig.RenderType = RenderType.Wireframe;
app.Editor.ModalManage.RenderModeless(InterfereModal, ModalPosition.Center, { count: set1.size, data: objMap });
await app.Editor.ModalManage.Wait();
for (let [o,] of objMap)
{
DisposeThreeObj(o);
app.Viewer.Scene.remove(o);
}
userConfig.RenderType = oldType;
}
private GetCSG(en: Solid3D)
{
if (en instanceof ExtrudeSolid)
{
return en.CSG;
}
else
{
return Geometry2CSG(en.MeshGeometry);
}
}
}

@ -94,7 +94,7 @@ export class CylinderHole extends Hole
return box.applyMatrix4(this.OCS);
}
private _MeshGeometry: CylinderBufferGeometry;
private get MeshGeometry()
get MeshGeometry()
{
if (this._MeshGeometry)
return this._MeshGeometry;

@ -17,6 +17,7 @@ import { ExtureContourCurve } from "../Entity/Extrude";
import { Polyline } from "../Entity/Polyline";
import { Shape } from "../Shape";
import { Hole } from "./Hole";
import { OBB } from './../../Geometry/OBB/obb';
@Factory
export class ExtrudeHole extends Hole
@ -154,7 +155,7 @@ export class ExtrudeHole extends Hole
return this._EdgeGeometry;
}
private _MeshGeometry: BufferGeometry | Geometry;
private get MeshGeometry()
get MeshGeometry()
{
if (this._MeshGeometry)
return this._MeshGeometry;
@ -347,6 +348,11 @@ export class ExtrudeHole extends Hole
obj.add(...FastWireframe2(this));
}
}
get OBB(): OBB
{
let size = this.ContourCurve.BoundingBox.getSize(new Vector3).setZ(this.Height);
return new OBB(this.OCS, size.multiplyScalar(0.5));
}
ReadFile(file: CADFiler)
{
super.ReadFile(file);

@ -15,6 +15,7 @@ import { Entity } from "../Entity/Entity";
import { arrayLast } from "../../Common/ArrayExt";
import { Box3Ext } from "../../Geometry/Box";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { OBB } from './../../Geometry/OBB/obb';
@Factory
export class SweepSolid extends Entity
@ -118,7 +119,7 @@ export class SweepSolid extends Entity
console.log("提供的轮廓没有和路径垂直");
}
private _MeshGeometry: SweepGeometry;
private get MeshGeometry()
get MeshGeometry()
{
if (this._MeshGeometry)
return this._MeshGeometry;
@ -193,6 +194,12 @@ export class SweepSolid extends Entity
{
return new Box3Ext().setFromPoints(this.GetStretchPoints());
}
get OBB(): OBB
{
let s = this.Contour.BoundingBox.getSize(new Vector3);
let size = this._PathCurve.BoundingBox.getSize(new Vector3).setZ(Math.max(s.x, s.y));
return new OBB(this.OCS, size.multiplyScalar(0.5));
}
GetObjectSnapPoints(
snapMode: ObjectSnapMode,
pickPoint: Vector3,

@ -1213,7 +1213,7 @@ export class ExtrudeSolid extends Entity
}
private _MeshGeometry: Geometry | BufferGeometry;
private get MeshGeometry()
get MeshGeometry()
{
if (this._MeshGeometry)
return this._MeshGeometry;

@ -157,6 +157,7 @@ import { Text2Curve } from "../Add-on/Text2Curve";
import { DrawVisualSpaceBox } from "../Add-on/Template/DrawVisualSpaceBox";
import { Align } from './../Add-on/Align';
import { BuyMaterial } from './../Add-on/BuyMaterial';
import { Interfere } from './../Add-on/interfere';
export function registerCommand()
{
@ -432,6 +433,7 @@ export function registerCommand()
commandMachine.RegisterCommand("align", new Align());
commandMachine.RegisterCommand("buymaterial", new BuyMaterial());
commandMachine.RegisterCommand("interfere", new Interfere());
RegistCustomCommand();
}

@ -0,0 +1,112 @@
import React, { Component } from 'react';
import { Classes, Button } from '@blueprintjs/core';
import { app } from '../../../ApplicationServices/Application';
import { Card } from '@blueprintjs/core';
import { Mesh, MeshBasicMaterial, Vector3, Box3 } from 'three';
import { Solid3D } from '../../../Add-on/interfere';
import { Intent } from '@blueprintjs/core';
import { observable } from 'mobx';
import { observer } from 'mobx-react';
import { ColorMaterial } from './../../../Common/ColorPalette';
import { FixIndex } from './../../../Common/Utils';
import { CommonModal } from './ModalContainer';
interface IInterfereProps
{
count: number,
data: Map<Mesh, [Solid3D, Solid3D]>;
}
@observer
export class InterfereModal extends Component<IInterfereProps, {}> {
@observable currentIndex = -1;
render()
{
const { count, data } = this.props;
return (
<CommonModal
title="干涉检查"
icon="applications"
close={this.close}
hasConfig={false}
bodyStyle={{ width: 300 }}
footerStyle={{ width: "100%" }}
footerChildren={
<Button
className={Classes.INTENT_DANGER}
text="关闭"
onClick={this.close} />
}
>
<Card className="flex" style={{ padding: 10 }}>
<div style={{ width: "60%", paddingRight: 10 }}>
<h5>{count}</h5>
<div className="flex-between">
<span></span>
<span>{data.size}</span>
</div>
</div>
<div className="flex-col" style={{ width: "40%" }}>
<h5></h5>
<Button
text="上一个"
intent={Intent.SUCCESS}
onClick={this.previos}
/>
<Button
text="下一个"
intent={Intent.SUCCESS}
onClick={this.next}
/>{
this.currentIndex >= 0 && <span>{this.currentIndex + 1}{data.size}</span>
}
</div>
</Card>
</CommonModal>
);
}
private close = () =>
{
app.Editor.ModalManage.Clear();
app.Editor.ModalManage.EndCmd();
app.Viewer.OutlinePass.selectedObjects = [];
};
private restore = (os: Mesh[]) =>
{
for (let o of os)
{
let mat = o.material as MeshBasicMaterial;
mat.color = ColorMaterial.GetColor(1);
}
app.Viewer.OutlinePass.selectedObjects = [];
};
private next = () =>
{
let os = [...this.props.data.keys()];
this.restore(os);
this.currentIndex = FixIndex(this.currentIndex + 1, os.length);
this.update(os[this.currentIndex]);
};
private previos = () =>
{
let os = [...this.props.data.keys()];
this.restore(os);
this.currentIndex = FixIndex(this.currentIndex - 1, os.length);
this.update(os[this.currentIndex]);
};
private update = (o: Mesh) =>
{
let mat = o.material as MeshBasicMaterial;
mat.color = ColorMaterial.GetColor(3);
let box = new Box3();
app.Viewer.OutlinePass.selectedObjects = this.props.data.get(o).map(e =>
{
box.union(e.BoundingBox);
return e.DrawObject;
});
app.Viewer.CameraCtrl.ZoomExtensBox3(box);
app.Viewer.Zoom(1, box.getCenter(new Vector3));
};
}

@ -1,4 +1,4 @@
import React, { Component } from 'react'
import React, { Component } from 'react';
import { Icon, Button, Classes, IconName } from '@blueprintjs/core';
import { UserConfig } from '../Board/UserConfig';
import { IConfigStore } from '../../Store/BoardStore';
@ -17,6 +17,8 @@ interface IModalProps
footerChildren?: JSX.Element | (JSX.Element[]),
type?: BoardModalType,
bodyClass?: string;
bodyStyle?: React.CSSProperties;
footerStyle?: React.CSSProperties;
containerEl?: (el) => void;
}
@ -30,7 +32,7 @@ export class CommonModal extends Component<IModalProps>{
icon={this.props.icon}
close={this.props.close}
/>
<ModalBody className={this.props.bodyClass || ""}>
<ModalBody className={this.props.bodyClass || ""} bodyStyle={this.props.bodyStyle}>
{
this.props.children
}
@ -38,13 +40,14 @@ export class CommonModal extends Component<IModalProps>{
<ModalFooter
hasConfig={this.props.hasConfig}
store={this.props.store}
style={this.props.footerStyle}
type={this.props.type} >
{
this.props.footerChildren
}
</ModalFooter>
</ModalContainer>
)
);
}
}
@ -53,7 +56,7 @@ interface IModalContainer
containerEl?: (el) => void;
modalId?: string;
className?: string;
children?: JSX.Element | JSX.Element[]
children?: JSX.Element | JSX.Element[];
}
export class ModalContainer extends Component<IModalContainer>
@ -72,7 +75,7 @@ export class ModalContainer extends Component<IModalContainer>
}
</div>
</div>
)
);
}
}
@ -102,26 +105,34 @@ export class ModalHeader extends Component<IModalHeaderProps>
onClick={this.props.close}
/>
</div>
)
);
}
}
export class ModalBody extends Component<{ children?: JSX.Element | JSX.Element[], className?: string }>
interface IModalBodyProps
{
bodyStyle?: React.CSSProperties;
children?: JSX.Element | JSX.Element[];
className?: string;
}
export class ModalBody extends Component<IModalBodyProps>
{
static defaultProps = {
className: "",
}
};
render()
{
return (
<div
className={Classes.DIALOG_BODY + " " + this.props.className}
style={this.props.bodyStyle}
>
{
this.props.children
}
</div>
)
);
}
}
@ -138,7 +149,7 @@ export class ModalFooter extends Component<IModalFooterProps>
{
static defaultProps = {
hasConfig: true
}
};
render()
{
return (
@ -151,6 +162,6 @@ export class ModalFooter extends Component<IModalFooterProps>
{this.props.children}
</div>
</div>
)
);
}
}

Loading…
Cancel
Save