awv3
Version:
⚡ AWV3 embedded CAD
238 lines (214 loc) • 8.88 kB
JavaScript
import * as THREE from 'three';
import { actions as connectionActions } from '../../session/store/connections';
import { actions as elementActions } from '../../session/store/elements';
import Plugin from '../../session/plugin';
import Dimension from '../dimension/';
import Element from '../../session/element';
import React, { Component, connect } from '../../session/renderer';
import { Spacer, Group, Button, Input, Label, Selection, Dropdown, Link, Checkbox } from '../../session/elements';
import Feature from '../feature/';
const resources = ['isometric'].reduce(
(prev, item) => ({ ...prev, [item]: require('!!url-loader!awv3-icons/32x32/' + item + '.png') }),
{},
);
class CreatePanel extends Component {
constructor(props) {
super(props);
this.state = { items: props.defaultSelection, type: 'Fillet', radius: 1, offset1: 1, offset2: 1 };
}
render({ visible, createFillet }, { type, items, radius, offset1, offset2 }, set) {
return (
<Group format={Group.Format.Table}>
<Group name="Target" format={Group.Format.Rows}>
<Selection
types={['Mesh', 'LineSegments']}
limit={1}
visible={visible}
items={items}
onItems={items => set({ items })}
/>
<Button
name="Create"
visible={items.length != 0}
flex={0}
onLastEvent={() => createFillet(this.state)}
/>
</Group>
<Dropdown name="Type" items={['Fillet', 'Chamfer']} value={type} onValue={type => set({ type })} />
<Input
name="Radius"
visible={type === 'Fillet'}
hint="expression"
value={radius}
onValue={v => set({ radius: parseFloat(v) || '' })}
/>
<Input
name="Offset1"
visible={type === 'Chamfer'}
hint="expression"
value={offset1}
onValue={v => set({ offset1: parseFloat(v) || '' })}
/>
<Input
name="Offset2"
visible={type === 'Chamfer'}
hint="expression"
value={offset2}
onValue={v => set({ offset2: parseFloat(v) || '' })}
/>
</Group>
);
}
}
((state, props) => {
let connection = state.connections[state.globals.activeConnection];
return { feature: connection.tree[props.id] };
})
class FeaturePlugin extends Component {
constructor(props) {
super(props);
this.state = { flip: false };
this.proto = new Feature(this.plugin.session, {
icon: 'isometric',
name: props.feature.name,
filter: ['radius', 'offset1', 'offset2'],
collapsed: true,
closeable: false,
parent: this.plugin.id,
feature: props.feature,
pool: new THREE.Group(),
connection: this.plugin.connection,
});
this.proto.enabled = true;
}
componentWillUnmount() {
this.proto.destroy();
}
flip = flip => {
this.setState({ flip });
const offset1 = this.proto.findElementClass(el => el.type === Element.Type.Input && el.name === 'offset1');
const offset2 = this.proto.findElementClass(el => el.type === Element.Type.Input && el.name === 'offset2');
if (offset1 && offset2) {
const temp = offset1.value;
offset1.value = offset2.value;
offset2.value = temp;
this.update(offset1, offset2);
}
};
update = (
offset1 = this.proto.findElementClass(el => el.type === Element.Type.Input && el.name === 'offset1'),
offset2 = this.proto.findElementClass(el => el.type === Element.Type.Input && el.name === 'offset2'),
radius = this.proto.findElementClass(el => el.type === Element.Type.Input && el.name === 'radius'),
) => {
const isFillet = this.props.feature.class.indexOf('Fillet') != -1;
const operation = this.props.feature.id;
const command = `_C.CADApplication.SetFeatureParams(${operation}, [${isFillet
? parseFloat(radius.value)
: `${parseFloat(offset1.value)}, ${parseFloat(offset2.value)}`}], 1);`;
console.log(command);
this.plugin.connection.execute(command);
};
render({ feature, hoverPlugins }, { flip }, set) {
let isFillet = feature.class.indexOf('Fillet') != -1;
let values = isFillet
? feature.members.radius.value
: `${feature.members.offset1.value}, ${feature.members.offset2.value}`;
this.proto.feature = feature.id;
return (
<Group
name={`${feature.name} = ${values}`}
format={Group.Format.Collapse}
collapsed={true}
onLastEvent={event => hoverPlugins(event, feature)}>
<Link value={this.proto.id} collapsable={false} />
<Group format={Group.Format.Table}>
{!isFillet && <Checkbox name="Flip" value={flip} onValue={this.flip} />}
<Group name="Actions" format={Group.Format.Buttons}>
<Button name="Delete" color="black" />
<Button name="Reset" color="gray" />
<Button name="Apply" color="blue" onLastEvent={() => this.update()} />
</Group>
</Group>
</Group>
);
}
}
(state => {
const connection = state.connections[state.globals.activeConnection];
const tree = connection.tree;
const root = tree[tree.root];
return { features: root.features };
})
class Features extends Component {
render({ features, hoverPlugins }) {
const items = (features || [])
.filter(
feature =>
this.plugin.tree[feature].class.indexOf('Fillet') != -1 ||
this.plugin.tree[feature].class.indexOf('Chamfer') != -1,
);
return (
<Group>
{items.map(item => <FeaturePlugin id={item} hoverPlugins={hoverPlugins} />)}
</Group>
);
}
}
export default class Fillet extends Plugin {
constructor(session, args) {
super(session, {
type: 'Fillet',
icon: 'isometric',
selectionVisible: true,
defaultSelection: [],
resources,
...args,
});
}
render() {
return (
<Group>
<CreatePanel
visible={this.selectionVisible}
defaultSelection={this.defaultSelection}
createFillet={this.createFillet}
/>
<Spacer />
<Features hoverPlugins={this.hoverPlugins} />
</Group>
);
}
createFillet = async props => {
const { items, type, radius, offset1, offset2 } = props;
const hit = this.connection.pool.findMaterial(material => material.meta && material.meta.id === items[0]);
if (hit && radius > 0) {
const id = hit.material.meta.originalId;
const isFillet = type === 'Fillet';
await this.connection.execute(
`_C.CADApplication.NewFeature(${this.tree.root}, "${isFillet
? 'CC_ConstantRadiusFillet'
: 'CC_Chamfer'}", "${isFillet ? 'Fillet' : 'Chamfer'}");`,
);
const operation = this.tree[this.root.features[this.root.features.length - 1]].id;
await this.connection.execute(`_C.CADApplication.FeatureBuildReferences(${operation}, [${id}]);`);
await this.connection.execute(
`_C.CADApplication.SetFeatureParams(${operation}, [${isFillet
? radius
: `${offset1}, ${offset2}`}], 1);`,
);
}
};
hoverPlugins = (event, feature) => {
const color = this.session.globals.colors.primary;
const hit = this.connection.pool.findMaterial(
material => material.meta && material.meta.operationId === feature.id,
);
if (hit) {
if (event.type === 'mouseenter') {
hit.material.animate({ color: new THREE.Color(color) }).start(500);
} else if (event.type === 'mouseleave') {
hit.material.animate(hit.material.meta.material).start(500);
}
}
};
}