setup debugger UI

This commit is contained in:
xibyte 2017-12-16 23:38:42 -08:00 committed by Val Erastov
parent d7d7e2e597
commit 1597c5f4b3
17 changed files with 295 additions and 18 deletions

View file

@ -3,7 +3,8 @@
"version": "0.1.0",
"description": "JS.Sketcher is a parametric 2D and 3D CAD modeler written in pure javascript",
"scripts": {
"start": "node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.config.dev.js --content-base web/ --port 3000",
"start": "node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.config.js --content-base web/ --port 3000",
"start-test": "node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config webpack.config.dev.js --content-base web/ --port 3000",
"pack": "node ./node_modules/webpack/bin/webpack.js --config webpack.config.js --progress --profile --colors",
"build": "grunt",
"lint": "eslint web/app"
@ -31,6 +32,7 @@
"babel-preset-stage-2": "6.24.1",
"babel-polyfill": "6.26.0",
"babel-preset-react": "6.24.1",
"babel-plugin-local-styles-transformer": "git://github.com/xibyte/babel-plugin-local-styles-transformer.git#0.0.1",
"css-loader": "0.28.7",
"less-loader": "4.0.5",
@ -58,6 +60,7 @@
"less": "2.7.3",
"libtess": "1.2.2",
"numeric": "1.2.6",
"sprintf": "0.1.5"
"sprintf": "0.1.5",
"classnames": "2.2.5"
}
}

View file

@ -4,6 +4,11 @@ import {createSolidMaterial} from './scene/scene-object'
import DPR from '../utils/dpr'
import Vector from "../math/vector";
import {NurbsCurve} from "../brep/geom/impl/nurbs";
import * as ui from '../ui/ui';
import React from 'react';
import ReactDOM from 'react-dom';
import BrepDebugger from './../brep/debug/debugger/brepDebugger';
export const DEBUG = true;
@ -207,7 +212,7 @@ const DebugMenuConfig = {
label: 'debug',
cssIcons: ['bug'],
info: 'set of debug actions',
actions: [ 'DebugPrintAllSolids', 'DebugPrintFace', 'DebugFaceId', 'DebugFaceSketch']
actions: [ 'DebugPrintAllSolids', 'DebugPrintFace', 'DebugFaceId', 'DebugFaceSketch', 'DebugOpenBrepDebugger']
}
};
@ -274,5 +279,27 @@ const DebugActions = {
};
console.log(JSON.stringify(squashed));
}
},
'DebugOpenBrepDebugger': {
cssIcons: ['cubes'],
label: 'open BREP debugger',
info: 'open the BREP debugger in a window',
invoke: (app) => {
let debuggerWinDom = document.getElementById('brep-debugger');
if (!debuggerWinDom) {
//Temporary hack until win infrastructure is done for 3d
debuggerWinDom = document.createElement('div');
debuggerWinDom.setAttribute('id', 'brep-debugger');
debuggerWinDom.innerHTML = '<div class="tool-caption" ><i class="fa fa-fw fa-bug"></i>Brep Debugger</div><div class="content"></div>';
document.body.appendChild(debuggerWinDom);
debuggerWinDom.debuggerWin = new ui.Window($(debuggerWinDom), new ui.WinManager());
ReactDOM.render(
<BrepDebugger />,
debuggerWinDom.getElementsByClassName('content')[0]
);
}
debuggerWinDom.debuggerWin.show();
}
}
};

View file

