pushing expressions to the sketcher

This commit is contained in:
Val Erastov (xibyte) 2019-11-28 02:01:48 -08:00
parent 9cf9f18e37
commit dbd871c920
10 changed files with 78 additions and 24 deletions

View file

@ -50,6 +50,12 @@ export function activate({streams, services}) {
pointer: modifications.length - 1
});
}
function rebuild() {
const mods = streams.craft.modifications.value;
reset([]);
streams.craft.modifications.next(mods);
}
function runRequest(request) {
let op = services.operation.get(request.type);
@ -79,7 +85,7 @@ export function activate({streams, services}) {
}
services.craft = {
modify, modifyInHistoryAndStep, reset, runRequest,
modify, modifyInHistoryAndStep, reset, runRequest, rebuild,
historyTravel: historyTravel(streams.craft.modifications)
};

View file

@ -19,19 +19,20 @@ import {aboveElement} from '../../../../../modules/ui/positionUtils';
inProgressOperation: insertOperationReq.type,
getOperation: type => operationRegistry[type]||EMPTY_OBJECT
})))
@mapContext(({streams}) => ({
@mapContext(({streams, services}) => ({
remove: atIndex => streams.craft.modifications.update(modifications => removeAndDropDependants(modifications, atIndex)),
cancel: () => streams.craft.modifications.update(modifications => finishHistoryEditing(modifications)),
setHistoryPointer: pointer => streams.craft.modifications.update(({history}) => ({history, pointer}))
setHistoryPointer: pointer => streams.craft.modifications.update(({history}) => ({history, pointer})),
rebuild: () => services.craft.rebuild()
}))
export default class HistoryTimeline extends React.Component {
render() {
let {history, pointer, setHistoryPointer, remove, getOperation, inProgressOperation} = this.props;
let {history, pointer, setHistoryPointer, rebuild, getOperation, inProgressOperation} = this.props;
let scrolly;
let eof = history.length-1;
return <div className={ls.root} ref={this.keepRef}>
<Controls pointer={pointer} eoh={eof} setHistoryPointer={this.setHistoryPointerAndRequestScroll}/>
<Controls rebuild={rebuild} history={history} pointer={pointer} eoh={eof} setHistoryPointer={this.setHistoryPointerAndRequestScroll}/>
<div className={ls.scroller} onClick={e => scrolly.scrollLeft -= 60}><Fa icon='caret-left'/></div>
<div className={ls.history} ref={el => scrolly = el}>
{history.map((m, i) => <React.Fragment key={i}>
@ -102,10 +103,13 @@ function Handle() {
</svg>;
}
function Controls({pointer, eoh, setHistoryPointer}) {
function Controls({rebuild, history, pointer, eoh, setHistoryPointer, }) {
const noB = pointer===-1;
const noF = pointer===eoh;
return <React.Fragment>
<button disabled={!history.length} className={cx(ls.controlBtn)} onClick={rebuild}>
<Fa icon='repeat' fw/>
</button>
<div className={cx(ls.controlBtn, noB&&ls.disabled)} onClick={noB?undefined :() => setHistoryPointer(pointer-1)}>
<Fa icon='step-backward' fw/>
</div>

View file

@ -1,6 +1,6 @@
import {state, stream, merge} from 'lstream';
import {indexArray} from '../../../../modules/gems/iterables';
import {NOOP} from '../../../../modules/gems/func';
import {merge, state} from 'lstream';
import {indexArray} from 'gems/iterables';
import {NOOP} from 'gems/func';
export function defineStreams(ctx) {
const script = state('');
@ -39,8 +39,10 @@ export function activate(ctx) {
return value;
}
ctx.services.expressions = {
reevaluateExpressions, load, evaluateExpression
reevaluateExpressions, load, evaluateExpression,
signature: ''
};
ctx.streams.expressions.list.attach(list => ctx.services.expressions.signature = Date.now() + '');
ctx.services.action.registerAction({
id: 'expressionsUpdateTable',
appearance: {

View file

@ -19,7 +19,7 @@ export class InPlaceSketcher {
return !!this.face
}
enter(face) {
enter(face, headless) {
let viewer3d = this.ctx.services.viewer;
this.face = face;
this.face.ext.view.sketchGroup.visible = false;
@ -34,6 +34,7 @@ export class InPlaceSketcher {
container.appendChild(canvas);
this.viewer = new Viewer(canvas, IO);
this.viewer.parametricManager.externalConstantResolver = this.ctx.services.expressions.evaluateExpression;
this.ctx.streams.sketcherApp = this.viewer.streams;
this.syncWithCamera();
@ -45,7 +46,7 @@ export class InPlaceSketcher {
this.viewer.io.loadSketch(sketchData);
this.ctx.streams.sketcher.sketchingFace.value = face;
}
get sketchStorageKey() {
return this.ctx.services.project.sketchStorageKey(this.face.id);
}
@ -106,7 +107,9 @@ export class InPlaceSketcher {
};
save() {
this.ctx.services.storage.set(this.sketchStorageKey, this.viewer.io.serializeSketch());
this.ctx.services.storage.set(this.sketchStorageKey, this.viewer.io.serializeSketch({
expressionsSignature: this.ctx.services.expressions.signature
}));
}
}

View file

@ -5,6 +5,9 @@ import {InPlaceSketcher} from './inPlaceSketcher';
import sketcherUIContrib from './sketcherUIContrib';
import initReassignSketchMode from './reassignSketchMode';
import sketcherStreams from '../../sketcher/sketcherStreams';
import {Viewer} from "../../sketcher/viewer2d";
import {IO} from "../../sketcher/io";
import {DelegatingPanTool} from "../../sketcher/tools/pan";
export function defineStreams(ctx) {
ctx.streams.sketcher = {
@ -55,11 +58,34 @@ export function activate(ctx) {
return services.storage.remove(sketchStorageKey);
}
const headlessCanvas = document.createElement('canvas');
document.createElement('div').appendChild(headlessCanvas);
function readSketch(sketchId) {
let savedSketch = getSketchData(sketchId);
if (savedSketch === null) {
return null;
}
let signature = services.expressions.signature;
if (savedSketch && (!savedSketch.metadata || savedSketch.expressionsSignature !== signature)) {
try {
const viewer = new Viewer(headlessCanvas, IO);
viewer.parametricManager.externalConstantResolver = services.expressions.evaluateExpression;
viewer.historyManager.init(savedSketch);
viewer.io.loadSketch(savedSketch);
viewer.parametricManager.refresh();
services.storage.set(services.project.sketchStorageKey(sketchId), viewer.io.serializeSketch({
expressionsSignature: signature
}), true);
savedSketch = getSketchData(sketchId);
} catch (e) {
console.error(e);
return null;
}
}
try {
return ReadSketch(JSON.parse(savedSketch), sketchId, true);
} catch (e) {
@ -132,7 +158,14 @@ export function activate(ctx) {
}
}
});
streams.expressions.table.attach(() => {
if (inPlaceEditor.viewer !== null) {
inPlaceEditor.viewer.parametricManager.refresh();
}
updateAllSketches();
});
services.sketcher = {
sketchFace, sketchFace2D, updateAllSketches, getAllSketches, readSketch, hasSketch, inPlaceEditor, reassignSketch,
reassignSketchMode: initReassignSketchMode(ctx)

View file

@ -8,9 +8,11 @@ export function defineStreams(ctx) {
export function activate({services, streams}) {
function set(key, value) {
function set(key, value, quiet) {
localStorage.setItem(key, value);
notify(key);
if (!quiet) {
notify(key);
}
}
function get(key) {

View file

@ -12,7 +12,7 @@ export function activate({streams, services}) {
return sceneSolid;
}
function addOnScene(sceneSolid, skin) {
services.cadRegistry.update(null, [sceneSolid]);
streams.craft.models.next([sceneSolid]);
services.viewer.render();
}
services.tpi = Object.assign({

View file

@ -1,6 +1,6 @@
export {dotVM} from 'numeric';
function scalarOperand(v, out, func) {
export function scalarOperand(v, out, func) {
for (let i = 0; i < v.length; i++) {
out[i] = func(v[i]);
}

View file

@ -43,8 +43,8 @@ IO.prototype.loadSketch = function(sketchData) {
return this._loadSketch(JSON.parse(sketchData));
};
IO.prototype.serializeSketch = function() {
return JSON.stringify(this._serializeSketch());
IO.prototype.serializeSketch = function(metadata) {
return JSON.stringify(this._serializeSketch(metadata));
};
IO.prototype._loadSketch = function(sketch) {
@ -333,7 +333,7 @@ IO.prototype.cleanUpData = function() {
}
};
IO.prototype._serializeSketch = function() {
IO.prototype._serializeSketch = function(metadata) {
var sketch = {};
//sketch.boundary = boundary;
sketch['layers'] = [];
@ -408,6 +408,7 @@ IO.prototype._serializeSketch = function() {
if (constantDefinition !== undefined && constantDefinition != null && !/^\s*$/.test(constantDefinition)) {
sketch['constants'] = constantDefinition;
}
sketch.metadata = metadata;
return sketch;
};

View file

@ -19,6 +19,7 @@ class ParametricManager {
this.viewer.params.define('constantDefinition', null);
this.viewer.params.subscribe('constantDefinition', 'parametricManager', this.onConstantsExternalChange, this)();
this.constantResolver = this.createConstantResolver();
this.externalConstantResolver = null;
this.messageSink = msg => alert(msg);
}
@ -28,9 +29,11 @@ class ParametricManager {
}
ParametricManager.prototype.createConstantResolver = function() {
var pm = this;
return function(value) {
var _value = pm.constantTable[value];
return value => {
var _value = this.constantTable[value];
if (_value === undefined && this.externalConstantResolver) {
_value = this.externalConstantResolver(value);
}
if (_value !== undefined) {
value = _value;
} else if (typeof(value) != 'number') {