UNPKG

awv3

Version:
239 lines (220 loc) 9.34 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 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 Members from '../members/' 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={['LineSegments']} limit={1} visible={visible} items={items} onItems={items => set({ items })} /> <Button name="✔︎" color="blue" 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" format={Input.Format.Number} visible={type === 'Fillet'} hint="expression" value={radius} onValue={radius => set({ radius })} onLastEvent={e => e.key === 'Enter' && createFillet(this.state)} /> <Input name="Offset1" format={Input.Format.Number} visible={type === 'Chamfer'} hint="expression" value={offset1} onValue={offset1 => set({ offset1 })} onLastEvent={e => e.key === 'Enter' && createFillet(this.state)} /> <Input name="Offset2" format={Input.Format.Number} visible={type === 'Chamfer'} hint="expression" value={offset2} onValue={offset2 => set({ offset2 })} onLastEvent={e => e.key === 'Enter' && createFillet(this.state)} /> </Group> ) } } @connect((state, { connection, key }) => { connection = state.connections[connection] const tree = connection ? connection.tree : {} return { feature: tree[key] } }) class FeaturePlugin extends Component { state = { flip: false, color: undefined } componentWillMount() { this.proto = new Members(this.plugin.session, { icon: 'isometric', name: this.props.feature.name, filter: ['radius', 'offset1', 'offset2'], collapsed: true, closeable: false, parent: this.plugin.id, feature: this.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 names = isFillet ? '"radius"' : '"offset1", "offset2"' const values = isFillet ? parseFloat(radius.value) : `${parseFloat(offset1.value)}, ${parseFloat(offset2.value)}` const command = `_C.CADApplication.SetExpressions(${operation}, [${names}], [${values}], 1);` this.plugin.connection.execute(command) } render({ feature, hoverPlugins }, { flip, color }, set) { if (!feature) return null 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 color={color} 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.Rows}> <Button name="✘" color="black" /> <Button name="❙◀︎" color="grey" /> <Button name="✔︎" color="blue" onLastEvent={() => this.update()} /> </Group> </Group> </Group> ) } } @connect(state => { const connection = state.globals.activeConnection if (!connection) return {} const tree = state.connections[connection].tree const root = tree[tree.root] return { connection, features: root.features } }) class Features extends Component { render({ connection, features, hoverPlugins }) { const items = (features || []) .filter( feature => this.plugin.tree[feature].class.indexOf('Fillet') != -1 || this.plugin.tree[feature].class.indexOf('Chamfer') != -1, ) return items.map(item => <FeaturePlugin key={item} connection={connection} hoverPlugins={hoverPlugins} />) } } 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) } } } }