@ -1,5 +1,4 @@
export const keymap = {
'CUT': 'C',
'EXTRUDE': 'E',
'ZoomIn': '+',
@ -8,5 +7,6 @@ export const keymap = {
'menu.primitives': 'shift+A',
'menu.main': 'space',
'Save': 'ctrl+S',
'Info': 'F1'
'Info': 'F1',
'DebugOpenBrepDebugger': 'ctrl+B'
};

View file

@ -0,0 +1,34 @@
class BRepDebug {
constructor() {
this.booleanSessions = [];
}
startBooleanSession(a, b, type) {
this.currentBooleanSession = new BooleanSession(a, b, type)
this.booleanSessions.push(this.currentBooleanSession);
}
}
class BooleanSession {
constructor(a, b, type) {
this.inputOperandA = a;
this.inputOperandB = b;
}
setWorkingOperands(a, b) {
this.workingOperandA = a;
this.workingOperandB = b;
}
setResult(result) {
this.result = result;
}
}
export default (new BRepDebug());

View file

@ -0,0 +1,60 @@
import React from 'react';
import './brepDebugger.less';
import BREP_DEBUG from '../brep-debug';
import ShellExplorer from './shellExplorer';
import Section from './section'
export default class BrepDebugger extends React.PureComponent {
render() {
let {booleanSessions} = BREP_DEBUG;
return <div className='brep-debugger'>
<div className='section'>
<i className='fa fa-fw fa-eye-slash button' onClick={() => __DEBUG__.HideSolids()} />
</div>
<div className='section boolean-sessions'>
{booleanSessions.map(session =>
<Section name={`boolean session ${session.id}`} closable accent captionStyles={['centered']}>
<div className='section'>
<Section name='input operands' accent>
<div className='operands-veiew'>
<div>
<div className='caption operand-a'>Operand A</div>
<ShellExplorer shell={session.inputOperandA}/>
</div>
<div>
<div className='caption operand-b'>Operand B</div>
<ShellExplorer shell={session.inputOperandB}/>
</div>
</div>
</Section>
</div>
<Section name='working operands' accent>
<div className='operands-veiew'>
<div>
<div className='caption operand-a'>Operand A</div>
<ShellExplorer shell={session.workingOperandA}/>
</div>
<div>
<div className='caption operand-b'>Operand B</div>
<ShellExplorer shell={session.workingOperandB}/>
</div>
<div>
<div className='caption result'>Result</div>
<ShellExplorer shell={session.result}/>
</div>
</div>
</Section>
</Section>)}
</div>
</div>;
}
}

View file

@ -0,0 +1,53 @@
.brep-debugger {
padding: 0.3em;
line-height: 1.5;
button {
font-size: inherit;
padding: 0 0.3em;
}
& .operands-veiew {
display: flex;
justify-content: space-between;
& > * {
flex: 1 1;
}
}
& .section {
& .caption {
&.closable {
cursor: pointer;
&:hover {
color: blue;
}
}
&.accent {
background-color: rgb(255, 244, 244);
font-weight: bold;
}
&.centered {
text-align: center;
}
&.operand-a {
background-color: rgb(239, 244, 255)
}
&.operand-b {
background-color: rgb(244, 255, 245)
}
&.result {
background-color: rgb(254, 255, 244)
}
}
}
.button {
cursor: pointer;
font-size: 1.3em;
&:hover {
color: blue;
}
}
}

View file

@ -0,0 +1,31 @@
import React from 'react';
import cx from 'classnames';
export default class Section extends React.PureComponent {
constructor() {
super();
this.state = {
closed: false
}
}
render() {
let {name, tabs, closable, defaultClosed, accent, children, captionStyles} = this.props;
let closed = closable && (this.state.closed || defaultClosed);
return <div className={cx('section', {closable, closed})} style={{paddingLeft: tabs}}>
<div className={cx('caption', {accent}, captionStyles)} >
{closable && <i className={'fa fa-fw fa-caret-' + (closed ? 'right': 'down')} />} {name}</div>
{children}
</div>;
}
}
function mapIterator(it, fn) {
for (let i of it) {
fn(i);
}
}

View file

@ -0,0 +1,26 @@
import React from 'react';
export default class ShellExplorer extends React.PureComponent {
render() {
let {shell} = this.props;
return <div className='shell-explorer'>
<div className='caption'>faces</div>
{shell.faces.map(face => <div>
<div className='caption'>face {face.refId}</div>
{mapIterator(face.edges, e => <div>
edge: {e.refId}
</div>)}
</div>)
}
</div>;
}
}
function mapIterator(it, fn) {
for (let i of it) {
fn(i);
}
}

View file

@ -11,15 +11,17 @@ import {Ray} from "../utils/ray";
import pickPointInside2dPolygon from "../utils/pickPointInPolygon";
import CadError from "../../utils/errors";
import {createBoundingNurbs} from "../brep-builder";
import BREP_DEBUG from '../debug/brep-debug';
const A = 0, B = 1;
const DEBUG = {
OPERANDS_MODE: false,
LOOP_DETECTION: true,
FACE_FACE_INTERSECTION: true,
LOOP_DETECTION: false,
FACE_FACE_INTERSECTION: false,
RAY_CAST: false,
FACE_MERGE: true,
FACE_MERGE: false,
NOOP: () => {}
};
@ -78,9 +80,13 @@ function checkShellForErrors(shell, code) {
export function BooleanAlgorithm( shellA, shellB, type ) {
BREP_DEBUG.startBooleanSession(shellA, shellB, type);
shellA = prepareWorkingCopy(shellA);
shellB = prepareWorkingCopy(shellB);
BREP_DEBUG.currentBooleanSession.setWorkingOperands(shellA, shellB);
let facesData = [];
mergeVertices(shellA, shellB);
@ -137,6 +143,7 @@ export function BooleanAlgorithm( shellA, shellB, type ) {
// __DEBUG__.ClearVolumes();
// __DEBUG__.Clear();
BREP_DEBUG.currentBooleanSession.setResult(result);
return result;
}
@ -585,8 +592,8 @@ function filterFacesByNewEdges(faces) {
const validFaces = new Set(faces);
const result = new Set();
for (let face of faces) {
__DEBUG__.Clear();
__DEBUG__.AddFace(face);
// __DEBUG__.Clear();
// __DEBUG__.AddFace(face);
traverseFaces(face, validFaces, (it) => {
if (result.has(it) || isFaceContainNewEdge(it)) {
result.add(face);
@ -866,7 +873,7 @@ function collectNodesOfIntersectionOfFace(curve, face, nodes, operand) {
}
function collectNodesOfIntersection(curve, loop, nodes, operand) {
__DEBUG__.AddCurve(curve, 0xffffff);
// __DEBUG__.AddCurve(curve, 0xffffff);
let skippedEnclosures = new Set();
for (let edge of loop.halfEdges) {

View file

@ -19,6 +19,11 @@ function Window(el, winManager) {
winManager.registerDrag(this.root, caption);
}
Window.prototype.show = function() {
this.root.show();
}
Window.prototype.toggle = function() {
var aboutToShow = !this.root.is(':visible');
if (aboutToShow) {

View file

@ -1,3 +1,5 @@
@import 'brep-debugger.less';
@tab-switcher-inner-height: 20px;
@tab-switcher-top-border: 1px;
@tab-switcher-height: @tab-switcher-inner-height + @tab-switcher-top-border;

View file

@ -0,0 +1,18 @@
#brep-debugger {
position: absolute;
min-width: 100px;
min-height: 100px;
height: 50%;
width: 300px;
left:100px;
top:300px;
background: #eee;
border: 5px solid rgb(49, 121, 255);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
& .tool-caption {
padding: 0.3em;
background-color: rgb(238, 255, 246);
cursor: default;
user-select: none
}
}

View file

@ -1,6 +1,8 @@
const path = require('path');
const webpack = require('webpack');
const WEB_APP = path.join(__dirname, 'web/app');
module.exports = {
devtool: 'source-map',
entry: {
@ -25,21 +27,26 @@ module.exports = {
module: {
rules: [{
test: /\.(js|jsx)$/,
use: ['babel-loader'],
include: [path.join(__dirname, 'web/app'), path.join(__dirname, 'web/test')]
loader: 'babel-loader',
include: [WEB_APP, path.join(__dirname, 'web/test')],
options: {
plugins: [
['local-styles-transformer', {include: WEB_APP}]
]
}
}, {
test: /\.css$/,
use: [
"style-loader",
"css-loader",
'style-loader',
'css-loader',
]
},
{
test: /\.less$/,
use: [
"style-loader",
"css-loader?-url",
"less-loader"
'style-loader',
'css-loader?-url',
'less-loader'
]
},
{
@ -50,5 +57,9 @@ module.exports = {
test: /\.json$/,
use: 'json-loader'
}]
},
devServer: {
hot: false,
inline: false,
}
};