UNPKG

awv3

Version:
238 lines (214 loc) 8.88 kB
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> ); } } @connect((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> ); } } @connect(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); } } }; }