brep-io-kernel 1.0.20 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist-kernel/brep-kernel.js +10858 -9938
- package/package.json +3 -2
- package/src/BREP/Edge.js +2 -0
- package/src/BREP/Face.js +2 -0
- package/src/BREP/SolidMethods/visualize.js +372 -365
- package/src/BREP/Vertex.js +2 -17
- package/src/PartHistory.js +4 -25
- package/src/SketchSolver2D.js +3 -0
- package/src/UI/AccordionWidget.js +1 -1
- package/src/UI/EnvMonacoEditor.js +0 -3
- package/src/UI/HistoryWidget.js +12 -4
- package/src/UI/SceneListing.js +45 -7
- package/src/UI/SelectionFilter.js +903 -438
- package/src/UI/SelectionState.js +464 -0
- package/src/UI/assembly/AssemblyConstraintCollectionWidget.js +41 -1
- package/src/UI/assembly/AssemblyConstraintsWidget.js +21 -3
- package/src/UI/assembly/constraintSelectionUtils.js +3 -182
- package/src/UI/{assembly/constraintFaceUtils.js → faceUtils.js} +30 -5
- package/src/UI/featureDialogs.js +154 -69
- package/src/UI/history/HistoryCollectionWidget.js +65 -0
- package/src/UI/pmi/AnnotationCollectionWidget.js +1 -0
- package/src/UI/pmi/BaseAnnotation.js +37 -0
- package/src/UI/pmi/LabelOverlay.js +32 -0
- package/src/UI/pmi/PMIMode.js +27 -0
- package/src/UI/pmi/dimensions/AngleDimensionAnnotation.js +5 -0
- package/src/UI/pmi/dimensions/ExplodeBodyAnnotation.js +5 -0
- package/src/UI/pmi/dimensions/HoleCalloutAnnotation.js +57 -0
- package/src/UI/pmi/dimensions/LeaderAnnotation.js +5 -0
- package/src/UI/pmi/dimensions/LinearDimensionAnnotation.js +22 -16
- package/src/UI/pmi/dimensions/NoteAnnotation.js +9 -0
- package/src/UI/pmi/dimensions/RadialDimensionAnnotation.js +81 -16
- package/src/UI/toolbarButtons/orientToFaceButton.js +3 -36
- package/src/UI/toolbarButtons/registerDefaultButtons.js +2 -0
- package/src/UI/toolbarButtons/selectionStateButton.js +206 -0
- package/src/UI/viewer.js +34 -13
- package/src/assemblyConstraints/AssemblyConstraintHistory.js +18 -42
- package/src/assemblyConstraints/constraints/AngleConstraint.js +1 -0
- package/src/assemblyConstraints/constraints/DistanceConstraint.js +1 -0
- package/src/features/selectionUtils.js +21 -5
- package/src/features/sketch/SketchFeature.js +2 -2
- package/src/features/sketch/sketchSolver2D/constraintDefinitions.js +3 -2
- package/src/utils/selectionResolver.js +258 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { FloatingWindow } from '../FloatingWindow.js';
|
|
2
|
+
import { SelectionFilter } from '../SelectionFilter.js';
|
|
3
|
+
|
|
4
|
+
const PANEL_KEY = '__selectionStatePanel';
|
|
5
|
+
|
|
6
|
+
function _ensureStyles() {
|
|
7
|
+
if (document.getElementById('selection-state-styles')) return;
|
|
8
|
+
const style = document.createElement('style');
|
|
9
|
+
style.id = 'selection-state-styles';
|
|
10
|
+
style.textContent = `
|
|
11
|
+
.selection-state-content {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
gap: 8px;
|
|
15
|
+
padding: 10px;
|
|
16
|
+
height: 100%;
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
color: #e5e7eb;
|
|
19
|
+
font-size: 12px;
|
|
20
|
+
}
|
|
21
|
+
.selection-state-header {
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
justify-content: space-between;
|
|
25
|
+
gap: 8px;
|
|
26
|
+
font-weight: 700;
|
|
27
|
+
}
|
|
28
|
+
.selection-state-count {
|
|
29
|
+
color: #cbd5f5;
|
|
30
|
+
font-size: 12px;
|
|
31
|
+
}
|
|
32
|
+
.selection-state-list {
|
|
33
|
+
flex: 1 1 auto;
|
|
34
|
+
min-height: 0;
|
|
35
|
+
overflow: auto;
|
|
36
|
+
background: rgba(8,10,14,.55);
|
|
37
|
+
border: 1px solid #1f2937;
|
|
38
|
+
border-radius: 8px;
|
|
39
|
+
padding: 8px;
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
gap: 6px;
|
|
43
|
+
}
|
|
44
|
+
.selection-state-item {
|
|
45
|
+
display: grid;
|
|
46
|
+
grid-template-columns: auto 1fr;
|
|
47
|
+
gap: 6px 10px;
|
|
48
|
+
align-items: center;
|
|
49
|
+
padding: 4px 6px;
|
|
50
|
+
border-radius: 6px;
|
|
51
|
+
background: rgba(255,255,255,.02);
|
|
52
|
+
border: 1px solid rgba(148,163,184,.18);
|
|
53
|
+
}
|
|
54
|
+
.selection-state-type {
|
|
55
|
+
font-size: 10px;
|
|
56
|
+
font-weight: 700;
|
|
57
|
+
letter-spacing: 0.04em;
|
|
58
|
+
text-transform: uppercase;
|
|
59
|
+
color: #9aa0aa;
|
|
60
|
+
}
|
|
61
|
+
.selection-state-name {
|
|
62
|
+
font-size: 12px;
|
|
63
|
+
color: #e5e7eb;
|
|
64
|
+
word-break: break-word;
|
|
65
|
+
}
|
|
66
|
+
.selection-state-empty {
|
|
67
|
+
color: #9aa0aa;
|
|
68
|
+
font-style: italic;
|
|
69
|
+
padding: 6px;
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
document.head.appendChild(style);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function _labelFor(obj) {
|
|
76
|
+
if (!obj) return 'Unknown';
|
|
77
|
+
const name = obj.name
|
|
78
|
+
|| obj.userData?.faceName
|
|
79
|
+
|| obj.userData?.edgeName
|
|
80
|
+
|| obj.userData?.vertexName
|
|
81
|
+
|| obj.userData?.solidName
|
|
82
|
+
|| obj.userData?.name
|
|
83
|
+
|| null;
|
|
84
|
+
return name || '(unnamed)';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
class SelectionStatePanel {
|
|
88
|
+
constructor(viewer) {
|
|
89
|
+
this.viewer = viewer || null;
|
|
90
|
+
this.window = null;
|
|
91
|
+
this.root = null;
|
|
92
|
+
this.content = null;
|
|
93
|
+
this.countEl = null;
|
|
94
|
+
this.listEl = null;
|
|
95
|
+
this._boundSelectionChanged = this._handleSelectionChanged.bind(this);
|
|
96
|
+
try { window.addEventListener('selection-changed', this._boundSelectionChanged); } catch { }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
toggle() {
|
|
100
|
+
if (this.root && this.root.style.display !== 'none') this.close();
|
|
101
|
+
else this.open();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
open() {
|
|
105
|
+
this._ensureWindow();
|
|
106
|
+
if (!this.root) return;
|
|
107
|
+
this.root.style.display = 'flex';
|
|
108
|
+
this._render();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
close() {
|
|
112
|
+
if (this.root) {
|
|
113
|
+
try { this.root.style.display = 'none'; } catch { }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
_ensureWindow() {
|
|
118
|
+
if (this.window && this.root) return;
|
|
119
|
+
_ensureStyles();
|
|
120
|
+
const fw = new FloatingWindow({
|
|
121
|
+
title: 'Selection State',
|
|
122
|
+
width: 360,
|
|
123
|
+
height: 320,
|
|
124
|
+
right: 14,
|
|
125
|
+
top: 120,
|
|
126
|
+
shaded: false,
|
|
127
|
+
onClose: () => this.close(),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const content = document.createElement('div');
|
|
131
|
+
content.className = 'selection-state-content';
|
|
132
|
+
|
|
133
|
+
const header = document.createElement('div');
|
|
134
|
+
header.className = 'selection-state-header';
|
|
135
|
+
const title = document.createElement('div');
|
|
136
|
+
title.textContent = 'Currently selected';
|
|
137
|
+
const count = document.createElement('div');
|
|
138
|
+
count.className = 'selection-state-count';
|
|
139
|
+
header.appendChild(title);
|
|
140
|
+
header.appendChild(count);
|
|
141
|
+
|
|
142
|
+
const list = document.createElement('div');
|
|
143
|
+
list.className = 'selection-state-list';
|
|
144
|
+
|
|
145
|
+
content.appendChild(header);
|
|
146
|
+
content.appendChild(list);
|
|
147
|
+
fw.content.appendChild(content);
|
|
148
|
+
|
|
149
|
+
this.window = fw;
|
|
150
|
+
this.root = fw.root;
|
|
151
|
+
this.content = content;
|
|
152
|
+
this.countEl = count;
|
|
153
|
+
this.listEl = list;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
_handleSelectionChanged() {
|
|
157
|
+
if (!this.root || this.root.style.display === 'none') return;
|
|
158
|
+
this._render();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
_render() {
|
|
162
|
+
const list = this.listEl;
|
|
163
|
+
const countEl = this.countEl;
|
|
164
|
+
if (!list || !countEl) return;
|
|
165
|
+
|
|
166
|
+
const scene = this.viewer?.partHistory?.scene || this.viewer?.scene || null;
|
|
167
|
+
const selection = SelectionFilter.getSelectedObjects({ scene }) || [];
|
|
168
|
+
countEl.textContent = `${selection.length} selected`;
|
|
169
|
+
|
|
170
|
+
list.textContent = '';
|
|
171
|
+
if (!selection.length) {
|
|
172
|
+
const empty = document.createElement('div');
|
|
173
|
+
empty.className = 'selection-state-empty';
|
|
174
|
+
empty.textContent = 'No items selected.';
|
|
175
|
+
list.appendChild(empty);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
for (const obj of selection) {
|
|
180
|
+
const row = document.createElement('div');
|
|
181
|
+
row.className = 'selection-state-item';
|
|
182
|
+
const type = document.createElement('div');
|
|
183
|
+
type.className = 'selection-state-type';
|
|
184
|
+
type.textContent = String(obj?.type || 'object').toUpperCase();
|
|
185
|
+
const name = document.createElement('div');
|
|
186
|
+
name.className = 'selection-state-name';
|
|
187
|
+
name.textContent = _labelFor(obj);
|
|
188
|
+
row.appendChild(type);
|
|
189
|
+
row.appendChild(name);
|
|
190
|
+
list.appendChild(row);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function createSelectionStateButton(viewer) {
|
|
196
|
+
if (!viewer) return null;
|
|
197
|
+
if (!viewer[PANEL_KEY]) {
|
|
198
|
+
viewer[PANEL_KEY] = new SelectionStatePanel(viewer);
|
|
199
|
+
}
|
|
200
|
+
const panel = viewer[PANEL_KEY];
|
|
201
|
+
return {
|
|
202
|
+
label: 'Sel',
|
|
203
|
+
title: 'Toggle selection state window',
|
|
204
|
+
onClick: () => panel.toggle(),
|
|
205
|
+
};
|
|
206
|
+
}
|
package/src/UI/viewer.js
CHANGED
|
@@ -16,6 +16,7 @@ import { HistoryWidget } from './HistoryWidget.js';
|
|
|
16
16
|
import { AssemblyConstraintsWidget } from './assembly/AssemblyConstraintsWidget.js';
|
|
17
17
|
import { PartHistory } from '../PartHistory.js';
|
|
18
18
|
import { SelectionFilter } from './SelectionFilter.js';
|
|
19
|
+
import { SelectionState } from './SelectionState.js';
|
|
19
20
|
import './expressionsManager.js'
|
|
20
21
|
import { expressionsManager } from './expressionsManager.js';
|
|
21
22
|
import { MainToolbar } from './MainToolbar.js';
|
|
@@ -533,6 +534,8 @@ export class Viewer {
|
|
|
533
534
|
this._attachRendererEvents(el);
|
|
534
535
|
|
|
535
536
|
SelectionFilter.viewer = this;
|
|
537
|
+
try { SelectionFilter.startClickWatcher(this); } catch (_) { }
|
|
538
|
+
try { SelectionFilter._ensureSelectionFilterIndicator?.(this); } catch (_) { }
|
|
536
539
|
// Use capture on pointerup to ensure we end interactions even if pointerup fires off-element
|
|
537
540
|
window.addEventListener('pointerup', this._onPointerUp, { passive: false, capture: true });
|
|
538
541
|
document.addEventListener('dblclick', this._onGlobalDoubleClick, { passive: false, capture: true });
|
|
@@ -1476,8 +1479,15 @@ export class Viewer {
|
|
|
1476
1479
|
// ----------------------------------------
|
|
1477
1480
|
// PMI Edit Mode API
|
|
1478
1481
|
// ----------------------------------------
|
|
1482
|
+
_collapseExpandedDialogsForModeSwitch() {
|
|
1483
|
+
try { this.historyWidget?.collapseExpandedEntries?.({ clearOpenState: true, notify: false }); } catch { }
|
|
1484
|
+
try { this.assemblyConstraintsWidget?.collapseExpandedDialogs?.(); } catch { }
|
|
1485
|
+
try { this._pmiMode?.collapseExpandedDialogs?.(); } catch { }
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1479
1488
|
startPMIMode(viewEntry, viewIndex, widget = this.pmiViewsWidget) {
|
|
1480
1489
|
const alreadyActive = !!this._pmiMode;
|
|
1490
|
+
try { this._collapseExpandedDialogsForModeSwitch(); } catch { }
|
|
1481
1491
|
if (!alreadyActive) {
|
|
1482
1492
|
try { this.assemblyConstraintsWidget?.onPMIModeEnter?.(); } catch { }
|
|
1483
1493
|
}
|
|
@@ -1506,6 +1516,9 @@ export class Viewer {
|
|
|
1506
1516
|
|
|
1507
1517
|
endPMIMode() {
|
|
1508
1518
|
const hadMode = !!this._pmiMode;
|
|
1519
|
+
if (hadMode) {
|
|
1520
|
+
try { this._collapseExpandedDialogsForModeSwitch(); } catch { }
|
|
1521
|
+
}
|
|
1509
1522
|
try { if (this._pmiMode) this._pmiMode.dispose(); } catch { }
|
|
1510
1523
|
this._pmiMode = null;
|
|
1511
1524
|
if (hadMode) {
|
|
@@ -2174,16 +2187,8 @@ export class Viewer {
|
|
|
2174
2187
|
const ud = obj.userData;
|
|
2175
2188
|
const defaultMaterial = ud.__defaultMaterial ?? baseMaterial;
|
|
2176
2189
|
if (!ud.__defaultMaterial) ud.__defaultMaterial = baseMaterial;
|
|
2177
|
-
const isHovered = !!ud.__hoverMatApplied;
|
|
2178
|
-
const isSelected = obj.selected === true;
|
|
2179
|
-
|
|
2180
2190
|
const applyBase = (mat) => {
|
|
2181
|
-
|
|
2182
|
-
if (isHovered) {
|
|
2183
|
-
ud.__hoverOrigMat = mat;
|
|
2184
|
-
} else if (!isSelected && mat) {
|
|
2185
|
-
obj.material = mat;
|
|
2186
|
-
}
|
|
2191
|
+
SelectionState.setBaseMaterial(obj, mat);
|
|
2187
2192
|
};
|
|
2188
2193
|
|
|
2189
2194
|
if (!color) {
|
|
@@ -2365,21 +2370,25 @@ export class Viewer {
|
|
|
2365
2370
|
|
|
2366
2371
|
// Prefer the intersected object if it is clickable
|
|
2367
2372
|
let obj = intersection.object;
|
|
2373
|
+
if (obj && obj.type === 'POINTS' && obj.parent && String(obj.parent.type || '').toUpperCase() === SelectionFilter.VERTEX) {
|
|
2374
|
+
obj = obj.parent;
|
|
2375
|
+
}
|
|
2368
2376
|
|
|
2369
2377
|
// If the object (or its ancestors) doesn't expose onClick, climb to one that does
|
|
2370
2378
|
let target = obj;
|
|
2371
2379
|
while (target && typeof target.onClick !== 'function' && target.visible) target = target.parent;
|
|
2380
|
+
if (!target) target = obj;
|
|
2372
2381
|
if (!target) return null;
|
|
2373
2382
|
|
|
2374
2383
|
// Respect selection filter: ensure target is a permitted type, or ALL
|
|
2375
2384
|
if (typeof isAllowed === 'function') {
|
|
2376
2385
|
// Allow selecting already-selected items regardless (toggle off), consistent with SceneListing
|
|
2377
2386
|
if (!isAllowed(target.type) && !target.selected) {
|
|
2378
|
-
// Try to find a closer ancestor
|
|
2387
|
+
// Try to find a closer ancestor of allowed type
|
|
2379
2388
|
// Ascend first (e.g., FACE hit while EDGE is active should try parent SOLID only if allowed)
|
|
2380
2389
|
let t = target.parent;
|
|
2381
|
-
while (t &&
|
|
2382
|
-
if (t &&
|
|
2390
|
+
while (t && !isAllowed(t.type)) t = t.parent;
|
|
2391
|
+
if (t && isAllowed(t.type)) target = t;
|
|
2383
2392
|
else return null;
|
|
2384
2393
|
}
|
|
2385
2394
|
}
|
|
@@ -2566,11 +2575,23 @@ export class Viewer {
|
|
|
2566
2575
|
SelectionFilter.EDGE,
|
|
2567
2576
|
SelectionFilter.FACE,
|
|
2568
2577
|
SelectionFilter.PLANE,
|
|
2578
|
+
SelectionFilter.SKETCH,
|
|
2579
|
+
SelectionFilter.DATUM,
|
|
2580
|
+
SelectionFilter.HELIX,
|
|
2581
|
+
SelectionFilter.LOOP,
|
|
2569
2582
|
SelectionFilter.SOLID,
|
|
2570
2583
|
SelectionFilter.COMPONENT,
|
|
2571
2584
|
].map(t => normType(t));
|
|
2585
|
+
const normSolid = normType(SelectionFilter.SOLID);
|
|
2586
|
+
const normComponent = normType(SelectionFilter.COMPONENT);
|
|
2587
|
+
const nonSolidAllowed = Array.from(allowedSet).some(t => t && t !== normSolid && t !== normComponent);
|
|
2572
2588
|
const getPriority = (type) => {
|
|
2573
|
-
const
|
|
2589
|
+
const nt = normType(type);
|
|
2590
|
+
if (nonSolidAllowed && (nt === normSolid || nt === normComponent)) {
|
|
2591
|
+
// Always push SOLID/COMPONENT to the end when any other type is allowed.
|
|
2592
|
+
return priorityOrder.length + 2;
|
|
2593
|
+
}
|
|
2594
|
+
const idx = priorityOrder.indexOf(nt);
|
|
2574
2595
|
return idx === -1 ? priorityOrder.length : idx;
|
|
2575
2596
|
};
|
|
2576
2597
|
const isAllowedType = (type) => {
|
|
@@ -3,6 +3,7 @@ import { AssemblyConstraintRegistry } from './AssemblyConstraintRegistry.js';
|
|
|
3
3
|
import { evaluateConstraintNumericValue } from './constraintExpressionUtils.js';
|
|
4
4
|
import { deepClone } from '../utils/deepClone.js';
|
|
5
5
|
import { normalizeTypeString } from '../utils/normalizeTypeString.js';
|
|
6
|
+
import { resolveSelectionObject } from '../utils/selectionResolver.js';
|
|
6
7
|
|
|
7
8
|
const RESERVED_KEYS = new Set(['type', 'persistentData', '__open']);
|
|
8
9
|
|
|
@@ -102,47 +103,6 @@ function removeExistingDebugArrows(scene) {
|
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
function resolveSelectionObject(scene, selection) {
|
|
106
|
-
if (!scene || selection == null) return null;
|
|
107
|
-
let target = selection;
|
|
108
|
-
if (Array.isArray(selection)) {
|
|
109
|
-
target = selection.find((item) => item != null) ?? null;
|
|
110
|
-
}
|
|
111
|
-
if (!target) return null;
|
|
112
|
-
if (target.isObject3D) return target;
|
|
113
|
-
try {
|
|
114
|
-
if (typeof target === 'string') {
|
|
115
|
-
if (typeof scene.traverse === 'function') {
|
|
116
|
-
let best = null;
|
|
117
|
-
scene.traverse((obj) => {
|
|
118
|
-
if (!obj || obj.name !== target) return;
|
|
119
|
-
if (!best) best = obj;
|
|
120
|
-
const component = resolveComponentFromObject(obj);
|
|
121
|
-
const bestComponent = best ? resolveComponentFromObject(best) : null;
|
|
122
|
-
if (component && !bestComponent) {
|
|
123
|
-
best = obj;
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
if (best) return best;
|
|
127
|
-
}
|
|
128
|
-
return typeof scene.getObjectByName === 'function'
|
|
129
|
-
? scene.getObjectByName(target)
|
|
130
|
-
: null;
|
|
131
|
-
}
|
|
132
|
-
if (typeof target?.uuid === 'string' && typeof scene.getObjectByProperty === 'function') {
|
|
133
|
-
const found = scene.getObjectByProperty('uuid', target.uuid);
|
|
134
|
-
if (found) return found;
|
|
135
|
-
}
|
|
136
|
-
if (typeof target?.name === 'string' && typeof scene.getObjectByName === 'function') {
|
|
137
|
-
const found = scene.getObjectByName(target.name);
|
|
138
|
-
if (found) return found;
|
|
139
|
-
}
|
|
140
|
-
} catch {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
106
|
function resolveComponentFromObject(obj) {
|
|
147
107
|
let current = obj;
|
|
148
108
|
while (current) {
|
|
@@ -152,6 +112,10 @@ function resolveComponentFromObject(obj) {
|
|
|
152
112
|
return null;
|
|
153
113
|
}
|
|
154
114
|
|
|
115
|
+
function scoreObjectForComponent(object) {
|
|
116
|
+
return resolveComponentFromObject(object) ? 1 : 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
155
119
|
function vectorFrom(value) {
|
|
156
120
|
if (!value) return null;
|
|
157
121
|
if (value instanceof THREE.Vector3) return value.clone();
|
|
@@ -894,7 +858,19 @@ export class AssemblyConstraintHistory {
|
|
|
894
858
|
|
|
895
859
|
const updatedComponents = new Set();
|
|
896
860
|
|
|
897
|
-
const resolveObject = (selection) => resolveSelectionObject(scene, selection
|
|
861
|
+
const resolveObject = (selection) => resolveSelectionObject(scene, selection, {
|
|
862
|
+
scoreFn: scoreObjectForComponent,
|
|
863
|
+
allowJson: false,
|
|
864
|
+
allowUuidString: false,
|
|
865
|
+
allowUuidObject: true,
|
|
866
|
+
allowFuzzyName: false,
|
|
867
|
+
allowNameContains: false,
|
|
868
|
+
allowPath: false,
|
|
869
|
+
allowReference: false,
|
|
870
|
+
allowTarget: false,
|
|
871
|
+
allowSelectionName: false,
|
|
872
|
+
arrayMode: 'first',
|
|
873
|
+
});
|
|
898
874
|
const resolveComponent = (selection) => {
|
|
899
875
|
const obj = resolveObject(selection);
|
|
900
876
|
return resolveComponentFromObject(obj);
|
|
@@ -33,6 +33,7 @@ export class AngleConstraint extends BaseAssemblyConstraint {
|
|
|
33
33
|
static shortName = '∠';
|
|
34
34
|
static longName = '∠ Angle Constraint';
|
|
35
35
|
static constraintType = 'angle';
|
|
36
|
+
static focusField = 'angle';
|
|
36
37
|
static aliases = ['angle', 'angle_between', 'angular', 'ANGL'];
|
|
37
38
|
static inputParamsSchema = inputParamsSchema;
|
|
38
39
|
|
|
@@ -37,6 +37,7 @@ export class DistanceConstraint extends BaseAssemblyConstraint {
|
|
|
37
37
|
static shortName = '⟺';
|
|
38
38
|
static longName = '⟺ Distance Constraint';
|
|
39
39
|
static constraintType = 'distance';
|
|
40
|
+
static focusField = 'distance';
|
|
40
41
|
static aliases = ['distance', 'offset', 'gap', 'DIST'];
|
|
41
42
|
static inputParamsSchema = inputParamsSchema;
|
|
42
43
|
|
|
@@ -1,16 +1,32 @@
|
|
|
1
|
+
import { resolveSelectionObject as resolveSelectionObjectBase } from '../utils/selectionResolver.js';
|
|
2
|
+
|
|
1
3
|
export function resolveSelectionObject(selection, partHistory) {
|
|
2
4
|
if (!selection) return null;
|
|
3
|
-
if (typeof selection
|
|
5
|
+
if (typeof selection !== 'string') return selection;
|
|
6
|
+
|
|
7
|
+
const nameResolver = (name) => {
|
|
4
8
|
if (partHistory && typeof partHistory.getObjectByName === 'function') {
|
|
5
|
-
return partHistory.getObjectByName(
|
|
9
|
+
return partHistory.getObjectByName(name);
|
|
6
10
|
}
|
|
7
11
|
const scene = partHistory?.scene;
|
|
8
12
|
if (scene && typeof scene.getObjectByName === 'function') {
|
|
9
|
-
return scene.getObjectByName(
|
|
13
|
+
return scene.getObjectByName(name);
|
|
10
14
|
}
|
|
11
15
|
return null;
|
|
12
|
-
}
|
|
13
|
-
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return resolveSelectionObjectBase(partHistory?.scene || null, selection, {
|
|
19
|
+
nameResolver,
|
|
20
|
+
allowJson: false,
|
|
21
|
+
allowUuid: false,
|
|
22
|
+
allowFuzzyName: false,
|
|
23
|
+
allowNameContains: false,
|
|
24
|
+
allowPath: false,
|
|
25
|
+
allowReference: false,
|
|
26
|
+
allowTarget: false,
|
|
27
|
+
allowSelectionName: false,
|
|
28
|
+
arrayMode: 'first',
|
|
29
|
+
});
|
|
14
30
|
}
|
|
15
31
|
|
|
16
32
|
function getFeatureEntryId(entry) {
|
|
@@ -4,6 +4,7 @@ import { BREP } from "../../BREP/BREP.js";
|
|
|
4
4
|
const THREE = BREP.THREE;
|
|
5
5
|
import { LineGeometry } from 'three/examples/jsm/Addons.js';
|
|
6
6
|
import { deepClone } from '../../utils/deepClone.js';
|
|
7
|
+
import { SelectionState } from '../../UI/SelectionState.js';
|
|
7
8
|
|
|
8
9
|
const inputParamsSchema = {
|
|
9
10
|
id: {
|
|
@@ -892,8 +893,7 @@ export class SketchFeature {
|
|
|
892
893
|
if (sketchMat) {
|
|
893
894
|
sketchMat.side = THREE.DoubleSide;
|
|
894
895
|
sketchMat.needsUpdate = true;
|
|
895
|
-
face
|
|
896
|
-
face.userData.__baseMaterial = sketchMat;
|
|
896
|
+
SelectionState.setBaseMaterial(face, sketchMat);
|
|
897
897
|
}
|
|
898
898
|
} catch { }
|
|
899
899
|
sceneGroup.add(face);
|
|
@@ -689,9 +689,10 @@ const shortestAngleDelta = (target, current) => {
|
|
|
689
689
|
|
|
690
690
|
|
|
691
691
|
export const constraints = {
|
|
692
|
-
tolerance,
|
|
692
|
+
get tolerance() { return tolerance; },
|
|
693
|
+
set tolerance(value) { tolerance = value; },
|
|
693
694
|
constraintFunctions,
|
|
694
|
-
}
|
|
695
|
+
};
|
|
695
696
|
|
|
696
697
|
|
|
697
698
|
|