mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 16:33:15 +01:00
fix tests, working on the test infrastructure
This commit is contained in:
parent
41ca9a51e8
commit
0c586935c7
45 changed files with 206 additions and 101 deletions
|
|
@ -193,6 +193,10 @@ export function polynomial(coefs, vectors) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function fromXYZ({x, y, z}) {
|
||||||
|
return [x, y, z];
|
||||||
|
}
|
||||||
|
|
||||||
export const AXIS_X3 = [1,0,0];
|
export const AXIS_X3 = [1,0,0];
|
||||||
export const AXIS_Y3 = [0,1,0];
|
export const AXIS_Y3 = [0,1,0];
|
||||||
export const AXIS_Z3 = [0,0,1];
|
export const AXIS_Z3 = [0,0,1];
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from '../../../web/app/math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {perpendicularVector} from '../../../web/app/math/math';
|
import {perpendicularVector} from '../../../web/app/math/math';
|
||||||
import {Face3, Geometry, Vector3} from 'three';
|
import {Face3, Geometry, Vector3} from 'three';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {Face3, FaceColors, Geometry, Mesh, MeshBasicMaterial, MeshPhongMaterial} from 'three';
|
import {Face3, FaceColors, Geometry, Mesh, MeshBasicMaterial, MeshPhongMaterial} from 'three';
|
||||||
import {advancePseudoFrenetFrame, frenetFrame, pseudoFrenetFrame} from '../../../web/app/brep/geom/curves/frenetFrame';
|
import {advancePseudoFrenetFrame, frenetFrame, pseudoFrenetFrame} from '../../../web/app/brep/geom/curves/frenetFrame';
|
||||||
import * as vec from '../../../web/app/math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {viewScaleFactor} from '../scaleHelper';
|
import {viewScaleFactor} from '../scaleHelper';
|
||||||
import {arrToThree} from 'math/vectorAdapters';
|
import {arrToThree} from 'math/vectorAdapters';
|
||||||
import {ORIGIN} from '../../../web/app/math/l3space';
|
import {ORIGIN} from '../../../web/app/math/l3space';
|
||||||
|
|
|
||||||
|
|
@ -173,8 +173,11 @@ export default class SceneSetUp {
|
||||||
return raycaster;
|
return raycaster;
|
||||||
}
|
}
|
||||||
|
|
||||||
raycast(event, objects) {
|
raycast(event, objects, logInfoOut = null) {
|
||||||
let raycaster = this.createRaycaster(event.offsetX, event.offsetY);
|
const raycaster = this.createRaycaster(event.offsetX, event.offsetY);
|
||||||
|
if (logInfoOut !== null) {
|
||||||
|
logInfoOut.ray = raycaster.ray
|
||||||
|
}
|
||||||
return raycaster.intersectObjects( objects, true );
|
return raycaster.intersectObjects( objects, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,6 @@ import React from 'react';
|
||||||
import ls from './Field.less'
|
import ls from './Field.less'
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
export default function Field({active, ...props}) {
|
export default function Field({active, name, ...props}) {
|
||||||
return <div className={cx(ls.root, active&&ls.active)} {...props} />
|
return <div className={cx(ls.root, active&&ls.active)} data-field-name={name} {...props} />
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from "../../web/app/math/vec";
|
import * as vec from "math/vec";
|
||||||
|
|
||||||
export class Node {
|
export class Node {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ export default ctx => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function select(from, to) {
|
function select(from, to) {
|
||||||
ctx.services.pickControl.pickFromRay(from, to, ALL_EXCLUDING_SOLID_KINDS);
|
ctx.services.pickControl.simulatePickFromRay(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectFirst(type) {
|
function selectFirst(type) {
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,9 @@
|
||||||
import * as sketcher_utils from '../utils/sketcherUtils'
|
import * as sketcher_utils from '../utils/sketcherUtils'
|
||||||
import {decapitalize} from '../../../modules/gems/capitalize';
|
|
||||||
import {genSerpinskiImpl} from '../../../web/app/utils/genSerpinski';
|
import {genSerpinskiImpl} from '../../../web/app/utils/genSerpinski';
|
||||||
import {distance} from '../../../web/app/math/math';
|
import {distance} from '../../../web/app/math/math';
|
||||||
|
|
||||||
export function createSubjectFromInPlaceSketcher(ctx) {
|
export function createSubjectFromInPlaceSketcher(ctx) {
|
||||||
let actions = {};
|
return createSketcherTPI(ctx.services.sketcher.inPlaceEditor.sketcherAppContext);
|
||||||
for (const actionId of Object.keys(ctx.streams.action.state)) {
|
|
||||||
if (actionId.startsWith('sketch')) {
|
|
||||||
let oldId = decapitalize(actionId.substring(6));
|
|
||||||
actions[oldId] = {
|
|
||||||
action: () => ctx.services.action.run(actionId)
|
|
||||||
};
|
|
||||||
actions.addBezierCurve = actions.addCubicBezierSpline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldStyleSketcherApp = {
|
|
||||||
viewer: ctx.services.sketcher.inPlaceEditor.viewer,
|
|
||||||
actions
|
|
||||||
};
|
|
||||||
|
|
||||||
return createSketcherTPI(oldStyleSketcherApp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSketcherTPI(context) {
|
export function createSketcherTPI(context) {
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ export function addArc(ctx, cX, cY, aX, aY, bX, bY) {
|
||||||
[bX, bY] = modelToScreen(ctx.viewer, bX, bY);
|
[bX, bY] = modelToScreen(ctx.viewer, bX, bY);
|
||||||
[cX, cY] = modelToScreen(ctx.viewer, cX, cY);
|
[cX, cY] = modelToScreen(ctx.viewer, cX, cY);
|
||||||
|
|
||||||
ctx.actions['addArc'].action();
|
ctx.actions.ArcTool.invoke(ctx);
|
||||||
|
|
||||||
moveAndClickXY(ctx, cX, cY);
|
moveAndClickXY(ctx, cX, cY);
|
||||||
moveAndClickXY(ctx, aX, aY);
|
moveAndClickXY(ctx, aX, aY);
|
||||||
|
|
@ -166,12 +166,12 @@ export class TestSegment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function modelToScreen(x, y) {
|
export function modelToScreen(viewer, x, y) {
|
||||||
if (this.screenToModelMatrix) {
|
if (viewer.screenToModelMatrix) {
|
||||||
let modelToScreenMx = this.screenToModelMatrix.invert();
|
let modelToScreenMx = viewer.screenToModelMatrix.invert();
|
||||||
[x, y] = modelToScreenMx.apply3([x, y, 0]);
|
[x, y] = modelToScreenMx.apply3([x, y, 0]);
|
||||||
}
|
}
|
||||||
x /= this.retinaPxielRatio;
|
x /= viewer.retinaPxielRatio;
|
||||||
y = (this.canvas.height - y) / this.retinaPxielRatio;
|
y = (viewer.canvas.height - y) / viewer.retinaPxielRatio;
|
||||||
return [x, y];
|
return [x, y];
|
||||||
}
|
}
|
||||||
|
|
@ -16,13 +16,37 @@ import {defineCypressTests} from "../../../coreTests/defineCypress";
|
||||||
describe("Wizrds", () => {
|
describe("Wizrds", () => {
|
||||||
|
|
||||||
|
|
||||||
afterEach(() => {
|
beforeEach(() => {
|
||||||
cy.screenshot();
|
cy.openModeller();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("plane wizrd should open", () => {
|
// afterEach(() => {
|
||||||
createDatum();
|
// cy.screenshot();
|
||||||
|
// });
|
||||||
|
|
||||||
|
it("plane wizard should open", () => {
|
||||||
|
cy.getActionButton('PLANE').click();
|
||||||
|
cy.get('.wizard').should('have.attr', 'data-operation-id', 'PLANE');
|
||||||
|
cy.getActiveWizardField('depth').find('input').type('100');
|
||||||
|
cy.get('.wizard .dialog-ok').click();
|
||||||
|
cy.selectRaycasting([-119, 29, 167], [23, -15, 33])
|
||||||
|
});
|
||||||
|
|
||||||
|
it("extrube wizard should work", () => {
|
||||||
|
cy.getActionButton('PLANE').click();
|
||||||
|
cy.get('.wizard').should('have.attr', 'data-operation-id', 'PLANE');
|
||||||
|
cy.getActiveWizardField('depth').find('input').type('100');
|
||||||
|
cy.get('.wizard .dialog-ok').click();
|
||||||
|
cy.selectRaycasting([-119, 29, 167], [23, -15, 33]);
|
||||||
|
cy.openSketcher().then(sketcher => {
|
||||||
|
sketcher.addRectangle(0, 0, 80, 100);
|
||||||
|
cy.commitSketch();
|
||||||
|
});
|
||||||
|
cy.getActionButton('EXTRUDE').click();
|
||||||
|
cy.get('.wizard .dialog-ok').click();
|
||||||
|
cy.selectRaycasting([-18, 67, 219], [120, 25, 81]);
|
||||||
|
cy.get('.float-view-btn[data-view="selection"]').click();
|
||||||
|
cy.get('.selection-view [data-entity="face"] li').should('have.text', 'S:1/F:5');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,38 @@
|
||||||
// ***********************************************
|
import modellerUISubject from "../../coreTests/subjects/modellerTPI";
|
||||||
// This example commands.js shows you how to
|
|
||||||
// create various custom commands and overwrite
|
|
||||||
// existing commands.
|
Cypress.Commands.add("openModeller", () => {
|
||||||
//
|
return cy.visit("http://localhost:3000?test&LOG.PICK=true");;
|
||||||
// For more comprehensive examples of custom
|
});
|
||||||
// commands please read more here:
|
|
||||||
// https://on.cypress.io/custom-commands
|
|
||||||
// ***********************************************
|
Cypress.Commands.add("getActionButton", (actionId) => {
|
||||||
//
|
return cy.get(`[data-action-id='${actionId}']`);
|
||||||
//
|
});
|
||||||
// -- This is a parent command --
|
|
||||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
|
||||||
//
|
Cypress.Commands.add("getActiveWizardField", (fieldName) => {
|
||||||
//
|
|
||||||
// -- This is a child command --
|
return cy.get(`.wizard [data-field-name='${fieldName}']`);
|
||||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
|
||||||
//
|
});
|
||||||
//
|
|
||||||
// -- This is a dual command --
|
Cypress.Commands.add("selectRaycasting", (from, to) => {
|
||||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
return cy.window().then(win => {
|
||||||
//
|
win.__CAD_APP.services.pickControl.simulatePickFromRay(from, to);
|
||||||
//
|
win.__DEBUG__.AddSegment3(from, to);
|
||||||
// -- This will overwrite an existing command --
|
});
|
||||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add("openSketcher", () => {
|
||||||
|
return cy.getModellerTPI().then(tpi => tpi.openSketcher());
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add("commitSketch", () => {
|
||||||
|
return cy.getModellerTPI().then(tpi => tpi.commitSketch());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Cypress.Commands.add("getModellerTPI", () => {
|
||||||
|
return cy.window().then(win => modellerUISubject(win.__CAD_APP));
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
|
|
||||||
export function cubicBezierPoint(p0, p1, p2, p3, t) {
|
export function cubicBezierPoint(p0, p1, p2, p3, t) {
|
||||||
const mt = 1 - t;
|
const mt = 1 - t;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import InvertedCurve from './invertedCurve';
|
import InvertedCurve from './invertedCurve';
|
||||||
|
|
||||||
export default class BoundedCurve {
|
export default class BoundedCurve {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import newtonIterations, {newtonIterationsOnInterval} from './newtonIterations';
|
import newtonIterations, {newtonIterationsOnInterval} from './newtonIterations';
|
||||||
import {curveTessParams} from '../impl/curve/curve-tess';
|
import {curveTessParams} from '../impl/curve/curve-tess';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {cubicBezierDer1, cubicBezierDer2, cubicBezierPoint} from './bezierCubic';
|
import {cubicBezierDer1, cubicBezierDer2, cubicBezierPoint} from './bezierCubic';
|
||||||
import {closestToCurveParam} from './closestPoint';
|
import {closestToCurveParam} from './closestPoint';
|
||||||
import InvertedCurve from './invertedCurve';
|
import InvertedCurve from './invertedCurve';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {perpendicularVector} from '../../../math/math';
|
import {perpendicularVector} from '../../../math/math';
|
||||||
|
|
||||||
export function frenetFrame(D1, D2) {
|
export function frenetFrame(D1, D2) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import {TOLERANCE, veq3} from '../tolerance';
|
import {TOLERANCE, veq3} from '../tolerance';
|
||||||
import {surfaceClosestParam} from '../impl/nurbs-ext';
|
import {surfaceClosestParam} from '../impl/nurbs-ext';
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import CubicHermiteInterpolation from './cubicHermiteIntepolation';
|
import CubicHermiteInterpolation from './cubicHermiteIntepolation';
|
||||||
import InvertedCurve from './invertedCurve';
|
import InvertedCurve from './invertedCurve';
|
||||||
import {genericCurveSplit} from './boundedCurve';
|
import {genericCurveSplit} from './boundedCurve';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
|
|
||||||
export default class InvertedCurve {
|
export default class InvertedCurve {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from "../../../../math/vec";
|
import * as vec from "math/vec";
|
||||||
|
|
||||||
export default function curveTess(curve, min, max, tessTol, scale) {
|
export default function curveTess(curve, min, max, tessTol, scale) {
|
||||||
return curveTessParams(curve, min, max, tessTol, scale).map(u => curve.point(u));
|
return curveTessParams(curve, min, max, tessTol, scale).map(u => curve.point(u));
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from "../../../../math/vec";
|
import * as vec from "math/vec";
|
||||||
import {TOLERANCE, TOLERANCE_SQ} from '../../tolerance';
|
import {TOLERANCE, TOLERANCE_SQ} from '../../tolerance';
|
||||||
import * as math from '../../../../math/math'
|
import * as math from '../../../../math/math'
|
||||||
import {fmin_bfgs} from "../../../../math/optim";
|
import {fmin_bfgs} from "../../../../math/optim";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import * as vec from "../../../math/vec";
|
import * as vec from "math/vec";
|
||||||
import * as math from '../../../math/math'
|
import * as math from '../../../math/math'
|
||||||
import {eqEps, TOLERANCE, TOLERANCE_01, TOLERANCE_SQ} from '../tolerance';
|
import {eqEps, TOLERANCE, TOLERANCE_01, TOLERANCE_SQ} from '../tolerance';
|
||||||
import {fmin_bfgs} from "../../../math/optim";
|
import {fmin_bfgs} from "../../../math/optim";
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import {NUMERICAL_SOLVE_TOL, TOLERANCE, TOLERANCE_01, TOLERANCE_SQ} from '../tolerance';
|
import {NUMERICAL_SOLVE_TOL, TOLERANCE, TOLERANCE_01, TOLERANCE_SQ} from '../tolerance';
|
||||||
import {curveDomain, curvePoint, meshesIntersect, surfaceMaxDegree} from '../impl/nurbs-ext';
|
import {curveDomain, curvePoint, meshesIntersect, surfaceMaxDegree} from '../impl/nurbs-ext';
|
||||||
import {IntersectionCurve} from '../curves/intersectionCurve';
|
import {IntersectionCurve} from '../curves/intersectionCurve';
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
|
|
||||||
export function surfaceIntersect(surfaceA, surfaceB) {
|
export function surfaceIntersect(surfaceA, surfaceB) {
|
||||||
const tessA = verb.eval.Tess.rationalSurfaceAdaptive(surfaceA);
|
const tessA = verb.eval.Tess.rationalSurfaceAdaptive(surfaceA);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import BrepBuilder, {createBoundingSurfaceFrom2DPoints, createBoundingSurfaceFromBBox} from '../brep-builder';
|
import BrepBuilder, {createBoundingSurfaceFrom2DPoints, createBoundingSurfaceFromBBox} from '../brep-builder';
|
||||||
import VertexFactory from '../vertexFactory';
|
import VertexFactory from '../vertexFactory';
|
||||||
import NurbsSurface from '../geom/surfaces/nurbsSurface';
|
import NurbsSurface from '../geom/surfaces/nurbsSurface';
|
||||||
import * as vec from '../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {BrepSurface} from '../geom/surfaces/brepSurface';
|
import {BrepSurface} from '../geom/surfaces/brepSurface';
|
||||||
import {Plane} from '../geom/impl/plane';
|
import {Plane} from '../geom/impl/plane';
|
||||||
import Vector from '../../../../modules/math/vector';
|
import Vector from '../../../../modules/math/vector';
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ export function ActionButtonBehavior({children, actionId}) {
|
||||||
const actionService = ctx.services.action;
|
const actionService = ctx.services.action;
|
||||||
|
|
||||||
return children({
|
return children({
|
||||||
|
'data-action-id': actionId,
|
||||||
onClick: e => actionService.run(actionId, e),
|
onClick: e => actionService.run(actionId, e),
|
||||||
onMouseEnter: e => {
|
onMouseEnter: e => {
|
||||||
updateCoords(e);
|
updateCoords(e);
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ export default class Wizard extends React.Component {
|
||||||
onClose={this.cancel}
|
onClose={this.cancel}
|
||||||
onKeyDown={this.onKeyDown}
|
onKeyDown={this.onKeyDown}
|
||||||
setFocus={this.focusFirstInput}
|
setFocus={this.focusFirstInput}
|
||||||
|
className='Wizard'
|
||||||
|
data-operation-id={operation.id}
|
||||||
controlButtons={<>
|
controlButtons={<>
|
||||||
<WindowControlButton title='help' onClick={(e) => DocumentationTopic$.next({
|
<WindowControlButton title='help' onClick={(e) => DocumentationTopic$.next({
|
||||||
topic: operation.id,
|
topic: operation.id,
|
||||||
|
|
@ -74,8 +76,8 @@ export default class Wizard extends React.Component {
|
||||||
</FormContext.Provider>
|
</FormContext.Provider>
|
||||||
<Stack>
|
<Stack>
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button onClick={this.cancel}>Cancel</Button>
|
<Button className='dialog-cancel' onClick={this.cancel}>Cancel</Button>
|
||||||
<Button type='accent' onClick={this.onOK}>OK</Button>
|
<Button className='dialog-ok' type='accent' onClick={this.onOK}>OK</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
{this.state.hasError && <div className={ls.errorMessage}>
|
{this.state.hasError && <div className={ls.errorMessage}>
|
||||||
{this.state.algorithmError && <span>
|
{this.state.algorithmError && <span>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export default class EntityList extends React.Component {
|
||||||
if (!Array.isArray(value)) {
|
if (!Array.isArray(value)) {
|
||||||
value = value ? asArray(value) : EMPTY_ARRAY;
|
value = value ? asArray(value) : EMPTY_ARRAY;
|
||||||
}
|
}
|
||||||
return <Field active={active} onClick={setActive}>
|
return <Field active={active} name={name} onClick={setActive}>
|
||||||
<Label>{label||camelCaseSplitToStr(name)}:</Label>
|
<Label>{label||camelCaseSplitToStr(name)}:</Label>
|
||||||
<div>{value.length === 0 ?
|
<div>{value.length === 0 ?
|
||||||
<span className={ls.emptySelection}>{placeholder || '<not selected>'}</span> :
|
<span className={ls.emptySelection}>{placeholder || '<not selected>'}</span> :
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ export function Group({children}) {
|
||||||
|
|
||||||
export function formField(Control) {
|
export function formField(Control) {
|
||||||
return function FormPrimitive({label, name, active, setActive, ...props}) {
|
return function FormPrimitive({label, name, active, setActive, ...props}) {
|
||||||
return <Field active={active} onFocus={setActive} onClick={setActive}>
|
return <Field active={active} name={name} onFocus={setActive} onClick={setActive}>
|
||||||
<Label>{label || camelCaseSplitToStr(name)}</Label>
|
<Label>{label || camelCaseSplitToStr(name)}</Label>
|
||||||
<Control {...props} />
|
<Control {...props} />
|
||||||
</Field>;
|
</Field>;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import {brepFaceToGeom, surfaceToThreeGeom} from './scene/wrappers/brepSceneObje
|
||||||
import {createSolidMaterial} from './scene/wrappers/sceneObject';
|
import {createSolidMaterial} from './scene/wrappers/sceneObject';
|
||||||
import DPR from 'dpr';
|
import DPR from 'dpr';
|
||||||
import Vector from 'math/vector';
|
import Vector from 'math/vector';
|
||||||
import * as vec from '../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {readSketchFloat} from './sketch/sketchReader';
|
import {readSketchFloat} from './sketch/sketchReader';
|
||||||
import {toLoops} from '../brep/io/brepLoopsFormat';
|
import {toLoops} from '../brep/io/brepLoopsFormat';
|
||||||
|
|
|
||||||
|
|
@ -25,17 +25,25 @@ export default class FloatView extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
let {views, getDescriptor} = this.props;
|
let {views, getDescriptor} = this.props;
|
||||||
|
|
||||||
|
function renderedIcon(icon) {
|
||||||
|
if (typeof icon === 'string') {
|
||||||
|
return <Fa fw icon={icon}/>;
|
||||||
|
} else {
|
||||||
|
const I = icon;
|
||||||
|
return <I />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function view(id) {
|
function view(id) {
|
||||||
let {title, icon, Component} = getDescriptor(id);
|
let {title, icon, Component} = getDescriptor(id);
|
||||||
return <Folder className={ls.folder} title={<span> <Fa fw icon={icon}/> {title}</span>}>
|
|
||||||
|
|
||||||
|
return <Folder className={ls.folder} title={<span> {renderedIcon(icon)} {title}</span>}>
|
||||||
<div className={ls.folderContent}><Component/></div>
|
<div className={ls.folderContent}><Component/></div>
|
||||||
</Folder>;
|
</Folder>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function icon(id) {
|
|
||||||
let {Icon} = getDescriptor(id);
|
|
||||||
return <Icon />
|
|
||||||
}
|
|
||||||
|
|
||||||
let selected = this.state.selected;
|
let selected = this.state.selected;
|
||||||
|
|
||||||
|
|
@ -43,8 +51,10 @@ export default class FloatView extends React.Component {
|
||||||
<div className={ls.tabs}>
|
<div className={ls.tabs}>
|
||||||
{views.map(tabId => <ToolButton pressed={selected === tabId}
|
{views.map(tabId => <ToolButton pressed={selected === tabId}
|
||||||
key={tabId}
|
key={tabId}
|
||||||
|
className='float-view-btn'
|
||||||
|
data-view={tabId}
|
||||||
onClick={() => this.setState({selected: selected === tabId ? null : tabId})}>
|
onClick={() => this.setState({selected: selected === tabId ? null : tabId})}>
|
||||||
{<Fa fw icon={getDescriptor(tabId).icon}/>}
|
{renderedIcon(getDescriptor(tabId).icon)}
|
||||||
</ToolButton>)}
|
</ToolButton>)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
svg {
|
||||||
|
path {
|
||||||
|
stroke: white;
|
||||||
|
}
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
|
|
|
||||||
37
web/app/cad/dom/components/SelectionView.tsx
Normal file
37
web/app/cad/dom/components/SelectionView.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {useStream} from "ui/effects";
|
||||||
|
import {SELECTABLE_ENTITIES} from "../../scene/entityContextPlugin";
|
||||||
|
|
||||||
|
|
||||||
|
export function SelectionView() {
|
||||||
|
|
||||||
|
const selections = [];
|
||||||
|
SELECTABLE_ENTITIES.forEach(entity => {
|
||||||
|
selections.push(useStream(ctx => ctx.streams.selection[entity]));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
return <div className='selection-view'>
|
||||||
|
|
||||||
|
{SELECTABLE_ENTITIES.map((entity, i) => {
|
||||||
|
|
||||||
|
const selection = selections[i];
|
||||||
|
|
||||||
|
if (selection.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return <div>
|
||||||
|
<b>{entity}</b>
|
||||||
|
<ul data-entity={entity} key={entity} style={{marginLeft: 10}}>
|
||||||
|
|
||||||
|
{selection.map(id => <li>{id}</li>)}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
})}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@ import BrepCurve from '../../brep/geom/curves/brepCurve';
|
||||||
import {Plane} from '../../brep/geom/impl/plane';
|
import {Plane} from '../../brep/geom/impl/plane';
|
||||||
import pip from '../tess/pip';
|
import pip from '../tess/pip';
|
||||||
import {readShellEntityFromJson} from '../scene/wrappers/entityIO';
|
import {readShellEntityFromJson} from '../scene/wrappers/entityIO';
|
||||||
import * as vec from '../../math/vec'
|
import * as vec from 'math/vec'
|
||||||
import NurbsSurface from '../../brep/geom/surfaces/nurbsSurface';
|
import NurbsSurface from '../../brep/geom/surfaces/nurbsSurface';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ import ObjectExplorer from '../craft/ui/ObjectExplorer';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import OperationHistory from '../craft/ui/OperationHistory';
|
import OperationHistory from '../craft/ui/OperationHistory';
|
||||||
import Expressions from '../expressions/Expressions';
|
import Expressions from '../expressions/Expressions';
|
||||||
|
import {SelectionView} from "../dom/components/SelectionView";
|
||||||
|
import {GrSelect} from "react-icons/gr";
|
||||||
|
|
||||||
export const STANDARD_MODE_HEADS_UP_TOOLBAR = ['DATUM_CREATE', 'PLANE', 'EditFace', 'EXTRUDE', 'CUT', 'REVOLVE', 'LOFT',
|
export const STANDARD_MODE_HEADS_UP_TOOLBAR = ['DATUM_CREATE', 'PLANE', 'EditFace', 'EXTRUDE', 'CUT', 'REVOLVE', 'LOFT',
|
||||||
'-', 'FILLET', '-', 'INTERSECTION', 'SUBTRACT', 'UNION'];
|
'-', 'FILLET', '-', 'INTERSECTION', 'SUBTRACT', 'UNION'];
|
||||||
|
|
@ -32,4 +34,5 @@ export function activate({services, streams}) {
|
||||||
services.ui.registerFloatView('project', ObjectExplorer, 'Model', 'cubes');
|
services.ui.registerFloatView('project', ObjectExplorer, 'Model', 'cubes');
|
||||||
services.ui.registerFloatView('history', OperationHistory, 'Modifications', 'history');
|
services.ui.registerFloatView('history', OperationHistory, 'Modifications', 'history');
|
||||||
services.ui.registerFloatView('expressions', Expressions, 'Expressions', 'percent');
|
services.ui.registerFloatView('expressions', Expressions, 'Expressions', 'percent');
|
||||||
|
services.ui.registerFloatView('selection', SelectionView, 'Selection', GrSelect);
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {AXIS, Matrix3, ORIGIN} from '../math/l3space'
|
import {AXIS, Matrix3, ORIGIN} from '../math/l3space'
|
||||||
import * as vec from '../math/vec'
|
import * as vec from 'math/vec'
|
||||||
import Vector from 'math/vector';
|
import Vector from 'math/vector';
|
||||||
import BrepBuilder from '../brep/brep-builder'
|
import BrepBuilder from '../brep/brep-builder'
|
||||||
import * as BREPPrimitives from '../brep/brep-primitives'
|
import * as BREPPrimitives from '../brep/brep-primitives'
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import * as mask from 'gems/mask'
|
||||||
import {getAttribute, setAttribute} from 'scene/objectData';
|
import {getAttribute, setAttribute} from 'scene/objectData';
|
||||||
import {FACE, EDGE, SKETCH_OBJECT, DATUM, SHELL, DATUM_AXIS, LOOP} from '../entites';
|
import {FACE, EDGE, SKETCH_OBJECT, DATUM, SHELL, DATUM_AXIS, LOOP} from '../entites';
|
||||||
import {LOG_FLAGS} from '../../logFlags';
|
import {LOG_FLAGS} from '../../logFlags';
|
||||||
|
import * as vec from 'math/vec';
|
||||||
|
|
||||||
export const PICK_KIND = {
|
export const PICK_KIND = {
|
||||||
FACE: mask.type(1),
|
FACE: mask.type(1),
|
||||||
|
|
@ -21,6 +22,8 @@ const DEFAULT_SELECTION_MODE = Object.freeze({
|
||||||
datum: true
|
datum: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let RayCastDebugInfo;
|
||||||
|
|
||||||
export const ALL_EXCLUDING_SOLID_KINDS = PICK_KIND.FACE | PICK_KIND.SKETCH | PICK_KIND.EDGE | PICK_KIND.DATUM_AXIS | PICK_KIND.LOOP;
|
export const ALL_EXCLUDING_SOLID_KINDS = PICK_KIND.FACE | PICK_KIND.SKETCH | PICK_KIND.EDGE | PICK_KIND.DATUM_AXIS | PICK_KIND.LOOP;
|
||||||
|
|
||||||
export function activate(context) {
|
export function activate(context) {
|
||||||
|
|
@ -98,7 +101,7 @@ export function activate(context) {
|
||||||
const deselectAll = () => services.marker.clear();
|
const deselectAll = () => services.marker.clear();
|
||||||
|
|
||||||
function handlePick(event) {
|
function handlePick(event) {
|
||||||
let pickResults = services.viewer.raycast(event, services.cadScene.workGroup.children);
|
let pickResults = services.viewer.raycast(event, services.cadScene.workGroup.children, RayCastDebugInfo);
|
||||||
traversePickResults(event, pickResults, ALL_EXCLUDING_SOLID_KINDS, pickHandler);
|
traversePickResults(event, pickResults, ALL_EXCLUDING_SOLID_KINDS, pickHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,6 +110,10 @@ export function activate(context) {
|
||||||
return traversePickResults(event, pickResults, kind, pickHandler);
|
return traversePickResults(event, pickResults, kind, pickHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function simulatePickFromRay(from3, to3, event = null) {
|
||||||
|
return pickFromRay(from3, to3, ALL_EXCLUDING_SOLID_KINDS, event);
|
||||||
|
}
|
||||||
|
|
||||||
function pick(obj, event = null) {
|
function pick(obj, event = null) {
|
||||||
pickHandler(obj, event);
|
pickHandler(obj, event);
|
||||||
}
|
}
|
||||||
|
|
@ -136,8 +143,12 @@ export function activate(context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
services.pickControl = {
|
services.pickControl = {
|
||||||
setPickHandler, deselectAll, pick, pickFromRay
|
setPickHandler, deselectAll, pick, pickFromRay, simulatePickFromRay
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (LOG_FLAGS.PICK) {
|
||||||
|
RayCastDebugInfo = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traversePickResults(event, pickResults, kind, visitor) {
|
export function traversePickResults(event, pickResults, kind, visitor) {
|
||||||
|
|
@ -210,5 +221,12 @@ function printPickInfo(model, rayCastData) {
|
||||||
console.dir(rayCastData);
|
console.dir(rayCastData);
|
||||||
let pt = rayCastData.point;
|
let pt = rayCastData.point;
|
||||||
console.log('POINT: ' + pt.x + ', ' + pt.y + ',' + pt.z);
|
console.log('POINT: ' + pt.x + ', ' + pt.y + ',' + pt.z);
|
||||||
|
if (RayCastDebugInfo && RayCastDebugInfo.ray) {
|
||||||
|
//generating test data
|
||||||
|
const BUFFER = 100;
|
||||||
|
const r = vec.fromXYZ(pt).map(Math.round);
|
||||||
|
const dir = vec._mul(vec.fromXYZ(RayCastDebugInfo.ray.direction), BUFFER);
|
||||||
|
console.log('cy.selectRaycasting(['+ vec.sub(r, dir).map(Math.round).join(', ') + '], [' + vec.add(r, dir).map(Math.round).join(', ') + '])');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -32,8 +32,8 @@ export default class Viewer {
|
||||||
this.sceneSetup.lookAtObject(obj);
|
this.sceneSetup.lookAtObject(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
raycast(event, objects) {
|
raycast(event, objects, logInfoOut) {
|
||||||
return this.sceneSetup.raycast(event, objects);
|
return this.sceneSetup.raycast(event, objects, logInfoOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
customRaycast(from3, to3, objects) {
|
customRaycast(from3, to3, objects) {
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import {SceneEdge, SceneFace, SceneSolid} from './sceneObject';
|
||||||
import brepTess from '../../tess/brep-tess';
|
import brepTess from '../../tess/brep-tess';
|
||||||
import tessellateSurface from '../../../brep/geom/surfaces/surfaceTess';
|
import tessellateSurface from '../../../brep/geom/surfaces/surfaceTess';
|
||||||
import {setAttribute} from '../../../../../modules/scene/objectData';
|
import {setAttribute} from '../../../../../modules/scene/objectData';
|
||||||
import * as vec from '../../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {perpendicularVector} from '../../../math/math';
|
import {perpendicularVector} from '../../../math/math';
|
||||||
|
|
||||||
const SMOOTH_RENDERING = true;
|
const SMOOTH_RENDERING = true;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {areEqual, circleFromPoints, distanceAB, radiusOfCurvature, TOLERANCE} from '../../math/math';
|
import {areEqual, circleFromPoints, distanceAB, radiusOfCurvature, TOLERANCE} from '../../math/math';
|
||||||
import * as vec from '../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {iteratePath} from '../cad-utils';
|
import {iteratePath} from '../cad-utils';
|
||||||
import NurbsCurve from '../../brep/geom/curves/nurbsCurve';
|
import NurbsCurve from '../../brep/geom/curves/nurbsCurve';
|
||||||
import {veqXYZ} from '../../brep/geom/tolerance';
|
import {veqXYZ} from '../../brep/geom/tolerance';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Vector from 'math/vector';
|
import Vector from 'math/vector';
|
||||||
import BBox from './bbox'
|
import BBox from './bbox'
|
||||||
import * as vec from './vec';
|
import * as vec from 'math/vec';
|
||||||
import {perp2d} from "./vec";
|
import {perp2d} from "math/vec";
|
||||||
import {eqTol} from "../brep/geom/tolerance";
|
import {eqTol} from "../brep/geom/tolerance";
|
||||||
|
|
||||||
export const TOLERANCE = 1E-6;
|
export const TOLERANCE = 1E-6;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import {COS_FN, Polynomial, POW_1_FN, POW_2_FN, POW_3_FN, SIN_FN} from "./polyno
|
||||||
import {cubicBezierDer1, cubicBezierDer2, cubicBezierPoint} from "../../brep/geom/curves/bezierCubic";
|
import {cubicBezierDer1, cubicBezierDer2, cubicBezierPoint} from "../../brep/geom/curves/bezierCubic";
|
||||||
import {greaterThanConstraint, lessThanConstraint} from "./barriers";
|
import {greaterThanConstraint, lessThanConstraint} from "./barriers";
|
||||||
import {genericCurveStep} from "../../brep/geom/impl/nurbs-ext";
|
import {genericCurveStep} from "../../brep/geom/impl/nurbs-ext";
|
||||||
import {_normalize} from "../../math/vec";
|
import {_normalize} from "math/vec";
|
||||||
import {
|
import {
|
||||||
AngleBetweenConstraintIcon,
|
AngleBetweenConstraintIcon,
|
||||||
AngleConstraintIcon,
|
AngleConstraintIcon,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import QR from '../../math/qr'
|
||||||
import LMOptimizer from '../../math/lm'
|
import LMOptimizer from '../../math/lm'
|
||||||
import {ConstantWrapper, EqualsTo} from './solverConstraints'
|
import {ConstantWrapper, EqualsTo} from './solverConstraints'
|
||||||
import {dog_leg} from '../../math/optim'
|
import {dog_leg} from '../../math/optim'
|
||||||
import {newVector} from '../../math/vec';
|
import {newVector} from 'math/vec';
|
||||||
|
|
||||||
/** @constructor */
|
/** @constructor */
|
||||||
function Param(value, objectParam) {
|
function Param(value, objectParam) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import * as math from '../../math/math'
|
import * as math from '../../math/math'
|
||||||
import * as vec from '../../math/vec'
|
import * as vec from 'math/vec'
|
||||||
import {DEG_RAD, lineLineIntersection2d, makeAngle0_360, pointToLineSignedDistance} from '../../math/math'
|
import {DEG_RAD, lineLineIntersection2d, makeAngle0_360, pointToLineSignedDistance} from '../../math/math'
|
||||||
import Vector from 'math/vector';
|
import Vector from 'math/vector';
|
||||||
import {Styles} from "../styles";
|
import {Styles} from "../styles";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {SketchObject} from './sketch-object'
|
import {SketchObject} from './sketch-object'
|
||||||
import * as vec from '../../math/vec';
|
import * as vec from 'math/vec';
|
||||||
import {curveTessellate} from '../../brep/geom/impl/nurbs-ext';
|
import {curveTessellate} from '../../brep/geom/impl/nurbs-ext';
|
||||||
import {Ellipse} from "./ellipse";
|
import {Ellipse} from "./ellipse";
|
||||||
import {EndPoint} from "./point";
|
import {EndPoint} from "./point";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {_270, _90, makeAngle0_360, pointToLineSignedDistance} from "../../math/math";
|
import {_270, _90, makeAngle0_360, pointToLineSignedDistance} from "../../math/math";
|
||||||
import {_negate} from "../../math/vec";
|
import {_negate} from "math/vec";
|
||||||
|
|
||||||
export class TextHelper {
|
export class TextHelper {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {isInstanceOf} from "../actions/matchUtils";
|
||||||
import {Segment} from "../shapes/segment";
|
import {Segment} from "../shapes/segment";
|
||||||
import {DEFAULT_SEARCH_BUFFER} from "../viewer2d";
|
import {DEFAULT_SEARCH_BUFFER} from "../viewer2d";
|
||||||
import {distance} from "../../math/math";
|
import {distance} from "../../math/math";
|
||||||
import {_negate, cross2d} from "../../math/vec";
|
import {_negate, cross2d} from "math/vec";
|
||||||
|
|
||||||
export class AddDimTool extends Tool {
|
export class AddDimTool extends Tool {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue