mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-23 17:04:00 +01:00
reassign sketch functionality
This commit is contained in:
parent
a53bc95ffa
commit
778403fd19
7 changed files with 122 additions and 19 deletions
|
|
@ -114,7 +114,11 @@ export default class Vector {
|
||||||
};
|
};
|
||||||
|
|
||||||
cross(a) {
|
cross(a) {
|
||||||
return new Vector(
|
return this.copy()._cross(a);
|
||||||
|
};
|
||||||
|
|
||||||
|
_cross(a) {
|
||||||
|
return this.set(
|
||||||
this.y * a.z - this.z * a.y,
|
this.y * a.z - this.z * a.y,
|
||||||
this.z * a.x - this.x * a.z,
|
this.z * a.x - this.x * a.z,
|
||||||
this.x * a.y - this.y * a.x
|
this.x * a.y - this.y * a.x
|
||||||
|
|
@ -129,6 +133,10 @@ export default class Vector {
|
||||||
return this._multiply(-1);
|
return this._multiply(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_perpXY() {
|
||||||
|
return this.set(-this.y, this.x, this.z);
|
||||||
|
}
|
||||||
|
|
||||||
toArray() {
|
toArray() {
|
||||||
return [this.x, this.y, this.z];
|
return [this.x, this.y, this.z];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,19 @@ export default [
|
||||||
invoke: ({services}) => services.sketcher.sketchFace(services.selection.face.single)
|
invoke: ({services}) => services.sketcher.sketchFace(services.selection.face.single)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
id: 'ReassignSketch',
|
||||||
|
appearance: {
|
||||||
|
cssIcons: ['share'],
|
||||||
|
label: 'reassign sketch',
|
||||||
|
icon96: 'img/cad/face-edit96.png',
|
||||||
|
info: 'open sketcher for a face/plane',
|
||||||
|
},
|
||||||
|
listens: streams => streams.selection.face,
|
||||||
|
update: ActionHelpers.checkForSelectedFaces(1),
|
||||||
|
invoke: ctx => ctx.services.sketcher.reassignSketchMode.enter(ctx.services.selection.face.single.id)
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
id: 'Save',
|
id: 'Save',
|
||||||
appearance: {
|
appearance: {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export default [
|
||||||
id: 'craft',
|
id: 'craft',
|
||||||
cssIcons: ['magic'],
|
cssIcons: ['magic'],
|
||||||
info: 'set of available craft operations on a solid',
|
info: 'set of available craft operations on a solid',
|
||||||
actions: ['EXTRUDE', 'CUT', 'REVOLVE', 'SHELL', 'FILLET', 'DATUM_CREATE']
|
actions: ['EXTRUDE', 'CUT', 'REVOLVE', 'SHELL', 'FILLET', 'DATUM_CREATE', 'ReassignSketch']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'primitives',
|
id: 'primitives',
|
||||||
|
|
|
||||||
43
web/app/cad/sketch/reassignSketchMode.js
Normal file
43
web/app/cad/sketch/reassignSketchMode.js
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import React from 'react';
|
||||||
|
import mapContext from '../../../../modules/ui/mapContext';
|
||||||
|
import Button from '../../../../modules/ui/components/controls/Button';
|
||||||
|
|
||||||
|
export default function initReassignSketchMode(ctx) {
|
||||||
|
ctx.services.ui.registerComponent('ReassignSketchTool', ReassignSketchTool);
|
||||||
|
|
||||||
|
|
||||||
|
let detach = null;
|
||||||
|
|
||||||
|
function exit() {
|
||||||
|
ctx.streams.ui.sockets.headsUpHelper.next(null);
|
||||||
|
if (detach) {
|
||||||
|
detach();
|
||||||
|
detach = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function enter(fromId) {
|
||||||
|
ctx.streams.ui.sockets.headsUpHelper.next('ReassignSketchTool');
|
||||||
|
detach = ctx.streams.selection.face.attach(faces => {
|
||||||
|
let face = faces[0];
|
||||||
|
if (face && face !== fromId) {
|
||||||
|
exit();
|
||||||
|
ctx.services.sketcher.reassignSketch(fromId, face);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {enter, exit};
|
||||||
|
}
|
||||||
|
|
||||||
|
function ReassignSketchTool({from, cancel}) {
|
||||||
|
return <div style={{
|
||||||
|
margin: 10
|
||||||
|
}}>
|
||||||
|
Reassign sketch from {from}. Pick a target face. <Button onClick={cancel}>cancel</Button>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReassignSketchTool = mapContext(ctx => ({
|
||||||
|
from: ctx.services.selection.face.single.id,
|
||||||
|
cancel: ctx.services.sketcher.reassignSketchMode.exit
|
||||||
|
}))(ReassignSketchTool);
|
||||||
|
|
@ -124,7 +124,9 @@ export function FetchContours(geom) {
|
||||||
contours.push(contour);
|
contours.push(contour);
|
||||||
}
|
}
|
||||||
for (let contour of contours) {
|
for (let contour of contours) {
|
||||||
if (!contour.isCCW()) contour.reverse();
|
if (!contour.isCCW()) {
|
||||||
|
contour.reverse();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return contours;
|
return contours;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ import {ReadSketch} from './sketchReader';
|
||||||
import {getSketchBoundaries} from './sketchBoundaries';
|
import {getSketchBoundaries} from './sketchBoundaries';
|
||||||
import {state, stream} from 'lstream';
|
import {state, stream} from 'lstream';
|
||||||
import {InPlaceSketcher} from './inPlaceSketcher';
|
import {InPlaceSketcher} from './inPlaceSketcher';
|
||||||
import {CAMERA_MODE} from '../scene/viewer';
|
|
||||||
import sketcherUIContrib from './sketcherUIContrib';
|
import sketcherUIContrib from './sketcherUIContrib';
|
||||||
|
import initReassignSketchMode from './reassignSketchMode';
|
||||||
|
|
||||||
export function activate(ctx) {
|
export function activate(ctx) {
|
||||||
|
|
||||||
|
|
@ -23,10 +23,8 @@ export function activate(ctx) {
|
||||||
if (evt.key.indexOf(prefix) < 0) return;
|
if (evt.key.indexOf(prefix) < 0) return;
|
||||||
let sketchFaceId = evt.key.substring(prefix.length);
|
let sketchFaceId = evt.key.substring(prefix.length);
|
||||||
let sketchFace = services.cadRegistry.findFace(sketchFaceId);
|
let sketchFace = services.cadRegistry.findFace(sketchFaceId);
|
||||||
if (sketchFace !== null) {
|
updateSketchForFace(sketchFace);
|
||||||
updateSketchForFace(sketchFace);
|
services.viewer.requestRender();
|
||||||
services.viewer.requestRender();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.storage.addListener(onSketchUpdate);
|
services.storage.addListener(onSketchUpdate);
|
||||||
|
|
@ -38,21 +36,43 @@ export function activate(ctx) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function readSketch(sketchId) {
|
function getSketchData(sketchId) {
|
||||||
let sketchStorageKey = services.project.sketchStorageKey(sketchId);
|
let sketchStorageKey = services.project.sketchStorageKey(sketchId);
|
||||||
let savedSketch = services.storage.get(sketchStorageKey);
|
return services.storage.get(sketchStorageKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSketchData(sketchId, data) {
|
||||||
|
let sketchStorageKey = services.project.sketchStorageKey(sketchId);
|
||||||
|
return services.storage.set(sketchStorageKey, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSketchData(sketchId) {
|
||||||
|
let sketchStorageKey = services.project.sketchStorageKey(sketchId);
|
||||||
|
return services.storage.remove(sketchStorageKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readSketch(sketchId) {
|
||||||
|
let savedSketch = getSketchData(sketchId);
|
||||||
if (savedSketch === null) {
|
if (savedSketch === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ReadSketch(JSON.parse(savedSketch), sketchId, true);
|
try {
|
||||||
|
return ReadSketch(JSON.parse(savedSketch), sketchId, true);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasSketch(sketchId) {
|
||||||
|
let sketchStorageKey = services.project.sketchStorageKey(sketchId);
|
||||||
|
return !!services.storage.get(sketchStorageKey);
|
||||||
|
}
|
||||||
|
|
||||||
function updateSketchForFace(mFace) {
|
function updateSketchForFace(mFace) {
|
||||||
let sketch = readSketch(mFace.id);
|
let sketch = readSketch(mFace.id);
|
||||||
if (sketch !== null) {
|
mFace.setSketch(sketch);
|
||||||
mFace.setSketch(sketch);
|
streams.sketcher.update.next(mFace);
|
||||||
streams.sketcher.update.next(mFace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAllSketches() {
|
function updateAllSketches() {
|
||||||
|
|
@ -88,9 +108,22 @@ export function activate(ctx) {
|
||||||
services.appTabs.show(face.id, 'Sketch ' + face.id, 'sketcher.html#' + sketchURL);
|
services.appTabs.show(face.id, 'Sketch ' + face.id, 'sketcher.html#' + sketchURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reassignSketch(fromId, toId) {
|
||||||
|
let sketchData = getSketchData(fromId);
|
||||||
|
if (!sketchData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSketchData(toId, sketchData);
|
||||||
|
removeSketchData(fromId);
|
||||||
|
updateSketchForFace(services.cadRegistry.findFace(fromId));
|
||||||
|
updateSketchForFace(services.cadRegistry.findFace(toId));
|
||||||
|
services.viewer.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
streams.craft.models.attach(updateAllSketches);
|
streams.craft.models.attach(updateAllSketches);
|
||||||
|
|
||||||
services.sketcher = {
|
services.sketcher = {
|
||||||
sketchFace, sketchFace2D, updateAllSketches, getAllSketches, readSketch, inPlaceEditor
|
sketchFace, sketchFace2D, updateAllSketches, getAllSketches, readSketch, hasSketch, inPlaceEditor, reassignSketch,
|
||||||
|
reassignSketchMode: initReassignSketchMode(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,11 @@ export function activate({services}) {
|
||||||
function get(key) {
|
function get(key) {
|
||||||
return localStorage.getItem(key);
|
return localStorage.getItem(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function remove(key) {
|
||||||
|
return localStorage.removeItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
function getAllKeysFromNamespace(namespace) {
|
function getAllKeysFromNamespace(namespace) {
|
||||||
let keys = [];
|
let keys = [];
|
||||||
for(let i = localStorage.length - 1; i >= 0 ; i--) {
|
for(let i = localStorage.length - 1; i >= 0 ; i--) {
|
||||||
|
|
@ -25,6 +29,6 @@ export function activate({services}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
services.storage = {
|
services.storage = {
|
||||||
set, get, addListener, getAllKeysFromNamespace
|
set, get, remove, addListener, getAllKeysFromNamespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue