@buerli.io/react-cad 0.6.0 → 0.7.1-beta.1

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.
@@ -8,6 +8,7 @@ var core = require('@buerli.io/core');
8
8
  var classcad = require('@buerli.io/classcad');
9
9
  var THREE = require('three');
10
10
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
11
+ var _extends = require('@babel/runtime/helpers/extends');
11
12
  var fiber = require('@react-three/fiber');
12
13
  var drei = require('@react-three/drei');
13
14
  var create = require('zustand');
@@ -15,7 +16,6 @@ var vanilla = require('zustand/vanilla');
15
16
  require('antd/dist/antd.css');
16
17
  var styled = require('styled-components');
17
18
  var icons = require('@ant-design/icons');
18
- var _extends = require('@babel/runtime/helpers/extends');
19
19
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
20
20
  var reactDom = require('react-dom');
21
21
  var antd = require('antd');
@@ -223,7 +223,7 @@ function useGlobalToLocalMatrix(drawingId, objId) {
223
223
  function getGlobalToLocalMatrix(drawingId, objId) {
224
224
  const drawing = core.getDrawing(drawingId);
225
225
  const object = drawing.structure.tree[objId];
226
- const matrix = core.MathUtils.convertToMatrix4(object.coordinateSystem);
226
+ const matrix = object.coordinateSystem ? core.MathUtils.convertToMatrix4(object.coordinateSystem) : new THREE__namespace.Matrix4();
227
227
  return matrix.invert();
228
228
  }
229
229
  function convertToVector(point) {
@@ -1115,9 +1115,36 @@ const isAngular = dim => classcad.ccUtils.base.isA(dim.class, classcad.CCClasses
1115
1115
 
1116
1116
  function ownKeys$q(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
1117
1117
  function _objectSpread$q(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$q(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$q(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
1118
+ const isFeatureActive = drawingId => {
1119
+ const activePlugin = core.getDrawing(drawingId).plugin.active.feature;
1120
+ if (activePlugin) {
1121
+ core.showMessage({
1122
+ text: 'Error: Please close feature before changing the current product!',
1123
+ type: 'error'
1124
+ });
1125
+ return true;
1126
+ }
1127
+ return false;
1128
+ };
1129
+ const isExprPluginActive = drawingId => {
1130
+ const drawing = core.getDrawing(drawingId);
1131
+ const activeGPlugins = drawing.plugin.active.global;
1132
+ const isExprPluginActive_ = activeGPlugins.findIndex(id => drawing.plugin.refs[id].name === 'Expressions') !== -1;
1133
+ if (isExprPluginActive_) {
1134
+ core.showMessage({
1135
+ text: 'Error: Please close the Expressions plugin before changing the current product!',
1136
+ type: 'error'
1137
+ });
1138
+ return true;
1139
+ }
1140
+ return false;
1141
+ };
1118
1142
  const appApi = (set, get) => ({
1119
1143
  assemblyTree: {
1120
1144
  startProdEditing: (drawingId, objId) => {
1145
+ if (isFeatureActive(drawingId) || isExprPluginActive(drawingId)) {
1146
+ return;
1147
+ }
1121
1148
  set(state => {
1122
1149
  let res = [];
1123
1150
  const curNode = core.api.getState().drawing.refs[drawingId].structure.currentNode;
@@ -1134,7 +1161,9 @@ const appApi = (set, get) => ({
1134
1161
  goBack: drawingId => {
1135
1162
  const prodStack = get().assemblyTree.prodStack;
1136
1163
  const prevProd = prodStack[prodStack.length - 1];
1137
- if (!prevProd) return;
1164
+ if (!prevProd || isFeatureActive(drawingId) || isExprPluginActive(drawingId)) {
1165
+ return;
1166
+ }
1138
1167
  set(state => {
1139
1168
  const res = state.assemblyTree.prodStack;
1140
1169
  res.pop();
@@ -1212,13 +1241,19 @@ const BlankDiv = () => {
1212
1241
  }) : null;
1213
1242
  };
1214
1243
 
1244
+ const notoSansFont$1 = 'https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5TRG.woff';
1245
+ const characters$1 = '0123456789-,.';
1246
+ const quat$1 = new THREE__namespace.Quaternion();
1247
+ const textMaterial$1 = new THREE__namespace.MeshBasicMaterial({
1248
+ depthTest: false,
1249
+ depthWrite: false
1250
+ });
1215
1251
  const mainColor = 0x424242;
1216
1252
  const lineWidth$1 = 0.5;
1217
1253
  const arrowSize = 5;
1218
1254
  const TextValue = ({
1219
1255
  position,
1220
1256
  value,
1221
- onClick,
1222
1257
  backgroundColor
1223
1258
  }) => {
1224
1259
  return /*#__PURE__*/React.createElement("group", {
@@ -1226,11 +1261,11 @@ const TextValue = ({
1226
1261
  }, /*#__PURE__*/React.createElement(drei.Html, {
1227
1262
  zIndexRange: [0, 0],
1228
1263
  style: {
1229
- marginTop: '22px'
1264
+ marginTop: '22px',
1265
+ pointerEvents: 'none'
1230
1266
  },
1231
1267
  center: true
1232
1268
  }, /*#__PURE__*/React.createElement("div", {
1233
- onClick: onClick,
1234
1269
  style: {
1235
1270
  backgroundColor: backgroundColor ? `#${backgroundColor.toString(16)}` : undefined,
1236
1271
  color: `#${mainColor.toString(16)}`,
@@ -1242,12 +1277,14 @@ const TextValue = ({
1242
1277
  const DimValue = ({
1243
1278
  position,
1244
1279
  backgroundColor,
1245
- dimId
1280
+ dimId,
1281
+ disableEvents = false
1246
1282
  }) => {
1247
1283
  var _dimension$members, _tree, _master$members;
1248
1284
  const {
1249
1285
  drawingId
1250
1286
  } = React.useContext(DimContext);
1287
+ const textRef = React.useRef(null);
1251
1288
  const tree = core.getDrawing(drawingId).structure.tree;
1252
1289
  const dimension = tree[dimId];
1253
1290
  const masterId = (_dimension$members = dimension.members) == null ? void 0 : _dimension$members.master.value;
@@ -1269,6 +1306,31 @@ const DimValue = ({
1269
1306
  return expr && !isDeg ? expr + ' (' + valueStr + ')' : valueStr;
1270
1307
  }, [master, memberName]);
1271
1308
  const [editMode, setEditMode] = React.useState(false);
1309
+ const [isHovered, setIsHovered] = React.useState(false);
1310
+ drei.useCursor(isHovered, 'text');
1311
+ const onPointerOver = React.useCallback(e => {
1312
+ setIsHovered(true);
1313
+ e.stopPropagation();
1314
+ }, []);
1315
+ const onPointerOut = React.useCallback(e => {
1316
+ setIsHovered(false);
1317
+ e.stopPropagation();
1318
+ }, []);
1319
+ const onClick = React.useCallback(e => {
1320
+ setIsHovered(false);
1321
+ setEditMode(true);
1322
+ e.stopPropagation();
1323
+ }, []);
1324
+ const stopPropagation = React.useCallback(e => {
1325
+ e.stopPropagation();
1326
+ }, []);
1327
+ const handlers = disableEvents ? {} : {
1328
+ onPointerOver,
1329
+ onPointerOut,
1330
+ onClick,
1331
+ onPointerDown: stopPropagation,
1332
+ onPointerUp: stopPropagation
1333
+ };
1272
1334
  React.useEffect(() => {
1273
1335
  if (editMode) {
1274
1336
  getCADState().api.blankDiv.show(() => setEditMode(false));
@@ -1279,7 +1341,7 @@ const DimValue = ({
1279
1341
  var _master_$children, _sketchRegion$members, _master_$members, _master_$members2, _master_$members3, _master_$members4, _master_$members5;
1280
1342
  const master_ = core.getDrawing(drawingId).structure.tree[masterId];
1281
1343
  if (isSketchConstr) {
1282
- classcad.ccAPI.base.callSafeAPI(drawingId, 'Sketcher', 'UpdateDimensionValue', [dimId, [valueParam.serverValue.value, valueParam.serverValue.isExpr]]).catch(console.warn);
1344
+ classcad.ccAPI.sketcher.updateDimensionValue(drawingId, dimId, valueParam.serverValue).catch(console.warn);
1283
1345
  } else {
1284
1346
  switch (master_.class) {
1285
1347
  case classcad.CCClasses.CCExtrusion:
@@ -1314,28 +1376,39 @@ const DimValue = ({
1314
1376
  }
1315
1377
  e.stopPropagation();
1316
1378
  }, [update]);
1379
+ fiber.useFrame(args => {
1380
+ if (!textRef.current || !textRef.current.parent) {
1381
+ return;
1382
+ }
1383
+ textRef.current.quaternion.copy(textRef.current.parent.getWorldQuaternion(quat$1)).invert().multiply(args.camera.quaternion);
1384
+ textRef.current.scale.setScalar(1 / args.camera.zoom);
1385
+ });
1317
1386
  return /*#__PURE__*/React.createElement("group", {
1318
1387
  position: position
1319
- }, /*#__PURE__*/React.createElement(drei.Html, {
1388
+ }, !editMode ? /*#__PURE__*/React.createElement(React.Suspense, {
1389
+ fallback: null
1390
+ }, /*#__PURE__*/React.createElement(drei.Text, _extends({
1391
+ ref: textRef,
1392
+ color: "#111111",
1393
+ font: notoSansFont$1,
1394
+ fontSize: 17,
1395
+ letterSpacing: 0.05,
1396
+ anchorY: 17,
1397
+ characters: characters$1,
1398
+ renderOrder: 3000,
1399
+ material: textMaterial$1,
1400
+ userData: {
1401
+ onHUD: true
1402
+ }
1403
+ }, handlers), caption)) : /*#__PURE__*/React.createElement(drei.Html, {
1320
1404
  zIndexRange: [blankZIndex + 1, blankZIndex + 1],
1321
1405
  style: {
1322
1406
  transform: 'translate3d(-50%,0,0)',
1323
- marginTop: '14px'
1407
+ marginTop: '10px'
1324
1408
  }
1325
1409
  }, /*#__PURE__*/React.createElement("div", {
1326
1410
  onKeyUp: keyHandler
1327
- }, !editMode ? /*#__PURE__*/React.createElement("div", {
1328
- onClick: () => {
1329
- setEditMode(true);
1330
- },
1331
- style: {
1332
- backgroundColor: backgroundColor ? `#${backgroundColor.toString(16)}` : undefined,
1333
- color: `#${mainColor.toString(16)}`,
1334
- fontSize: '17px',
1335
- textAlign: 'center',
1336
- cursor: 'text'
1337
- }
1338
- }, caption) : /*#__PURE__*/React.createElement("div", {
1411
+ }, /*#__PURE__*/React.createElement("div", {
1339
1412
  style: {
1340
1413
  width: '100px'
1341
1414
  }
@@ -1412,7 +1485,8 @@ const hRadius$1 = 6; // Radius of position handler in pixels
1412
1485
  const PositionHandler = ({
1413
1486
  dimId,
1414
1487
  setPosition,
1415
- position
1488
+ position,
1489
+ disableEvents = false
1416
1490
  }) => {
1417
1491
  const isPressed = React.useRef(false);
1418
1492
  const isDragged = React.useRef(false);
@@ -1479,15 +1553,17 @@ const PositionHandler = ({
1479
1553
  setIsHovered(false);
1480
1554
  e.stopPropagation();
1481
1555
  }, []);
1482
- return /*#__PURE__*/React.createElement("mesh", {
1556
+ const handlers = disableEvents ? {} : {
1557
+ onPointerDown,
1558
+ onPointerUp,
1559
+ onPointerOver,
1560
+ onPointerMove,
1561
+ onPointerOut
1562
+ };
1563
+ return /*#__PURE__*/React.createElement("mesh", _extends({
1483
1564
  ref: ref,
1484
- position: position,
1485
- onPointerDown: onPointerDown,
1486
- onPointerMove: onPointerMove,
1487
- onPointerUp: onPointerUp,
1488
- onPointerOver: onPointerOver,
1489
- onPointerOut: onPointerOut
1490
- }, /*#__PURE__*/React.createElement("sphereGeometry", {
1565
+ position: position
1566
+ }, handlers), /*#__PURE__*/React.createElement("sphereGeometry", {
1491
1567
  args: [1.5, 16, 16]
1492
1568
  }), /*#__PURE__*/React.createElement("meshBasicMaterial", {
1493
1569
  color: mainColor,
@@ -1499,7 +1575,8 @@ const PositionHandler = ({
1499
1575
  };
1500
1576
 
1501
1577
  const LinearDim = ({
1502
- dimId
1578
+ dimId,
1579
+ disableEvents = false
1503
1580
  }) => {
1504
1581
  const {
1505
1582
  drawingId
@@ -1558,15 +1635,18 @@ const LinearDim = ({
1558
1635
  dir: endDir
1559
1636
  }), /*#__PURE__*/React.createElement(DimValue, {
1560
1637
  position: tmpDimP,
1561
- dimId: dimension.id
1638
+ dimId: dimension.id,
1639
+ disableEvents: disableEvents
1562
1640
  }), /*#__PURE__*/React.createElement(PositionHandler, {
1563
1641
  position: tmpDimP,
1564
1642
  setPosition: setTmpDimP,
1565
- dimId: dimId
1643
+ dimId: dimId,
1644
+ disableEvents: disableEvents
1566
1645
  }));
1567
1646
  };
1568
1647
  const RadialDim = ({
1569
- dimId
1648
+ dimId,
1649
+ disableEvents = false
1570
1650
  }) => {
1571
1651
  const {
1572
1652
  drawingId
@@ -1604,14 +1684,17 @@ const RadialDim = ({
1604
1684
  }), /*#__PURE__*/React.createElement(PositionHandler, {
1605
1685
  position: tmpDimP,
1606
1686
  setPosition: setTmpDimP,
1607
- dimId: dimId
1687
+ dimId: dimId,
1688
+ disableEvents: disableEvents
1608
1689
  }), /*#__PURE__*/React.createElement(DimValue, {
1609
1690
  position: tmpDimP,
1610
- dimId: dimension.id
1691
+ dimId: dimension.id,
1692
+ disableEvents: disableEvents
1611
1693
  }));
1612
1694
  };
1613
1695
  const DiametralDim = ({
1614
- dimId
1696
+ dimId,
1697
+ disableEvents = false
1615
1698
  }) => {
1616
1699
  const {
1617
1700
  drawingId
@@ -1653,14 +1736,17 @@ const DiametralDim = ({
1653
1736
  }), /*#__PURE__*/React.createElement(PositionHandler, {
1654
1737
  position: tmpDimP,
1655
1738
  setPosition: setTmpDimP,
1656
- dimId: dimId
1739
+ dimId: dimId,
1740
+ disableEvents: disableEvents
1657
1741
  }), /*#__PURE__*/React.createElement(DimValue, {
1658
1742
  position: tmpDimP,
1659
- dimId: dimension.id
1743
+ dimId: dimension.id,
1744
+ disableEvents: disableEvents
1660
1745
  }));
1661
1746
  };
1662
1747
  const AngularDim = ({
1663
- dimId
1748
+ dimId,
1749
+ disableEvents = false
1664
1750
  }) => {
1665
1751
  const {
1666
1752
  drawingId
@@ -1744,14 +1830,17 @@ const AngularDim = ({
1744
1830
  }), /*#__PURE__*/React.createElement(PositionHandler, {
1745
1831
  dimId: dimId,
1746
1832
  position: tmpDimP,
1747
- setPosition: setTmpDimP
1833
+ setPosition: setTmpDimP,
1834
+ disableEvents: disableEvents
1748
1835
  }), /*#__PURE__*/React.createElement(DimValue, {
1749
1836
  position: tmpDimP,
1750
- dimId: dimension.id
1837
+ dimId: dimension.id,
1838
+ disableEvents: disableEvents
1751
1839
  }));
1752
1840
  };
1753
1841
  const DimGraphics = ({
1754
- dimId
1842
+ dimId,
1843
+ disableEvents = false
1755
1844
  }) => {
1756
1845
  const {
1757
1846
  drawingId
@@ -1762,23 +1851,27 @@ const DimGraphics = ({
1762
1851
  });
1763
1852
  if (classcad.ccUtils.base.isA(objClass, classcad.CCClasses.CCLinearDimension)) {
1764
1853
  return /*#__PURE__*/React.createElement(LinearDim, {
1765
- dimId: dimId
1854
+ dimId: dimId,
1855
+ disableEvents: disableEvents
1766
1856
  });
1767
1857
  }
1768
1858
  if (classcad.ccUtils.base.isA(objClass, classcad.CCClasses.CCAngularDimension)) {
1769
1859
  return /*#__PURE__*/React.createElement(AngularDim, {
1770
- dimId: dimId
1860
+ dimId: dimId,
1861
+ disableEvents: disableEvents
1771
1862
  });
1772
1863
  }
1773
1864
  // DiameterDimension is also inherited from RadialDimension, so this check should strictly be first...
1774
1865
  if (classcad.ccUtils.base.isA(objClass, classcad.CCClasses.CCDiameterDimension)) {
1775
1866
  return /*#__PURE__*/React.createElement(DiametralDim, {
1776
- dimId: dimId
1867
+ dimId: dimId,
1868
+ disableEvents: disableEvents
1777
1869
  });
1778
1870
  }
1779
1871
  if (classcad.ccUtils.base.isA(objClass, classcad.CCClasses.CCRadialDimension)) {
1780
1872
  return /*#__PURE__*/React.createElement(RadialDim, {
1781
- dimId: dimId
1873
+ dimId: dimId,
1874
+ disableEvents: disableEvents
1782
1875
  });
1783
1876
  }
1784
1877
  return null;
@@ -2064,12 +2157,26 @@ function ViewImpl$f({
2064
2157
  drawingId,
2065
2158
  pluginId
2066
2159
  }) {
2160
+ var _dimSet$members, _dimSet$members$owner;
2067
2161
  const {
2068
2162
  objectId
2069
2163
  } = core.getPlugin(drawingId, pluginId);
2070
- const dimSet = react.useDrawing(drawingId, state => objectId && state.structure.tree[objectId]);
2164
+ const dimSet = react.useDrawing(drawingId, state => state.structure.tree[objectId || NOCCID]);
2165
+ const ownerId = (dimSet == null ? void 0 : (_dimSet$members = dimSet.members) == null ? void 0 : (_dimSet$members$owner = _dimSet$members.owner) == null ? void 0 : _dimSet$members$owner.value) || NOCCID;
2071
2166
  // dimSet here might be undefined for features without constrains
2072
2167
  const children = dimSet && dimSet.children || [];
2168
+
2169
+ // Dimensions shouldn't be interactable if sketch is active and a non-drag handler is active
2170
+ const isOwnerActive = react.useDrawing(drawingId, d => d.plugin.active.feature === ownerId) || false;
2171
+ const isOwnerSketch = react.useDrawing(drawingId, d => {
2172
+ var _d$structure$tree$own;
2173
+ return classcad.ccUtils.base.isA((_d$structure$tree$own = d.structure.tree[ownerId]) == null ? void 0 : _d$structure$tree$own.class, classcad.CCClasses.CCSketch);
2174
+ }) || false;
2175
+ const ownerState = react.useDrawing(drawingId, d => {
2176
+ var _d$plugin$refs$ownerI;
2177
+ return (_d$plugin$refs$ownerI = d.plugin.refs[ownerId]) == null ? void 0 : _d$plugin$refs$ownerI.state;
2178
+ });
2179
+ const disableEvents = isOwnerActive && isOwnerSketch && (ownerState == null ? void 0 : ownerState.activeHandler) !== undefined && ownerState.activeHandler !== 'drag';
2073
2180
  const matrix = useGlobalToLocalMatrix(drawingId, objectId);
2074
2181
  const contexVal = React.useMemo(() => {
2075
2182
  return {
@@ -2093,7 +2200,8 @@ function ViewImpl$f({
2093
2200
  value: contexVal
2094
2201
  }, children.map(dimId => /*#__PURE__*/React.createElement(DimGraphics$1, {
2095
2202
  key: dimId,
2096
- dimId: dimId
2203
+ dimId: dimId,
2204
+ disableEvents: disableEvents
2097
2205
  }))));
2098
2206
  }
2099
2207
  const View$f = ({
@@ -2335,7 +2443,6 @@ function useRefsParam(drawingId, objId, memberName) {
2335
2443
 
2336
2444
  function ownKeys$p(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2337
2445
  function _objectSpread$p(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$p(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$p(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
2338
-
2339
2446
  /**
2340
2447
  * Implies the following data structure:
2341
2448
  * data: {
@@ -2357,59 +2464,167 @@ const createTreeObjSelItem = (productId, object) => {
2357
2464
  removeCondition: d => d.structure.tree[object.id] === undefined
2358
2465
  };
2359
2466
  };
2467
+
2468
+ // Returns event values that are used in treeObjInteraction events
2469
+ const getEventInfo = e => {
2470
+ const eDef = e;
2471
+ const eRTF = e;
2472
+ if (eRTF.delta !== undefined) {
2473
+ return {
2474
+ delta: eRTF.delta,
2475
+ stopPropagation: eRTF.stopPropagation,
2476
+ shiftKey: eRTF.nativeEvent.shiftKey
2477
+ };
2478
+ } else {
2479
+ return {
2480
+ delta: 0,
2481
+ stopPropagation: undefined,
2482
+ shiftKey: eDef.shiftKey
2483
+ };
2484
+ }
2485
+ };
2360
2486
  function useSelect$1(drawingId, objId) {
2361
2487
  const onClick = React.useCallback(e => {
2362
- e.stopPropagation();
2363
- if (e.delta > 1) {
2488
+ var _drawing$plugin$refs, _drawing$structure$tr;
2489
+ const {
2490
+ delta,
2491
+ stopPropagation,
2492
+ shiftKey
2493
+ } = getEventInfo(e);
2494
+ if (delta > 1) {
2364
2495
  return;
2365
2496
  }
2366
- const structure = core.getDrawing(drawingId).structure;
2367
- const productId = structure.currentProduct;
2368
- if (!productId) return;
2369
- const object = structure.tree[objId];
2370
- const item = createTreeObjSelItem(productId, object);
2371
- const selApi = core.getDrawing(drawingId).api.selection;
2372
- selApi.isItemSelected(item) ? selApi.unselect(item) : selApi.select(item);
2497
+ const drawing = core.getDrawing(drawingId);
2498
+ const productId = drawing.structure.currentProduct;
2499
+ const object = drawing.structure.tree[objId];
2500
+ const selection = drawing.selection.refs[drawing.selection.active || ''];
2501
+ const isSelActive = selection !== undefined;
2502
+ const isSelectable = (selection == null ? void 0 : selection.isSelectable(TreeObjScope, {
2503
+ object
2504
+ })) || false;
2505
+ const activeId = ((_drawing$plugin$refs = drawing.plugin.refs[drawing.plugin.active.feature || -1]) == null ? void 0 : _drawing$plugin$refs.id) || -1;
2506
+ const objClass = ((_drawing$structure$tr = drawing.structure.tree[activeId]) == null ? void 0 : _drawing$structure$tr.class) || '';
2507
+ const isSketchActive = classcad.ccUtils.base.isA(objClass, classcad.CCClasses.CCSketch);
2508
+ if ((isSketchActive || isSelActive) && !isSelectable || !productId) {
2509
+ return;
2510
+ }
2511
+ stopPropagation == null ? void 0 : stopPropagation();
2512
+ if (selection) {
2513
+ if (selection.isSelectable(TreeObjScope, {
2514
+ object
2515
+ })) {
2516
+ const item = createTreeObjSelItem(productId, object);
2517
+ const selApi = drawing.api.selection;
2518
+ selApi.isItemSelected(item) ? selApi.unselect(item) : selApi.select(item);
2519
+ }
2520
+ return;
2521
+ }
2522
+ const interactionInfo = core.createInfo({
2523
+ objectId: objId,
2524
+ prodRefId: productId
2525
+ });
2526
+ const select = drawing.api.interaction.select;
2527
+ select(interactionInfo, shiftKey);
2373
2528
  }, [drawingId, objId]);
2374
- return {
2529
+ return React.useMemo(() => ({
2375
2530
  onClick
2376
- };
2377
- }
2378
- function useIsHovered$1(drawingId, objId) {
2379
- const activeSelId = react.useDrawing(drawingId, d => d.selection.active);
2380
- const isHovered = react.useDrawing(drawingId, d => {
2381
- var _d$selection$refs;
2382
- // Unfortunately we need this big selector in useDrawing,
2383
- // without it useIsHovered leads to re-rendering of component each time when hovered of the selection is changed.
2384
- const hoveredItem = (_d$selection$refs = d.selection.refs[activeSelId || '']) == null ? void 0 : _d$selection$refs.hoveredItem;
2385
- if (!hoveredItem) return false;
2386
- const productId = d.structure.currentProduct;
2387
- if (!productId) return false;
2388
- const object = d.structure.tree[objId];
2389
- return createTreeObjSelItem(productId, object).id === hoveredItem.id;
2390
- }) || false;
2391
- return isHovered;
2531
+ }), [onClick]);
2392
2532
  }
2393
2533
  function useHover$1(drawingId, objId) {
2394
2534
  const onPointerOver = React.useCallback(e => {
2395
- e.stopPropagation();
2396
- const structure = core.getDrawing(drawingId).structure;
2397
- const productId = structure.currentProduct;
2398
- if (!productId) return;
2399
- const object = core.getDrawing(drawingId).structure.tree[objId];
2400
- const item = createTreeObjSelItem(productId, object);
2401
- const selApi = core.getDrawing(drawingId).api.selection;
2402
- selApi.setHovered(item);
2535
+ var _drawing$plugin$refs2, _drawing$structure$tr2, _drawing$interaction$;
2536
+ const {
2537
+ stopPropagation
2538
+ } = getEventInfo(e);
2539
+ const drawing = core.getDrawing(drawingId);
2540
+ const productId = drawing.structure.currentProduct;
2541
+ const object = drawing.structure.tree[objId];
2542
+ const selection = drawing.selection.refs[drawing.selection.active || ''];
2543
+ const isSelActive = selection !== undefined;
2544
+ const isSelectable = (selection == null ? void 0 : selection.isSelectable(TreeObjScope, {
2545
+ object
2546
+ })) || false;
2547
+ const activeId = ((_drawing$plugin$refs2 = drawing.plugin.refs[drawing.plugin.active.feature || -1]) == null ? void 0 : _drawing$plugin$refs2.id) || -1;
2548
+ const objClass = ((_drawing$structure$tr2 = drawing.structure.tree[activeId]) == null ? void 0 : _drawing$structure$tr2.class) || '';
2549
+ const isSketchActive = classcad.ccUtils.base.isA(objClass, classcad.CCClasses.CCSketch);
2550
+ if ((isSketchActive || isSelActive) && !isSelectable || !productId) {
2551
+ return;
2552
+ }
2553
+ stopPropagation == null ? void 0 : stopPropagation();
2554
+ const interactionInfo = core.createInfo({
2555
+ objectId: objId,
2556
+ prodRefId: productId
2557
+ });
2558
+ if (interactionInfo.uniqueIdent !== ((_drawing$interaction$ = drawing.interaction.hovered) == null ? void 0 : _drawing$interaction$.uniqueIdent)) {
2559
+ const setHovered = drawing.api.interaction.setHovered;
2560
+ setHovered(interactionInfo);
2561
+ }
2403
2562
  }, [drawingId, objId]);
2404
2563
  const onPointerOut = React.useCallback(e => {
2405
- e.stopPropagation();
2406
- const selApi = core.getDrawing(drawingId).api.selection;
2407
- selApi.setHovered(null);
2408
- }, [drawingId]);
2409
- return {
2564
+ var _drawing$interaction$2;
2565
+ const {
2566
+ stopPropagation
2567
+ } = getEventInfo(e);
2568
+ const drawing = core.getDrawing(drawingId);
2569
+ const productId = drawing.structure.currentProduct;
2570
+ if (!productId) {
2571
+ return;
2572
+ }
2573
+ stopPropagation == null ? void 0 : stopPropagation();
2574
+ const interactionInfo = core.createInfo({
2575
+ objectId: objId,
2576
+ prodRefId: productId
2577
+ });
2578
+ if (interactionInfo.uniqueIdent === ((_drawing$interaction$2 = drawing.interaction.hovered) == null ? void 0 : _drawing$interaction$2.uniqueIdent)) {
2579
+ const setHovered = core.getDrawing(drawingId).api.interaction.setHovered;
2580
+ setHovered(null);
2581
+ }
2582
+ }, [drawingId, objId]);
2583
+ return React.useMemo(() => ({
2410
2584
  onPointerOut,
2411
2585
  onPointerOver
2412
- };
2586
+ }), [onPointerOut, onPointerOver]);
2587
+ }
2588
+ function useIsSketchActive(drawingId) {
2589
+ const activeId = react.useDrawing(drawingId, d => {
2590
+ var _d$plugin$refs;
2591
+ return (_d$plugin$refs = d.plugin.refs[d.plugin.active.feature || -1]) == null ? void 0 : _d$plugin$refs.id;
2592
+ }) || -1;
2593
+ const objClass = react.useDrawing(drawingId, d => {
2594
+ var _d$structure$tree$act;
2595
+ return (_d$structure$tree$act = d.structure.tree[activeId]) == null ? void 0 : _d$structure$tree$act.class;
2596
+ }) || '';
2597
+ return classcad.ccUtils.base.isA(objClass, classcad.CCClasses.CCSketch);
2598
+ }
2599
+ function useIsGHovered(drawingId, objId) {
2600
+ const isHovered = react.useDrawing(drawingId, d => {
2601
+ var _d$interaction$hovere;
2602
+ return ((_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.objectId) === objId;
2603
+ }) || false;
2604
+ const isSelActive = react.useDrawing(drawingId, d => d.selection.active !== null) || false;
2605
+ const isSketchActive = useIsSketchActive(drawingId);
2606
+ return !isSelActive && !isSketchActive && isHovered;
2607
+ }
2608
+ function useIsGSelected(drawingId, objId) {
2609
+ const isGSelected = react.useDrawing(drawingId, d => {
2610
+ var _d$interaction$select;
2611
+ return ((_d$interaction$select = d.interaction.selected) == null ? void 0 : _d$interaction$select.findIndex(info => info.objectId === objId)) !== -1;
2612
+ }) || false;
2613
+ const isSelActive = react.useDrawing(drawingId, d => d.selection.active !== null) || false;
2614
+ const isSketchActive = useIsSketchActive(drawingId);
2615
+ return !isSelActive && !isSketchActive && isGSelected;
2616
+ }
2617
+ function useIsSHovered(drawingId, objId) {
2618
+ const object = react.useDrawing(drawingId, d => d.structure.tree[objId]);
2619
+ const isHovered = react.useDrawing(drawingId, d => {
2620
+ var _d$interaction$hovere2;
2621
+ return ((_d$interaction$hovere2 = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere2.objectId) === objId;
2622
+ }) || false;
2623
+ const selection = react.useDrawing(drawingId, d => d.selection.refs[d.selection.active || '']);
2624
+ const isSelectable = (selection == null ? void 0 : selection.isSelectable(TreeObjScope, {
2625
+ object
2626
+ })) || false;
2627
+ return isSelectable && isHovered;
2413
2628
  }
2414
2629
 
2415
2630
  /**
@@ -2424,57 +2639,46 @@ function useHover$1(drawingId, objId) {
2424
2639
  * @param objId
2425
2640
  * @returns
2426
2641
  */
2427
- function useIsSelected$1(drawingId, objId) {
2428
- // Re-render if selectedItems is changed
2429
- const activeSelId = react.useDrawing(drawingId, d => d.selection.active);
2430
- const selectedItems = react.useDrawing(drawingId, d => {
2431
- var _d$selection$refs2;
2432
- return (_d$selection$refs2 = d.selection.refs[activeSelId || '']) == null ? void 0 : _d$selection$refs2.items;
2642
+ function useIsSSelected(drawingId, objId) {
2643
+ // Re-render if selItems is changed
2644
+ const selItems = react.useDrawing(drawingId, d => {
2645
+ var _d$selection$refs;
2646
+ return (_d$selection$refs = d.selection.refs[d.selection.active || '']) == null ? void 0 : _d$selection$refs.items;
2433
2647
  });
2434
2648
  const isSelected = React.useMemo(() => {
2435
- if (!selectedItems) return false;
2436
- const structure = core.getDrawing(drawingId).structure;
2437
- const productId = structure.currentProduct;
2438
- if (!productId) return false;
2439
- const object = structure.tree[objId];
2440
- const selApi = core.getDrawing(drawingId).api.selection;
2649
+ if (!selItems) {
2650
+ return false;
2651
+ }
2652
+ const drawing = core.getDrawing(drawingId);
2653
+ const productId = drawing.structure.currentProduct;
2654
+ if (!productId) {
2655
+ return false;
2656
+ }
2657
+ const object = drawing.structure.tree[objId];
2658
+ const selApi = drawing.api.selection;
2441
2659
  return selApi.isItemSelected(createTreeObjSelItem(productId, object));
2442
- }, [drawingId, objId, selectedItems]);
2660
+ }, [drawingId, objId, selItems]);
2443
2661
  return isSelected;
2444
2662
  }
2445
- function useTreeObjSelection(drawingId, objId) {
2446
- const activeSelId = react.useDrawing(drawingId, drawing => drawing.selection.active);
2447
- const isSelectableFunc = react.useDrawing(drawingId, d => {
2448
- var _d$selection$refs3;
2449
- return (_d$selection$refs3 = d.selection.refs[activeSelId || '']) == null ? void 0 : _d$selection$refs3.isSelectable;
2450
- });
2451
- const isSelectable = React.useMemo(() => {
2452
- if (!isSelectableFunc) return false;
2453
- const object = core.getDrawing(drawingId).structure.tree[objId];
2454
- const res = isSelectableFunc(TreeObjScope, {
2455
- object: object
2456
- });
2457
- return res;
2458
- }, [drawingId, objId, isSelectableFunc]);
2663
+ function useTreeObjInteraction(drawingId, objId) {
2459
2664
  const hHandlers = useHover$1(drawingId, objId);
2460
- const isHovered = useIsHovered$1(drawingId, objId);
2461
2665
  const sHandlers = useSelect$1(drawingId, objId);
2462
- const isSelected = useIsSelected$1(drawingId, objId);
2463
- const handlers = React.useMemo(() => {
2464
- if (isSelectable) {
2465
- return _objectSpread$p(_objectSpread$p({}, hHandlers), sHandlers);
2466
- }
2467
- return {};
2468
- }, [isSelectable, hHandlers, sHandlers]);
2666
+ const isGHovered = useIsGHovered(drawingId, objId);
2667
+ const isGSelected = useIsGSelected(drawingId, objId);
2668
+ const isSHovered = useIsSHovered(drawingId, objId);
2669
+ const isSSelected = useIsSSelected(drawingId, objId);
2670
+ const handlers = React.useMemo(() => _objectSpread$p(_objectSpread$p({}, hHandlers), sHandlers), [hHandlers, sHandlers]);
2469
2671
  return React.useMemo(() => {
2470
2672
  // If the handlers are switched off immediately after the selection (workplane selection for the sketcher), then hovered would keep being equal to true, making the mesh color wrong.
2471
2673
  // Thus, we don't want hovered and selected to be true if the object is not selectable.
2472
2674
  return {
2473
- isHovered: isHovered && isSelectable,
2474
- isSelected: isSelected && isSelectable,
2675
+ isGHovered,
2676
+ isGSelected,
2677
+ isSHovered,
2678
+ isSSelected,
2475
2679
  handlers
2476
2680
  };
2477
- }, [isHovered, isSelected, isSelectable, handlers]);
2681
+ }, [isGHovered, isSHovered, isGSelected, isSSelected, handlers]);
2478
2682
  }
2479
2683
 
2480
2684
  const pickGraphicId = itemData => itemData.graphicId;
@@ -6582,6 +6786,13 @@ const TmpAngularDim = props => {
6582
6786
  }));
6583
6787
  };
6584
6788
 
6789
+ const tolerance$4 = 1e-6;
6790
+
6791
+ /**
6792
+ * Allowed pixel offset for onClick handler events in case the pointer was slightly moved
6793
+ */
6794
+ const deltaTolerance = 4;
6795
+
6585
6796
  const getInitialState = () => {
6586
6797
  return {
6587
6798
  alwaysShowConstr: false,
@@ -6636,9 +6847,6 @@ const description$f = {
6636
6847
  initialState: getInitialState()
6637
6848
  };
6638
6849
 
6639
- // TODO: not realy the best file for const declaration.
6640
- const tolerance$3 = 1e-6;
6641
-
6642
6850
  function getSketchState(drawingId, pluginId) {
6643
6851
  const plugin = core.getPlugin(drawingId, pluginId);
6644
6852
  if (!plugin || plugin.name !== description$f.name) {
@@ -6685,8 +6893,6 @@ function CreateAngle(drawingId, pluginId) {
6685
6893
  // Local state:
6686
6894
  const tmpDimensionId = guid();
6687
6895
  let entities = [];
6688
- let isMoved = false;
6689
- let isPressed = false;
6690
6896
  const updateDimensionPreview = params => {
6691
6897
  set(state_ => {
6692
6898
  const tmpAngularDimension = state_.tmpObjects[tmpDimensionId];
@@ -6751,39 +6957,29 @@ function CreateAngle(drawingId, pluginId) {
6751
6957
  });
6752
6958
  }
6753
6959
  };
6754
-
6755
- // Pointer Handlers:
6756
- const onPointerDown = e => {
6757
- if (e.nativeEvent.buttons !== 1)
6758
- // Continue only if 'primary' mouse button is pressed
6960
+ const onClick = e => {
6961
+ if (e.delta > deltaTolerance) {
6962
+ // Continue only if the user hasn't moved mouse considerably.
6759
6963
  return;
6760
- isMoved = false;
6761
- isPressed = true;
6762
- e.stopPropagation();
6763
- };
6764
- const onPointerUp = e => {
6765
- if (!isMoved && isPressed) {
6766
- const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
6767
- const {
6768
- dir0,
6769
- dir1,
6770
- center,
6771
- dimPos,
6772
- reflex
6773
- } = tmpObjects[tmpDimensionId];
6774
- const sector = calcSector(dimPos, dir0, dir1, center);
6775
- const previewValue = calcPreviewValue(dir0, dir1, sector, reflex);
6776
- const degValue = radiansToDegrees(previewValue) + 'g';
6777
- classcad.ccAPI.sketcher.addConstraints(drawingId, sketchId, ['Ang'], [classcad.CCClasses.CC2DAngleConstraint], [entities], [degValue], [dimPos], [[sector, reflex]]).catch(console.warn);
6778
- isPressed = false;
6779
- set({
6780
- activeHandler: HandlersList.DRAG
6781
- });
6782
6964
  }
6965
+ const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
6966
+ const {
6967
+ dir0,
6968
+ dir1,
6969
+ center,
6970
+ dimPos,
6971
+ reflex
6972
+ } = tmpObjects[tmpDimensionId];
6973
+ const sector = calcSector(dimPos, dir0, dir1, center);
6974
+ const previewValue = calcPreviewValue(dir0, dir1, sector, reflex);
6975
+ const degValue = radiansToDegrees(previewValue) + 'g';
6976
+ classcad.ccAPI.sketcher.addConstraints(drawingId, sketchId, ['Ang'], [classcad.CCClasses.CC2DAngleConstraint], [entities], [degValue], [dimPos], [[sector, reflex]]).catch(console.warn);
6977
+ set({
6978
+ activeHandler: HandlersList.DRAG
6979
+ });
6783
6980
  e.stopPropagation();
6784
6981
  };
6785
6982
  const onPointerMove = e => {
6786
- isMoved = true;
6787
6983
  const dimPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
6788
6984
  updateDimensionPreview({
6789
6985
  dimPos
@@ -6796,9 +6992,8 @@ function CreateAngle(drawingId, pluginId) {
6796
6992
  onActivate,
6797
6993
  onDeactivate,
6798
6994
  pointerHandlers: {
6799
- onPointerDown,
6800
- onPointerUp,
6801
- onPointerMove
6995
+ onPointerMove,
6996
+ onClick
6802
6997
  },
6803
6998
  keyHandlers: {
6804
6999
  keydown,
@@ -7160,7 +7355,7 @@ const createArcMaterial = () => {
7160
7355
 
7161
7356
  // Max number of instances to be handled by Merged
7162
7357
  const limit = 10000;
7163
- const tolerance$2 = 1e-6;
7358
+ const tolerance$3 = 1e-6;
7164
7359
 
7165
7360
  // We need to create mesh instances which will be used later in Merged component.
7166
7361
  // InstancedMesh from three.js use the single mesh but applies different transformations to different instances of the mesh
@@ -7267,7 +7462,7 @@ const InstancedGeometry = ({
7267
7462
  const instances = arcMesh_.userData.instances;
7268
7463
  for (i = 0; i < instances.length; i++) {
7269
7464
  instanceRef = instances[i].current;
7270
- if (Math.abs(instanceRef.radius - radiusArr[i]) > tolerance$2) {
7465
+ if (Math.abs(instanceRef.radius - radiusArr[i]) > tolerance$3) {
7271
7466
  radiusArr[i] = instanceRef.radius;
7272
7467
  radiusAtt.needsUpdate = true;
7273
7468
  }
@@ -7275,7 +7470,7 @@ const InstancedGeometry = ({
7275
7470
  tubeRadiusArr[i] = instanceRef.tubeRadius;
7276
7471
  tubeRadiusAtt.needsUpdate = true;
7277
7472
  }
7278
- if (Math.abs(instanceRef.angularLength - angularLengthArr[i]) > tolerance$2) {
7473
+ if (Math.abs(instanceRef.angularLength - angularLengthArr[i]) > tolerance$3) {
7279
7474
  angularLengthArr[i] = instanceRef.angularLength;
7280
7475
  angularLengthAtt.needsUpdate = true;
7281
7476
  }
@@ -7572,7 +7767,7 @@ function Drag(drawingId, pluginId, camControls) {
7572
7767
  const snappedDiff = snapDraggedPoints(diff, drawingId);
7573
7768
  diff = snappedDiff || diff;
7574
7769
  const selected = getSketchState(drawingId, pluginId).selected;
7575
- if (diff.length() > tolerance$3) {
7770
+ if (diff.length() > tolerance$4) {
7576
7771
  if (promise) {
7577
7772
  // If we are waiting for the response from server, defer next diff and make it after current change.
7578
7773
  defferedDiff = diff;
@@ -7608,7 +7803,6 @@ function DrawPoint(drawingId, pluginId) {
7608
7803
 
7609
7804
  // Local state:
7610
7805
  const tmpPointId = guid();
7611
- let isMoved = false;
7612
7806
  const filter = object => {
7613
7807
  return object && classcad.ccUtils.base.isA(object.class, classcad.CCClasses.CCSketch);
7614
7808
  };
@@ -7631,32 +7825,24 @@ function DrawPoint(drawingId, pluginId) {
7631
7825
  mousePos: undefined
7632
7826
  });
7633
7827
  };
7634
-
7635
- // Pointer Handlers:
7636
- const onPointerDown = e => {
7637
- if (e.nativeEvent.buttons !== 1)
7638
- // Continue only if 'primary' mouse button is pressed
7828
+ const onClick = e => {
7829
+ if (e.delta > deltaTolerance) {
7830
+ // Continue only if the user hasn't moved mouse considerably.
7639
7831
  return;
7640
- isMoved = false;
7641
- e.stopPropagation();
7642
- };
7643
- const onPointerUp = e => {
7644
- if (!isMoved) {
7645
- const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
7646
- const pointPos = tmpObjects[tmpPointId].position.clone();
7647
- classcad.ccAPI.sketcher.addGeometry(drawingId, sketchId, 'Point', {
7648
- pos: pointPos
7649
- }, {
7650
- fixation: true,
7651
- incidence: true,
7652
- tangency: false,
7653
- vertAndHoriz: false
7654
- }).catch(console.warn);
7655
7832
  }
7833
+ const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
7834
+ const pointPos = tmpObjects[tmpPointId].position.clone();
7835
+ classcad.ccAPI.sketcher.addGeometry(drawingId, sketchId, 'Point', {
7836
+ pos: pointPos
7837
+ }, {
7838
+ fixation: true,
7839
+ incidence: true,
7840
+ tangency: false,
7841
+ vertAndHoriz: false
7842
+ }).catch(console.warn);
7656
7843
  e.stopPropagation();
7657
7844
  };
7658
7845
  const onPointerMove = e => {
7659
- isMoved = true;
7660
7846
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
7661
7847
  const snappedPos = snapPoint(localPos);
7662
7848
  const mousePos = snappedPos || localPos;
@@ -7679,9 +7865,8 @@ function DrawPoint(drawingId, pluginId) {
7679
7865
  onActivate,
7680
7866
  onDeactivate,
7681
7867
  pointerHandlers: {
7682
- onPointerDown,
7683
- onPointerUp,
7684
- onPointerMove
7868
+ onPointerMove,
7869
+ onClick
7685
7870
  }
7686
7871
  };
7687
7872
  }
@@ -7698,7 +7883,6 @@ function DrawLine(drawingId, pluginId) {
7698
7883
  // Local state:
7699
7884
  let firstPointIsSet = false;
7700
7885
  let lastAddedEndPointId = NOCCID;
7701
- let isMoved = false;
7702
7886
  let promise = null;
7703
7887
  const tmpStartPId = guid();
7704
7888
  const tmpEndPId = guid();
@@ -7744,17 +7928,11 @@ function DrawLine(drawingId, pluginId) {
7744
7928
  return false;
7745
7929
  }
7746
7930
  };
7747
- const onPointerDown = e => {
7748
- if (e.nativeEvent.buttons !== 1 || promise !== null)
7749
- // Continue only if 'primary' mouse button is pressed and we are not waiting for server response.
7750
- return;
7751
- isMoved = false;
7752
- e.stopPropagation();
7753
- };
7754
- const onPointerUp = e => {
7755
- if (isMoved || promise !== null)
7756
- // Continue only if user hasn't moved mouse and line adding is finished.
7931
+ const onClick = e => {
7932
+ if (e.delta > deltaTolerance || promise !== null) {
7933
+ // Continue only if the user hasn't moved mouse considerably, and adding the previous line is finished.
7757
7934
  return;
7935
+ }
7758
7936
  if (!firstPointIsSet) {
7759
7937
  set(state => {
7760
7938
  const tmpEndP = state.tmpObjects[tmpEndPId];
@@ -7824,7 +8002,6 @@ function DrawLine(drawingId, pluginId) {
7824
8002
  e.stopPropagation();
7825
8003
  };
7826
8004
  const onPointerMove = e => {
7827
- isMoved = true;
7828
8005
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
7829
8006
  const snappedPos = snapPoint(localPos);
7830
8007
  const mousePos = snappedPos || localPos;
@@ -7847,9 +8024,8 @@ function DrawLine(drawingId, pluginId) {
7847
8024
  onActivate,
7848
8025
  onDeactivate,
7849
8026
  pointerHandlers: {
7850
- onPointerDown,
7851
- onPointerUp,
7852
- onPointerMove
8027
+ onPointerMove,
8028
+ onClick
7853
8029
  },
7854
8030
  keyHandlers: {
7855
8031
  escape: escHandler
@@ -7867,8 +8043,7 @@ function DrawRectangle(drawingId, pluginId) {
7867
8043
 
7868
8044
  // Local state:
7869
8045
  let additionIndex = 0; // state of handler: 0 - drawing the first point, 1 - drawing tmp rectangle
7870
- let isMoved = false;
7871
- let isPressed = false;
8046
+
7872
8047
  const tmpRectId = guid();
7873
8048
  const tmpPointId = guid();
7874
8049
  const onActivate = () => {
@@ -7918,16 +8093,11 @@ function DrawRectangle(drawingId, pluginId) {
7918
8093
  return false;
7919
8094
  }
7920
8095
  };
7921
- const onPointerDown = e => {
7922
- if (e.nativeEvent.buttons !== 1)
7923
- // Continue only if 'primary' mouse button is pressed
8096
+ const onClick = e => {
8097
+ if (e.delta > deltaTolerance) {
8098
+ // Continue only if the user hasn't moved mouse considerably.
7924
8099
  return;
7925
- isMoved = false;
7926
- isPressed = true;
7927
- e.stopPropagation();
7928
- };
7929
- const onPointerUp = e => {
7930
- if (isMoved || !isPressed) return;
8100
+ }
7931
8101
  if (additionIndex === 0) {
7932
8102
  set(state => {
7933
8103
  const tmpPoint = state.tmpObjects[tmpPointId];
@@ -7988,11 +8158,9 @@ function DrawRectangle(drawingId, pluginId) {
7988
8158
  });
7989
8159
  additionIndex = 0;
7990
8160
  }
7991
- isPressed = false;
7992
8161
  e.stopPropagation();
7993
8162
  };
7994
8163
  const onPointerMove = e => {
7995
- isMoved = true;
7996
8164
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
7997
8165
  const snappedPos = snapPoint(localPos) || localPos;
7998
8166
  set(state => {
@@ -8064,9 +8232,8 @@ function DrawRectangle(drawingId, pluginId) {
8064
8232
  onActivate,
8065
8233
  onDeactivate,
8066
8234
  pointerHandlers: {
8067
- onPointerDown,
8068
- onPointerUp,
8069
- onPointerMove
8235
+ onPointerMove,
8236
+ onClick
8070
8237
  },
8071
8238
  keyHandlers: {
8072
8239
  escape: escHandler,
@@ -8247,7 +8414,6 @@ function DrawArc(drawingId, pluginId, arcType) {
8247
8414
  // Local state:
8248
8415
  let additionIndex = 0;
8249
8416
  let lastAddedEndPointId = NOCCID;
8250
- let isMoved = false;
8251
8417
  let tangent = new THREE__namespace.Vector3();
8252
8418
  let lastMousePos = new THREE__namespace.Vector3();
8253
8419
  let promise = null;
@@ -8325,13 +8491,6 @@ function DrawArc(drawingId, pluginId, arcType) {
8325
8491
  }
8326
8492
  return false;
8327
8493
  };
8328
- const onPointerDown = e => {
8329
- if (e.nativeEvent.buttons !== 1 || promise !== null)
8330
- // Continue only if 'primary' mouse button is pressed and we are not waiting for server response.
8331
- return;
8332
- isMoved = false;
8333
- e.stopPropagation();
8334
- };
8335
8494
  const calculateCenterPoint = (start, end, hint) => {
8336
8495
  if (arcType === HandlersList.DRAWARCCENTER) {
8337
8496
  const dir1 = end.clone().sub(start);
@@ -8348,7 +8507,7 @@ function DrawArc(drawingId, pluginId, arcType) {
8348
8507
  const v3 = new THREE__namespace.Vector3(length2End - length2Hint, length2Hint - length2Start, length2Start - length2End);
8349
8508
  const v4 = new THREE__namespace.Vector3(end.y - hint.y, hint.y - start.y, start.y - end.y);
8350
8509
  const denominator = v2.dot(v4);
8351
- if (Math.abs(denominator) < tolerance$3) {
8510
+ if (Math.abs(denominator) < tolerance$4) {
8352
8511
  return undefined;
8353
8512
  }
8354
8513
  const x = -0.5 * v1.dot(v3) / denominator;
@@ -8382,10 +8541,11 @@ function DrawArc(drawingId, pluginId, arcType) {
8382
8541
  }
8383
8542
  return false;
8384
8543
  };
8385
- const onPointerUp = e => {
8386
- if (isMoved || promise !== null)
8387
- // Continue only if user hasn't moved mouse and arc adding is finished.
8544
+ const onClick = e => {
8545
+ if (e.delta > deltaTolerance || promise !== null) {
8546
+ // Continue only if the user hasn't moved mouse considerably, and adding the previous arc is finished.
8388
8547
  return;
8548
+ }
8389
8549
  const tree = core.getDrawing(drawingId).structure.tree;
8390
8550
  const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
8391
8551
  if (additionIndex === 0) {
@@ -8395,7 +8555,7 @@ function DrawArc(drawingId, pluginId, arcType) {
8395
8555
  const startPos = tmpObjects[tmpStartPId].position.clone();
8396
8556
  const matchingPointIds = getDescendants(tree, sketch.id).filter(id => classcad.ccUtils.base.isA(tree[id].class, classcad.CCClasses.CCPoint) && (tree[id].name === 'startPoint' || tree[id].name === 'endPoint')).filter(id => {
8397
8557
  var _tree$id$members;
8398
- return convertToVector((_tree$id$members = tree[id].members) == null ? void 0 : _tree$id$members.pos).distanceToSquared(startPos) < tolerance$3;
8558
+ return convertToVector((_tree$id$members = tree[id].members) == null ? void 0 : _tree$id$members.pos).distanceToSquared(startPos) < tolerance$4;
8399
8559
  });
8400
8560
  if (matchingPointIds.length !== 1) {
8401
8561
  // TODO: Add some message for the user
@@ -8534,7 +8694,6 @@ function DrawArc(drawingId, pluginId, arcType) {
8534
8694
  e.stopPropagation();
8535
8695
  };
8536
8696
  const onPointerMove = e => {
8537
- isMoved = true;
8538
8697
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
8539
8698
  const snappedPos = snapPoint(localPos);
8540
8699
  lastMousePos = snappedPos || localPos;
@@ -8603,9 +8762,8 @@ function DrawArc(drawingId, pluginId, arcType) {
8603
8762
  onActivate,
8604
8763
  onDeactivate,
8605
8764
  pointerHandlers: {
8606
- onPointerDown,
8607
- onPointerUp,
8608
- onPointerMove
8765
+ onPointerMove,
8766
+ onClick
8609
8767
  },
8610
8768
  keyHandlers: {
8611
8769
  escape: escHandler
@@ -8623,7 +8781,6 @@ function DrawCircle(drawingId, pluginId) {
8623
8781
 
8624
8782
  // Local state:
8625
8783
  let additionIndex = 0;
8626
- let isMoved = false;
8627
8784
  let lastMousePos = new THREE__namespace.Vector3();
8628
8785
  const tmpCenterPId = guid();
8629
8786
  const tmpCircleId = guid();
@@ -8671,15 +8828,11 @@ function DrawCircle(drawingId, pluginId) {
8671
8828
  return false;
8672
8829
  }
8673
8830
  };
8674
- const onPointerDown = e => {
8675
- if (e.nativeEvent.buttons !== 1)
8676
- // Continue only if 'primary' mouse button is pressed
8831
+ const onClick = e => {
8832
+ if (e.delta > deltaTolerance) {
8833
+ // Continue only if the user hasn't moved mouse considerably.
8677
8834
  return;
8678
- isMoved = false;
8679
- e.stopPropagation();
8680
- };
8681
- const onPointerUp = e => {
8682
- if (isMoved) return;
8835
+ }
8683
8836
  if (additionIndex === 0) {
8684
8837
  set(state => {
8685
8838
  const tmpCenterP = state.tmpObjects[tmpCenterPId];
@@ -8725,7 +8878,6 @@ function DrawCircle(drawingId, pluginId) {
8725
8878
  e.stopPropagation();
8726
8879
  };
8727
8880
  const onPointerMove = e => {
8728
- isMoved = true;
8729
8881
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
8730
8882
  const snappedPos = snapPoint(localPos);
8731
8883
  lastMousePos = (snappedPos || localPos).clone();
@@ -8761,9 +8913,8 @@ function DrawCircle(drawingId, pluginId) {
8761
8913
  onActivate,
8762
8914
  onDeactivate,
8763
8915
  pointerHandlers: {
8764
- onPointerDown,
8765
- onPointerUp,
8766
- onPointerMove
8916
+ onPointerMove,
8917
+ onClick
8767
8918
  },
8768
8919
  keyHandlers: {
8769
8920
  escape: escHandler
@@ -9060,7 +9211,7 @@ const getOriginByPoint = (drawingId, pointId, objectIds) => {
9060
9211
  const object = tree[objectIds[i]];
9061
9212
  if (classcad.ccUtils.base.isA(object.class, classcad.CCClasses.CCPoint)) {
9062
9213
  var _object$members;
9063
- if (convertToVector((_object$members = object.members) == null ? void 0 : _object$members.pos).distanceToSquared(pointPos) < tolerance$3) {
9214
+ if (convertToVector((_object$members = object.members) == null ? void 0 : _object$members.pos).distanceToSquared(pointPos) < tolerance$4) {
9064
9215
  return {
9065
9216
  index: i
9066
9217
  };
@@ -9073,7 +9224,7 @@ const getOriginByPoint = (drawingId, pointId, objectIds) => {
9073
9224
  var _childPoint$members;
9074
9225
  const childPoint = childPoints.find(p => p.name === name);
9075
9226
  const pos = childPoint ? convertToVector((_childPoint$members = childPoint.members) == null ? void 0 : _childPoint$members.pos) : undefined;
9076
- return pos && pos.distanceToSquared(pointPos) < tolerance$3;
9227
+ return pos && pos.distanceToSquared(pointPos) < tolerance$4;
9077
9228
  });
9078
9229
  if (matchingPoint) {
9079
9230
  return {
@@ -10004,8 +10155,10 @@ const Constraints$2 = () => {
10004
10155
  width: size.width,
10005
10156
  sidepadding: size.sidePadding,
10006
10157
  iconmargin: size.iconMargin
10007
- }, sortedConstraints.map(constrClass => /*#__PURE__*/React.createElement(ConstrBtn, {
10008
- key: constrClass,
10158
+ }, sortedConstraints.map((constrClass, i) => /*#__PURE__*/React.createElement(ConstrBtn
10159
+ // Use index as key instead of constrClass for the same element to retain its position; This is needed for tooltip to behave correctly
10160
+ , {
10161
+ key: i,
10009
10162
  constrClass: constrClass,
10010
10163
  disabled: allowedConstraints.indexOf(constrClass) === -1
10011
10164
  })))));
@@ -10235,7 +10388,7 @@ function recognizeFilletByArc(object, tree, sketchId) {
10235
10388
 
10236
10389
  function ownKeys$c(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
10237
10390
  function _objectSpread$c(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys$c(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys$c(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
10238
- function Fillet(drawingId, pluginId, camControls) {
10391
+ function Fillet(drawingId, pluginId) {
10239
10392
  const plugin = core.getPlugin(drawingId, pluginId);
10240
10393
  const set = plugin.set;
10241
10394
  const sketchId = plugin.objectId;
@@ -10246,7 +10399,6 @@ function Fillet(drawingId, pluginId, camControls) {
10246
10399
  const tmpFilletPId = guid();
10247
10400
  const tmpLine1Id = guid();
10248
10401
  const tmpLine2Id = guid();
10249
- let isPressed = false;
10250
10402
  const filter = object => object && (classcad.ccUtils.base.isA(object.class, classcad.CCClasses.CCPoint) || classcad.ccUtils.base.isA(object.class, classcad.CCClasses.CCArc));
10251
10403
  const onDeactivate = () => {
10252
10404
  set({
@@ -10353,18 +10505,11 @@ function Fillet(drawingId, pluginId, camControls) {
10353
10505
  });
10354
10506
  e.stopPropagation();
10355
10507
  };
10356
- const onPointerDown = e => {
10357
- if (e.nativeEvent.buttons !== 1)
10358
- // Continue only if 'primary' mouse button is pressed
10508
+ const onClick = e => {
10509
+ if (e.delta > deltaTolerance) {
10510
+ // Continue only if the user hasn't moved mouse considerably.
10359
10511
  return;
10360
- isPressed = true;
10361
- camControls.enabled = false;
10362
- e.target.setPointerCapture(e.nativeEvent.pointerId);
10363
- e.stopPropagation();
10364
- };
10365
- const onPointerUp = e => {
10366
- if (!isPressed) return;
10367
- camControls.enabled = true;
10512
+ }
10368
10513
  const hoveredId = e.object.userData.objId;
10369
10514
  const tree = core.getDrawing(drawingId).structure.tree;
10370
10515
  const hoveredObject = tree[hoveredId];
@@ -10397,8 +10542,6 @@ function Fillet(drawingId, pluginId, camControls) {
10397
10542
  cursor: null
10398
10543
  });
10399
10544
  }
10400
- isPressed = false;
10401
- e.target.releasePointerCapture(e.nativeEvent.pointerId);
10402
10545
  e.stopPropagation();
10403
10546
  };
10404
10547
  return {
@@ -10408,8 +10551,7 @@ function Fillet(drawingId, pluginId, camControls) {
10408
10551
  pointerHandlers: {
10409
10552
  onPointerOver,
10410
10553
  onPointerOut,
10411
- onPointerDown,
10412
- onPointerUp
10554
+ onClick
10413
10555
  }
10414
10556
  };
10415
10557
  }
@@ -10454,6 +10596,10 @@ function Trim(drawingId, pluginId) {
10454
10596
  };
10455
10597
  const onClick = e => {
10456
10598
  var _tree2;
10599
+ if (e.delta > deltaTolerance) {
10600
+ // Continue only if the user hasn't moved mouse considerably.
10601
+ return;
10602
+ }
10457
10603
  const tree = core.getDrawing(drawingId).structure.tree;
10458
10604
  if (classcad.ccUtils.base.isA((_tree2 = tree[tree[e.object.userData.objId].parent || NOCCID]) == null ? void 0 : _tree2.class, classcad.CCClasses.CCContainer)) {
10459
10605
  classcad.ccAPI.sketcher.removeObjects(drawingId, sketchId, [e.object.userData.objId], false).catch(console.warn);
@@ -10535,12 +10681,16 @@ const useGeomParams = objId => {
10535
10681
  drawingId,
10536
10682
  pluginId
10537
10683
  } = React.useContext(ViewContext);
10684
+ // TODO: Rename lSelected / gSelected consts because it seems wrong to call sketch selection local and selector-selection global...
10685
+ const lHovered = useSketchState(drawingId, pluginId, state => state.hovered === objId);
10538
10686
  const lSelected = useSketchState(drawingId, pluginId, state => state.selected.indexOf(objId) !== -1);
10539
- // gSelected - true if object is selected in a global selection
10540
- const gSelected = useIsSelected$1(drawingId, objId);
10687
+ // gHovered - true if object is selector-hovered
10688
+ const gHovered = useIsSHovered(drawingId, objId);
10689
+ // gSelected - true if object is selector-selected
10690
+ const gSelected = useIsSSelected(drawingId, objId);
10541
10691
  const isSelected = lSelected || gSelected;
10692
+ const isHovered = lHovered || gHovered;
10542
10693
  const isHighlighted = useSketchState(drawingId, pluginId, state => state.highlighted.indexOf(objId) !== -1);
10543
- const isHovered = useSketchState(drawingId, pluginId, state => state.hovered === objId);
10544
10694
  const {
10545
10695
  renderOrder,
10546
10696
  offsetUnits
@@ -10637,7 +10787,7 @@ const getConstrColor = objState => {
10637
10787
  if (isHighlighted) return 0xbbecdd;
10638
10788
  return 0xdddddd;
10639
10789
  };
10640
- const getColor$1 = (object, objState) => {
10790
+ const getColor = (object, objState) => {
10641
10791
  const {
10642
10792
  isGHovered,
10643
10793
  isSketchActive,
@@ -10695,10 +10845,11 @@ const useColor = (objId, gHovered) => {
10695
10845
  isActive
10696
10846
  } = React.useContext(ViewContext);
10697
10847
 
10848
+ // TODO: Rename lSelected / gSelected consts because it seems wrong to call sketch selection local and selector-selection global...
10698
10849
  // Selected locally, in the sketcher.
10699
10850
  const lSelected = useSketchState(drawingId, pluginId, state => state.selected.indexOf(objId) !== -1);
10700
- // Globally selected by some of selection elements.
10701
- const gSelected = useIsSelected$1(drawingId, objId);
10851
+ // gSelected - true if object is selector-selected
10852
+ const gSelected = useIsSSelected(drawingId, objId);
10702
10853
  const isSelected = lSelected || gSelected;
10703
10854
  const isHighlighted = useSketchState(drawingId, pluginId, state => state.highlighted.indexOf(objId) !== -1);
10704
10855
  const isHovered = useSketchState(drawingId, pluginId, state => state.hovered === objId);
@@ -10708,7 +10859,7 @@ const useColor = (objId, gHovered) => {
10708
10859
  });
10709
10860
  const color = React.useMemo(() => {
10710
10861
  const object = core.getDrawing(drawingId).structure.tree[objId];
10711
- return getColor$1(object, {
10862
+ return getColor(object, {
10712
10863
  isSketchActive: isActive,
10713
10864
  isHighlighted,
10714
10865
  isHovered,
@@ -10749,11 +10900,11 @@ const defaultHandlers = {
10749
10900
  };
10750
10901
 
10751
10902
  const useHandlersAndColor = (drawingId, objId) => {
10752
- const activeSelection = react.useDrawing(drawingId, d => d.selection.active);
10753
- const globalSelection = useTreeObjSelection(drawingId, objId);
10903
+ const isSelActive = react.useDrawing(drawingId, d => d.selection.active);
10904
+ const treeObjInteraction = useTreeObjInteraction(drawingId, objId);
10754
10905
  const sketchPointerHandlers = useSketchHandlers(objId);
10755
- const pointerHandlers = activeSelection ? globalSelection.handlers : sketchPointerHandlers;
10756
- const color = useColor(objId, globalSelection.isHovered);
10906
+ const pointerHandlers = isSelActive ? treeObjInteraction.handlers : sketchPointerHandlers;
10907
+ const color = useColor(objId, treeObjInteraction.isSHovered);
10757
10908
  return React.useMemo(() => ({
10758
10909
  handlers: pointerHandlers || defaultHandlers,
10759
10910
  color
@@ -10772,7 +10923,7 @@ const HUD = ({
10772
10923
  gl.autoClear = false;
10773
10924
  gl.clearDepth();
10774
10925
  gl.render(virtualScene, camera);
10775
- }, 2);
10926
+ }, 3);
10776
10927
  return /*#__PURE__*/React.createElement(React.Fragment, null, fiber.createPortal( /*#__PURE__*/React.createElement("group", null, children), virtualScene));
10777
10928
  };
10778
10929
 
@@ -10934,7 +11085,7 @@ const Constraints$1 = props => {
10934
11085
  var _tree$pointId$members;
10935
11086
  return convertToArray((_tree$pointId$members = tree[pointId].members) == null ? void 0 : _tree$pointId$members.pos);
10936
11087
  }).reduce((sum, current) => [sum[0] + current[0], sum[1] + current[1], sum[2] + current[2]]).map(x => x / pointChildrenIds.length));
10937
- const suitableRow = constrRows.find(row => row.position.distanceTo(position) < tolerance$3);
11088
+ const suitableRow = constrRows.find(row => row.position.distanceTo(position) < tolerance$4);
10938
11089
  if (suitableRow) {
10939
11090
  suitableRow.constrIds.push(constraint.id);
10940
11091
  } else {
@@ -11644,7 +11795,7 @@ const SketchPlane = ({
11644
11795
  objId
11645
11796
  }
11646
11797
  })), /*#__PURE__*/React.createElement("gridHelper", {
11647
- args: [step * linesCount, linesCount, 0x000000, 0x888888],
11798
+ args: [step * linesCount, linesCount, 0x000000, 0x444444],
11648
11799
  "geometry-computeBoundingBox": zeroBounds,
11649
11800
  quaternion: planeQuaternion,
11650
11801
  onUpdate: update
@@ -11664,7 +11815,10 @@ const Sketch = ({
11664
11815
  } = core.getPlugin(drawingId, pluginId);
11665
11816
  const containerIds = React.useMemo(() => {
11666
11817
  const tree = core.getDrawing(drawingId).structure.tree;
11667
- return sketch.children && sketch.children.filter(id => classcad.ccUtils.base.isA(tree[id].class, classcad.CCClasses.CCContainer));
11818
+ // Not using ccUtils.isA here because sketch may contain other containers, CCUseSet in particular.
11819
+ // Since trim geometry is recognized as CCContainer's children, it is crucial for now to make a direct class check.
11820
+ // TODO: Change how this is handled on the serverside. For example, by using a unique class for trim container.
11821
+ return sketch.children && sketch.children.filter(id => tree[id].class === classcad.CCClasses.CCContainer);
11668
11822
  }, [sketch.children, drawingId]);
11669
11823
  const drawnObjects = React.useMemo(() => {
11670
11824
  let res = [];
@@ -12009,7 +12163,11 @@ const RubberBandRectangle = () => {
12009
12163
  // TODO: handle font in some other way?
12010
12164
  const notoSansFont = 'https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5TRG.woff';
12011
12165
  const characters = '0123456789-,.';
12012
- const pos = new THREE__namespace.Vector3();
12166
+ const quat = new THREE__namespace.Quaternion();
12167
+ const textMaterial = new THREE__namespace.MeshBasicMaterial({
12168
+ depthTest: false,
12169
+ depthWrite: false
12170
+ });
12013
12171
  const MousePosition = () => {
12014
12172
  const {
12015
12173
  drawingId,
@@ -12019,16 +12177,15 @@ const MousePosition = () => {
12019
12177
  const sketchId = react.usePlugin(drawingId, pluginId, p => p.objectId);
12020
12178
  const mousePos = useSketchState(drawingId, pluginId, state => state.mousePos);
12021
12179
  fiber.useFrame(args => {
12022
- if (!ref.current || !mousePos || !sketchId) {
12180
+ if (!ref.current || !ref.current.parent || !mousePos || !sketchId) {
12023
12181
  return;
12024
12182
  }
12025
- pos.copy(mousePos).applyMatrix4(core.getDrawing(drawingId).api.structure.calculateGlobalTransformation(sketchId));
12026
12183
  const scale = getScale(drawingId, pluginId);
12027
- ref.current.position.set(pos.x, pos.y, pos.z);
12028
- ref.current.quaternion.copy(args.camera.quaternion);
12184
+ ref.current.position.set(mousePos.x, mousePos.y, mousePos.z);
12185
+ ref.current.quaternion.copy(ref.current.parent.getWorldQuaternion(quat)).invert().multiply(args.camera.quaternion);
12029
12186
  ref.current.scale.setScalar(scale);
12030
12187
  });
12031
- return mousePos ? /*#__PURE__*/React.createElement(HUD, null, /*#__PURE__*/React.createElement(React.Suspense, {
12188
+ return mousePos ? /*#__PURE__*/React.createElement(React.Suspense, {
12032
12189
  fallback: null
12033
12190
  }, /*#__PURE__*/React.createElement(drei.Text, {
12034
12191
  ref: ref,
@@ -12038,8 +12195,10 @@ const MousePosition = () => {
12038
12195
  letterSpacing: 0.05,
12039
12196
  anchorX: -3,
12040
12197
  anchorY: 4,
12041
- characters: characters
12042
- }, `${mousePos.x.toFixed(2)}, ${mousePos.y.toFixed(2)}`))) : null;
12198
+ characters: characters,
12199
+ renderOrder: 3001,
12200
+ material: textMaterial
12201
+ }, `${mousePos.x.toFixed(2)}, ${mousePos.y.toFixed(2)}`)) : null;
12043
12202
  };
12044
12203
 
12045
12204
  function useSetScale(drawingId, pluginId) {
@@ -12048,7 +12207,7 @@ function useSetScale(drawingId, pluginId) {
12048
12207
  if (!plugin) return;
12049
12208
  const state = plugin.state;
12050
12209
  const sketchObj = core.getDrawing(drawingId).structure.tree[plugin.objectId];
12051
- const sketchMatrix = core.MathUtils.convertToMatrix4(sketchObj.coordinateSystem);
12210
+ const sketchMatrix = sketchObj.coordinateSystem ? core.MathUtils.convertToMatrix4(sketchObj.coordinateSystem) : new THREE__namespace.Matrix4();
12052
12211
  const sketchOriginGlobal = new THREE__namespace.Vector3(0.0, 0.0, 0.0).applyMatrix4(sketchMatrix);
12053
12212
  const approxScale = react.CameraHelper.calculateScaleFactor(sketchOriginGlobal, 7, args.camera, args.size);
12054
12213
  const newStep = Math.pow(10.0, Math.floor(Math.log10(approxScale * 30) + 1e-3));
@@ -12220,17 +12379,17 @@ const DrawingMode = ({
12220
12379
  const plane = core.getDrawing(drawingId).structure.tree[planeRef];
12221
12380
  const normal = convertToVector(plane == null ? void 0 : (_plane$members = plane.members) == null ? void 0 : _plane$members.Normal);
12222
12381
  const csys = core.getDrawing(drawingId).structure.tree[sketchId].coordinateSystem;
12223
- const transformMatrix = core.MathUtils.convertToMatrix3(csys);
12382
+ const transformMatrix = csys ? core.MathUtils.convertToMatrix3(csys) : new THREE__namespace.Matrix3();
12224
12383
  const upVector = new THREE__namespace.Vector3(0, 1, 0).applyMatrix3(transformMatrix).normalize();
12225
12384
 
12226
12385
  // If box.min === box.max add (1,1,0) to box.max to make box not empty
12227
12386
  const box = bounds.box;
12228
- if (box.min.distanceTo(box.max) < tolerance$3) {
12387
+ if (box.min.distanceTo(box.max) < tolerance$4) {
12229
12388
  box.set(box.min, box.min.clone().add(new THREE__namespace.Vector3(1000, 1000, 1000)));
12230
12389
  }
12231
12390
 
12232
12391
  // Convert local box coordinates to global
12233
- const matrix4 = core.MathUtils.convertToMatrix4(csys);
12392
+ const matrix4 = csys ? core.MathUtils.convertToMatrix4(csys) : new THREE__namespace.Matrix4();
12234
12393
  const globCenter = bounds.center.clone().applyMatrix4(matrix4);
12235
12394
  const globBox = box.clone().applyMatrix4(matrix4);
12236
12395
  camera.position.copy(globCenter.clone().addScaledVector(normal, (bounds.radius || 1) * 100 * 2));
@@ -12246,7 +12405,7 @@ const DrawingMode = ({
12246
12405
  boundsControls == null ? void 0 : boundsControls.refresh().fit();
12247
12406
  };
12248
12407
  // eslint-disable-next-line react-hooks/exhaustive-deps
12249
- }, [boundsMember]);
12408
+ }, []);
12250
12409
 
12251
12410
  // Add handlers to pluginState when sketcher is enabled
12252
12411
  React.useEffect(() => {
@@ -13172,13 +13331,13 @@ const ObjTitle = ({
13172
13331
  return (_d$structure$tree$obj2 = d.structure.tree[objId]) == null ? void 0 : _d$structure$tree$obj2.class;
13173
13332
  });
13174
13333
  const activeHandler = useSketchState(drawingId, pluginId, state => state.activeHandler);
13175
- const globalSelection = useTreeObjSelection(drawingId, objId);
13176
- const isGHovered = globalSelection.isHovered;
13177
- const isGSelected = globalSelection.isSelected;
13178
- const onClickSel = globalSelection.handlers.onClick;
13334
+ const treeObjInteraction = useTreeObjInteraction(drawingId, objId);
13335
+ const isSHovered = treeObjInteraction.isSHovered;
13336
+ const isSSelected = treeObjInteraction.isSSelected;
13337
+ const onClickSel = treeObjInteraction.handlers.onClick;
13179
13338
  const isHovered = useSketchState(drawingId, pluginId, s => s.hovered === objId);
13180
13339
  const isSelected = useSketchState(drawingId, pluginId, s => s.selected.indexOf(objId) !== -1);
13181
- const color = isSelected || isGSelected ? '#ffa500' : isHovered || isGHovered ? '#28d79f' : undefined;
13340
+ const color = isSelected || isSSelected ? '#ffa500' : isHovered || isSHovered ? '#28d79f' : undefined;
13182
13341
 
13183
13342
  // TODO: Rename resources so that they have more generic names, i.e. 'CC_Point' instead of 'drawPoint', etc
13184
13343
  const imgName = React.useMemo(() => {
@@ -13323,7 +13482,7 @@ const Details = () => {
13323
13482
  const refGeometry_ = ccUseGeometry.map(member => [member.members[0].value, member.members[1].value]) || [];
13324
13483
  const geometry_ = (sketchChildren == null ? void 0 : sketchChildren.filter(id => isSketchGeometry(tree[id].class) && refGeometry_.findIndex(refArr => refArr[0] === id) === -1)) || [];
13325
13484
  const constraints_ = (sketchChildren == null ? void 0 : sketchChildren.filter(id => is2DConstraint(tree[id].class))) || [];
13326
- const isTrimActive_ = (sketchChildren == null ? void 0 : sketchChildren.findIndex(id => classcad.ccUtils.base.isA(tree[id].class, classcad.CCClasses.CCContainer))) !== -1;
13485
+ const isTrimActive_ = (sketchChildren == null ? void 0 : sketchChildren.findIndex(id => tree[id].class === classcad.CCClasses.CCContainer)) !== -1;
13327
13486
  return {
13328
13487
  refGeometry: refGeometry_,
13329
13488
  geometry: geometry_,
@@ -13964,8 +14123,7 @@ var index$f = /*#__PURE__*/Object.freeze({
13964
14123
  __proto__: null,
13965
14124
  Root: Root$f,
13966
14125
  View: View$d,
13967
- description: description$f,
13968
- tolerance: tolerance$3
14126
+ description: description$f
13969
14127
  });
13970
14128
 
13971
14129
  function useRefsReset(type, refs) {
@@ -14152,16 +14310,29 @@ const WorkAxisObj = ({
14152
14310
  }));
14153
14311
  };
14154
14312
 
14155
- function getColor(hovered, selected, direction, type) {
14156
- if (hovered) {
14157
- return 0x28d79f;
14158
- } else if (selected) {
14159
- return 0xa70b0b;
14160
- } else if (direction.distanceTo(new THREE__namespace.Vector3(1, 0, 0)) < tolerance$3 && type === classcad.WorkAxisType.WA_FIXED) {
14313
+ const getHighlightedColor = (isGHovered, isGSelected, isSHovered, isSSelected) => {
14314
+ if (isSHovered) {
14315
+ return '#3280ff';
14316
+ }
14317
+ if (isSSelected) {
14318
+ return '#8040c0';
14319
+ }
14320
+ if (isGHovered) {
14321
+ return 'green';
14322
+ }
14323
+ if (isGSelected) {
14324
+ return 'red';
14325
+ }
14326
+ return undefined;
14327
+ };
14328
+
14329
+ const tolerance$2 = 1e-6;
14330
+ function getBaseColor(direction, type) {
14331
+ if (direction.distanceTo(new THREE__namespace.Vector3(1, 0, 0)) < tolerance$2 && type === classcad.WorkAxisType.WA_FIXED) {
14161
14332
  return 0xd52828;
14162
- } else if (direction.distanceTo(new THREE__namespace.Vector3(0, 1, 0)) < tolerance$3 && type === classcad.WorkAxisType.WA_FIXED) {
14333
+ } else if (direction.distanceTo(new THREE__namespace.Vector3(0, 1, 0)) < tolerance$2 && type === classcad.WorkAxisType.WA_FIXED) {
14163
14334
  return 0x28a628;
14164
- } else if (direction.distanceTo(new THREE__namespace.Vector3(0, 0, 1)) < tolerance$3 && type === classcad.WorkAxisType.WA_FIXED) {
14335
+ } else if (direction.distanceTo(new THREE__namespace.Vector3(0, 0, 1)) < tolerance$2 && type === classcad.WorkAxisType.WA_FIXED) {
14165
14336
  return 0x2828d7;
14166
14337
  } else {
14167
14338
  return 0x111111;
@@ -14178,11 +14349,13 @@ const ViewImpl$c = ({
14178
14349
  const workAxisObj = react.useDrawing(drawingId, drawing => drawing.structure.tree[objectId]);
14179
14350
  const direction = convertToVector(workAxisObj == null ? void 0 : (_workAxisObj$members = workAxisObj.members) == null ? void 0 : _workAxisObj$members.Direction);
14180
14351
  const {
14181
- isHovered,
14182
- isSelected,
14352
+ isGHovered,
14353
+ isGSelected,
14354
+ isSHovered,
14355
+ isSSelected,
14183
14356
  handlers
14184
- } = useTreeObjSelection(drawingId, objectId);
14185
- const color = getColor(isHovered, isSelected, direction, workAxisObj == null ? void 0 : (_workAxisObj$members2 = workAxisObj.members) == null ? void 0 : _workAxisObj$members2.Type.value);
14357
+ } = useTreeObjInteraction(drawingId, objectId);
14358
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected) || getBaseColor(direction, workAxisObj == null ? void 0 : (_workAxisObj$members2 = workAxisObj.members) == null ? void 0 : _workAxisObj$members2.Type.value);
14186
14359
  return /*#__PURE__*/React.createElement(HUD, null, /*#__PURE__*/React.createElement(WorkAxisObj, {
14187
14360
  drawingId: drawingId,
14188
14361
  objectId: objectId,
@@ -14553,18 +14726,27 @@ const ViewImpl$b = ({
14553
14726
  objectId = -1
14554
14727
  } = core.getPlugin(drawingId, pluginId);
14555
14728
  const {
14556
- isHovered,
14557
- isSelected,
14729
+ isGHovered,
14730
+ isGSelected,
14731
+ isSHovered,
14732
+ isSSelected,
14558
14733
  handlers
14559
- } = useTreeObjSelection(drawingId, objectId);
14560
- const color = isHovered ? 0x18b77f : isSelected ? 0xa70b0b : 0x34424f;
14561
- return /*#__PURE__*/React.createElement(WorkPlaneObj, {
14734
+ } = useTreeObjInteraction(drawingId, objectId);
14735
+ const isHighlighted = isGHovered || isGSelected || isSHovered || isSSelected;
14736
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected) || 0x34424f;
14737
+ return /*#__PURE__*/React.createElement(React.Fragment, null, !isHighlighted && /*#__PURE__*/React.createElement(WorkPlaneObj, {
14562
14738
  drawingId: drawingId,
14563
14739
  objectId: objectId,
14564
14740
  color: color,
14565
14741
  opacity: 0.5,
14566
14742
  handlers: handlers
14567
- });
14743
+ }), isHighlighted && /*#__PURE__*/React.createElement(HUD, null, /*#__PURE__*/React.createElement(WorkPlaneObj, {
14744
+ drawingId: drawingId,
14745
+ objectId: objectId,
14746
+ color: color,
14747
+ opacity: 0.3,
14748
+ handlers: handlers
14749
+ })));
14568
14750
  };
14569
14751
  const View$b = ({
14570
14752
  drawingId,
@@ -14746,11 +14928,13 @@ const ViewImpl$a = ({
14746
14928
  objectId = -1
14747
14929
  } = core.getPlugin(drawingId, pluginId);
14748
14930
  const {
14749
- isHovered,
14750
- isSelected,
14931
+ isGHovered,
14932
+ isGSelected,
14933
+ isSHovered,
14934
+ isSSelected,
14751
14935
  handlers
14752
- } = useTreeObjSelection(drawingId, objectId);
14753
- const color = isHovered ? 0x28d79f : isSelected ? 0xa70b0b : 0x111111;
14936
+ } = useTreeObjInteraction(drawingId, objectId);
14937
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected) || 0x111111;
14754
14938
  return /*#__PURE__*/React.createElement(HUD, null, /*#__PURE__*/React.createElement(WorkPointObj, {
14755
14939
  drawingId: drawingId,
14756
14940
  objectId: objectId,
@@ -14906,12 +15090,11 @@ function createCSysParam(coordSystem) {
14906
15090
  return value;
14907
15091
  }
14908
15092
  function useCSysParam(drawingId, objId) {
14909
- // TODO: Fix lint error without disabling it
14910
- // eslint-disable-next-line react-hooks/exhaustive-deps
14911
- const coordSystem = react.useDrawing(drawingId, d => {
15093
+ const objCsys = react.useDrawing(drawingId, d => {
14912
15094
  var _d$structure$tree$obj;
14913
15095
  return (_d$structure$tree$obj = d.structure.tree[objId]) == null ? void 0 : _d$structure$tree$obj.coordinateSystem;
14914
- }) || [[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]];
15096
+ });
15097
+ const coordSystem = React.useMemo(() => objCsys || core.MathUtils.convertToCoordinateSystem(new THREE.Matrix4()), [objCsys]);
14915
15098
  const [userValue, setUserValue] = React.useState(createCSysParam(coordSystem));
14916
15099
  React.useEffect(() => {
14917
15100
  setUserValue(createCSysParam(coordSystem));
@@ -14948,7 +15131,7 @@ const typeCaptions = {
14948
15131
  [classcad.WorkCoordSystemType.WCS_XYAXISORIGIN]: 'Set'
14949
15132
  };
14950
15133
  const tolerance$1 = 1e-6;
14951
- const getObjectPosition = obj => {
15134
+ const getObjectPosition = (drawingId, obj) => {
14952
15135
  if (obj.position) {
14953
15136
  return obj.position.clone();
14954
15137
  }
@@ -14956,14 +15139,18 @@ const getObjectPosition = obj => {
14956
15139
  return obj.center.clone();
14957
15140
  }
14958
15141
  const members = obj.members;
14959
- return convertToVector((members == null ? void 0 : members.Position) || (members == null ? void 0 : members.pos));
15142
+ const pos = convertToVector((members == null ? void 0 : members.Position) || (members == null ? void 0 : members.pos));
15143
+ const matrix = core.getDrawing(drawingId).api.structure.calculateGlobalTransformation(obj.id);
15144
+ return pos.applyMatrix4(matrix);
14960
15145
  };
14961
- const getObjectDirection = obj => {
15146
+ const getObjectDirection = (drawingId, obj) => {
14962
15147
  if (obj.end) {
14963
15148
  return obj.end.clone().sub(obj.start).normalize();
14964
15149
  }
14965
15150
  const members = obj.members;
14966
- return convertToVector((members == null ? void 0 : members.Direction) || (members == null ? void 0 : members.direction)).normalize();
15151
+ const dir = convertToVector((members == null ? void 0 : members.Direction) || (members == null ? void 0 : members.direction)).normalize();
15152
+ const matrix = core.getDrawing(drawingId).api.structure.calculateGlobalTransformation(obj.id);
15153
+ return dir.applyMatrix4(matrix).normalize();
14967
15154
  };
14968
15155
  function RootImpl$b({
14969
15156
  drawingId,
@@ -15025,7 +15212,7 @@ function RootImpl$b({
15025
15212
  });
15026
15213
  return;
15027
15214
  }
15028
- originPos = getObjectPosition(origin);
15215
+ originPos = getObjectPosition(drawingId, origin);
15029
15216
  } else {
15030
15217
  originPos = new THREE__namespace.Vector3(csys.userValue[CSysRows.Position].x, csys.userValue[CSysRows.Position].y, csys.userValue[CSysRows.Position].z);
15031
15218
  }
@@ -15046,7 +15233,7 @@ function RootImpl$b({
15046
15233
  });
15047
15234
  return;
15048
15235
  }
15049
- xDir = getObjectDirection(primaryAxis);
15236
+ xDir = getObjectDirection(drawingId, primaryAxis);
15050
15237
  } else {
15051
15238
  xDir = new THREE__namespace.Vector3(csys.userValue[CSysRows.XAxis].x, csys.userValue[CSysRows.XAxis].y, csys.userValue[CSysRows.XAxis].z);
15052
15239
  }
@@ -15067,7 +15254,7 @@ function RootImpl$b({
15067
15254
  });
15068
15255
  return;
15069
15256
  }
15070
- yDir = getObjectDirection(secondaryAxis);
15257
+ yDir = getObjectDirection(drawingId, secondaryAxis);
15071
15258
  } else {
15072
15259
  yDir = new THREE__namespace.Vector3(csys.userValue[CSysRows.YAxis].x, csys.userValue[CSysRows.YAxis].y, csys.userValue[CSysRows.YAxis].z);
15073
15260
  }
@@ -15292,14 +15479,16 @@ function ViewImpl$9({
15292
15479
  return calcluateTransform(originPos_, xDir_, yDir_, offset, rotation, inverted);
15293
15480
  }, [originPos, xDir, yDir, offset, rotation, inverted]);
15294
15481
  const {
15295
- isHovered,
15296
- isSelected,
15482
+ isGHovered,
15483
+ isGSelected,
15484
+ isSHovered,
15485
+ isSSelected,
15297
15486
  handlers
15298
- } = useTreeObjSelection(drawingId, objectId);
15487
+ } = useTreeObjInteraction(drawingId, objectId);
15299
15488
 
15300
15489
  // This color is used only for the hovered and selected state,
15301
15490
  // undefined means default color which defined in Csys component.
15302
- const color = isHovered ? 0x28d79f : isSelected ? 0xa70b0b : undefined;
15491
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected);
15303
15492
  return /*#__PURE__*/React.createElement(HUD, null, /*#__PURE__*/React.createElement("group", null, /*#__PURE__*/React.createElement(WorkCoordSystemObj, {
15304
15493
  drawingId: drawingId,
15305
15494
  objectId: objectId,
@@ -16277,6 +16466,7 @@ const CSysWrapper = ({
16277
16466
  } = userData;
16278
16467
  const currentNode = react.useDrawing(drawingId, drawing => drawing.structure.currentNode);
16279
16468
  const matrix = useCsysMatrix(drawingId, csysId, flip, reoriented);
16469
+ const activeColor = getHighlightedColor(false, false, false, true);
16280
16470
  const onPointerMove_ = React.useCallback(() => onPointerMove && onPointerMove(csysId, matePath), [onPointerMove, matePath, csysId]);
16281
16471
  const onPointerOut_ = React.useCallback(() => onPointerOut && onPointerOut(csysId, matePath), [onPointerOut, matePath, csysId]);
16282
16472
  return /*#__PURE__*/React.createElement(react.GlobalTransform, {
@@ -16287,7 +16477,7 @@ const CSysWrapper = ({
16287
16477
  matePath: matePath
16288
16478
  }, isSelected ? /*#__PURE__*/React.createElement(SelectedCsys, {
16289
16479
  matrix: matrix,
16290
- color: isActive ? 0xa70b0b : undefined,
16480
+ color: isActive ? activeColor : undefined,
16291
16481
  opacity: 1.0,
16292
16482
  userData: userData
16293
16483
  }) : /*#__PURE__*/React.createElement("group", {
@@ -16366,12 +16556,15 @@ const CSysDisplayImpl = ({
16366
16556
  }) => {
16367
16557
  // If we are in part mode, the products array contains the id of the CC_Part and no product references!
16368
16558
  // TODO: Split the products array into `products` and `productRefs` in the drawing state.
16369
- const currentNode = react.useDrawing(drawingId, drawing => drawing.structure.currentNode);
16370
- const rigidSets = react.useDrawing(drawingId, drawing => currentNode && drawing.structure.tree[currentNode].children);
16559
+ const currentNode = useDrawingCCId(drawingId, drawing => drawing.structure.currentNode);
16560
+ const rigidSets = useDrawingArr(drawingId, drawing => drawing.structure.tree[currentNode].children);
16371
16561
  const productIds = react.useDrawing(drawingId, drawing => drawing.structure.products);
16372
16562
  const selectors = react.useDrawing(drawingId, drawing => drawing.selection.refs);
16373
16563
  const activeSelector = react.useDrawing(drawingId, drawing => drawing.selection.active && drawing.selection.refs[drawing.selection.active]);
16374
- const [hoveredProductId, setHoveredProductId] = React.useState(undefined);
16564
+ const hoveredId = react.useDrawing(drawingId, drawing => {
16565
+ var _drawing$interaction$;
16566
+ return (_drawing$interaction$ = drawing.interaction.hovered) == null ? void 0 : _drawing$interaction$.prodRefId;
16567
+ }) || undefined;
16375
16568
  const [hoveredProductIds, setHoveredProductIds] = React.useState([]);
16376
16569
  const prevHoveredIdRef = React.useRef(undefined);
16377
16570
  const displayTimers = React.useRef({});
@@ -16392,21 +16585,21 @@ const CSysDisplayImpl = ({
16392
16585
  const timerKey = prevHoveredId.toString();
16393
16586
  displayTimers.current[timerKey] = timerId;
16394
16587
  }
16395
- prevHoveredIdRef.current = hoveredProductId;
16396
- if (hoveredProductId !== undefined) {
16588
+ prevHoveredIdRef.current = hoveredId;
16589
+ if (hoveredId !== undefined) {
16397
16590
  setHoveredProductIds(hoveredProductIds_ => {
16398
- if (hoveredProductIds_.indexOf(hoveredProductId) !== -1) {
16591
+ if (hoveredProductIds_.indexOf(hoveredId) !== -1) {
16399
16592
  return hoveredProductIds_;
16400
16593
  }
16401
- return [...hoveredProductIds_, hoveredProductId];
16594
+ return [...hoveredProductIds_, hoveredId];
16402
16595
  });
16403
- const timerKey = `${hoveredProductId}`;
16596
+ const timerKey = `${hoveredId}`;
16404
16597
  if (displayTimers.current[timerKey]) {
16405
16598
  window.clearTimeout(displayTimers.current[timerKey]);
16406
16599
  displayTimers.current[timerKey] = undefined;
16407
16600
  }
16408
16601
  }
16409
- }, [hoveredProductId]);
16602
+ }, [hoveredId]);
16410
16603
  const [hoveredCSysIds, setHoveredCSysIds] = React.useState([]);
16411
16604
  const onPointerMove = React.useCallback((csysId, matePath) => {
16412
16605
  setHoveredCSysIds(hoveredCSysIds_ => {
@@ -16449,13 +16642,17 @@ const CSysDisplayImpl = ({
16449
16642
  const activeSelItems = React.useMemo(() => {
16450
16643
  return activeSelector ? activeSelector.items.filter(item => item.scope === MateScope) : [];
16451
16644
  }, [activeSelector]);
16452
- const selRigidSets = React.useMemo(() => {
16645
+ const inactiveSelRS = React.useMemo(() => {
16453
16646
  return selItems.map(item => {
16647
+ if (activeSelItems.indexOf(item) !== -1) {
16648
+ // Obviously, if item is active, it (and it's rigidset) is not inactive. So it should be excluded from the array...
16649
+ return undefined;
16650
+ }
16454
16651
  const activeRefId = getActiveReference(drawingId, item.data.matePath, activeProducts);
16455
16652
  const rigidSet = activeRefId && rigidSets && getProductRigidSet(drawingId, activeRefId, rigidSets);
16456
16653
  return rigidSet;
16457
- });
16458
- }, [drawingId, activeProducts, rigidSets, selItems]);
16654
+ }).filter(id => id);
16655
+ }, [drawingId, activeProducts, rigidSets, selItems, activeSelItems]);
16459
16656
  const csysUDataArray = React.useMemo(() => {
16460
16657
  const csysUDataArray_ = [];
16461
16658
  const prToCsysMap = {};
@@ -16478,11 +16675,15 @@ const CSysDisplayImpl = ({
16478
16675
  onHUD: true
16479
16676
  });
16480
16677
  });
16678
+ if (hoveredOnly && !activeSelector) {
16679
+ // In hoveredOnly mode, only display inactive selected mates if no selector is active
16680
+ return csysUDataArray_;
16681
+ }
16481
16682
  const ids = hoveredOnly ? hoveredProductIds : activeProducts;
16482
16683
  ids == null ? void 0 : ids.forEach(id => {
16483
16684
  var _tree$id, _tree$id$members, _tree$id$members$prod, _tree$id2;
16484
- const rigidSet = rigidSets && getProductRigidSet(drawingId, id, rigidSets);
16485
- if (selRigidSets.indexOf(rigidSet) !== -1) {
16685
+ const rigidSet = getProductRigidSet(drawingId, id, rigidSets);
16686
+ if (rigidSet && inactiveSelRS.indexOf(rigidSet) !== -1) {
16486
16687
  return;
16487
16688
  }
16488
16689
  const matePath = getMatePath(drawingId, id);
@@ -16516,35 +16717,8 @@ const CSysDisplayImpl = ({
16516
16717
  });
16517
16718
  }
16518
16719
  return csysUDataArray_;
16519
- }, [drawingId, hoveredOnly, activeProducts, hoveredProductIds, hoveredCSysIds, selItems, activeSelItems, rigidSets, selRigidSets]);
16520
- const lnTh = fiber.useThree(state => {
16521
- var _state$raycaster$para;
16522
- return (_state$raycaster$para = state.raycaster.params.Line) == null ? void 0 : _state$raycaster$para.threshold;
16523
- });
16524
- const ptsTh = fiber.useThree(state => {
16525
- var _state$raycaster$para2;
16526
- return (_state$raycaster$para2 = state.raycaster.params.Points) == null ? void 0 : _state$raycaster$para2.threshold;
16527
- });
16528
- const {
16529
- camera,
16530
- size
16531
- } = fiber.useThree();
16532
- const {
16533
- lineThreshold,
16534
- pointThreshold
16535
- } = React.useMemo(() => {
16536
- return {
16537
- lineThreshold: lnTh || react.CameraHelper.calculateScaleFactor(camera.position, 4, camera, size),
16538
- pointThreshold: ptsTh || react.CameraHelper.calculateScaleFactor(camera.position, 6, camera, size)
16539
- };
16540
- }, [camera, size, lnTh, ptsTh]);
16541
- const onInfiniteMove = React.useCallback(e => {
16542
- const geom = react.findBuerliGeometry(e, lineThreshold, pointThreshold)[0];
16543
- setHoveredProductId(geom == null ? void 0 : geom.productId);
16544
- }, [setHoveredProductId, lineThreshold, pointThreshold]);
16545
- return /*#__PURE__*/React.createElement(HUD, null, /*#__PURE__*/React.createElement("infinityPlane", {
16546
- onPointerMove: onInfiniteMove
16547
- }), /*#__PURE__*/React.createElement("group", null, csysUDataArray.map(userData => /*#__PURE__*/React.createElement(CSysWrapper, {
16720
+ }, [drawingId, hoveredOnly, activeProducts, hoveredProductIds, hoveredCSysIds, activeSelector, selItems, activeSelItems, rigidSets, inactiveSelRS]);
16721
+ return /*#__PURE__*/React.createElement(HUD, null, /*#__PURE__*/React.createElement("group", null, csysUDataArray.map(userData => /*#__PURE__*/React.createElement(CSysWrapper, {
16548
16722
  key: getCSysKey$1(userData),
16549
16723
  drawingId: drawingId,
16550
16724
  csys: csys,
@@ -16581,7 +16755,7 @@ const SelectableMate = ({
16581
16755
  isSelected,
16582
16756
  handlers
16583
16757
  } = useMateSelection(drawingId, matePath, csysId);
16584
- const color = isHovered ? 0x28d79f : isSelected ? 0xa70b0b : undefined;
16758
+ const color = getHighlightedColor(false, false, isHovered, isSelected);
16585
16759
  return /*#__PURE__*/React.createElement(Csys, {
16586
16760
  matrix: matrix,
16587
16761
  opacity: 1.0,
@@ -19390,6 +19564,18 @@ class OutlineEffect extends postprocessing.Effect {
19390
19564
  this.outlinePass.render(renderer, null, this.outlineRT);
19391
19565
  };
19392
19566
  }
19567
+ set edgeColor1(value) {
19568
+ const uniform = this.uniforms.get('edgeColor1');
19569
+ uniform.value = new THREE__namespace.Color(value);
19570
+ }
19571
+ set edgeColor2(value) {
19572
+ const uniform = this.uniforms.get('edgeColor2');
19573
+ uniform.value = new THREE__namespace.Color(value);
19574
+ }
19575
+ set edgeColor3(value) {
19576
+ const uniform = this.uniforms.get('edgeColor3');
19577
+ uniform.value = new THREE__namespace.Color(value);
19578
+ }
19393
19579
  set selectionLayer(value) {
19394
19580
  this.selections1.forEach(selection => {
19395
19581
  selection.layer = value;
@@ -19496,7 +19682,9 @@ const Outline = /*#__PURE__*/React.forwardRef(function Outline(_ref, forwardRef)
19496
19682
  width,
19497
19683
  height,
19498
19684
  kernelSize
19499
- }), [scene, camera, edgeStrength, edgeColor1, edgeColor2, edgeColor3, width, height, kernelSize]);
19685
+ }),
19686
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19687
+ [scene, camera, edgeStrength, width, height, kernelSize]);
19500
19688
  React.useEffect(() => {
19501
19689
  if (selections1) {
19502
19690
  effect.selections1 = selections1.map(selection => new postprocessing.Selection(selection, selectionLayer));
@@ -19533,6 +19721,27 @@ const Outline = /*#__PURE__*/React.forwardRef(function Outline(_ref, forwardRef)
19533
19721
  }
19534
19722
  // eslint-disable-next-line react-hooks/exhaustive-deps
19535
19723
  }, [effect, selections3]);
19724
+ React.useEffect(() => {
19725
+ if (edgeColor1) {
19726
+ effect.edgeColor1 = edgeColor1;
19727
+ invalidate();
19728
+ }
19729
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19730
+ }, [effect, edgeColor1]);
19731
+ React.useEffect(() => {
19732
+ if (edgeColor2) {
19733
+ effect.edgeColor2 = edgeColor2;
19734
+ invalidate();
19735
+ }
19736
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19737
+ }, [effect, edgeColor2]);
19738
+ React.useEffect(() => {
19739
+ if (edgeColor3) {
19740
+ effect.edgeColor3 = edgeColor3;
19741
+ invalidate();
19742
+ }
19743
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19744
+ }, [effect, edgeColor3]);
19536
19745
  React.useEffect(() => {
19537
19746
  effect.selectionLayer = selectionLayer;
19538
19747
  invalidate();
@@ -20923,71 +21132,27 @@ const Feature = ({
20923
21132
  });
20924
21133
  const visible = react.useDrawing(drawingId, d => d.plugin.visible.indexOf(featureId) >= 0);
20925
21134
  const {
21135
+ isGHovered,
21136
+ isGSelected,
21137
+ isSHovered,
20926
21138
  handlers
20927
- } = useTreeObjSelection(drawingId, featureId);
21139
+ } = useTreeObjInteraction(drawingId, featureId);
20928
21140
  const onTreeObjClick = handlers.onClick;
20929
21141
  const onTreeObjPointerOver = handlers.onPointerOver;
20930
21142
  const onTreeObjPointerOut = handlers.onPointerOut;
20931
- const selected = react.useDrawing(drawingId, d => d.interaction.selected);
20932
- const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.objectId)) || [];
20933
- const isHovered = react.useDrawing(drawingId, d => {
20934
- var _d$interaction$hovere;
20935
- return ((_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.objectId) === featureId;
20936
- });
20937
- const isSelected = (selectedIds == null ? void 0 : selectedIds.indexOf(featureId)) !== -1;
20938
- const isHighlighted = isHovered || isSelected;
21143
+ const isHovered = isGHovered || isSHovered;
21144
+ const isHighlighted = isHovered || isGSelected;
20939
21145
  const hasGraphics = useHasView(drawingId, featureId);
20940
21146
  const isActive = react.useDrawing(drawingId, d => d.plugin.active.feature === featureId);
20941
21147
  const isCustom = useIsCustom(drawingId, featureRefId);
20942
21148
  const disabled = useIsDisabled(drawingId, featureId);
20943
21149
  const errorId = usePrecheckErrorId(drawingId, featureId);
20944
21150
  const [rename, setRename] = React.useState(false);
20945
- const onClick = React.useCallback(e => {
20946
- const drawing = core.getDrawing(drawingId);
20947
- const isSelActive = drawing.selection.active !== null;
20948
- if (isSelActive && onTreeObjClick) {
20949
- onTreeObjClick(e);
20950
- return;
20951
- }
20952
- const select = drawing.api.interaction.select;
20953
- const multi = e.shiftKey;
20954
- const curNodeId = drawing.structure.currentNode;
20955
- const curProdId = drawing.structure.currentProduct;
20956
- select(core.createInfo({
20957
- objectId: featureId,
20958
- prodRefId: curNodeId || curProdId
20959
- }), multi);
20960
- }, [drawingId, featureId, onTreeObjClick]);
20961
21151
  const onDoubleClick = React.useCallback(() => {
20962
21152
  if (!disabled) {
20963
21153
  core.getDrawing(drawingId).api.plugin.setActiveFeature(featureId);
20964
21154
  }
20965
21155
  }, [disabled, featureId, drawingId]);
20966
- const onMouseEnter = React.useCallback(e => {
20967
- const drawing = core.getDrawing(drawingId);
20968
- const isSelActive = drawing.selection.active !== null;
20969
- if (isSelActive && onTreeObjPointerOver) {
20970
- onTreeObjPointerOver(e);
20971
- return;
20972
- }
20973
- const setHovered = drawing.api.interaction.setHovered;
20974
- const curNodeId = drawing.structure.currentNode;
20975
- const curProdId = drawing.structure.currentProduct;
20976
- setHovered(core.createInfo({
20977
- objectId: featureId,
20978
- prodRefId: curNodeId || curProdId
20979
- }));
20980
- }, [drawingId, featureId, onTreeObjPointerOver]);
20981
- const onMouseLeave = React.useCallback(e => {
20982
- const drawing = core.getDrawing(drawingId);
20983
- const isSelActive = drawing.selection.active !== null;
20984
- if (isSelActive && onTreeObjPointerOut) {
20985
- onTreeObjPointerOut(e);
20986
- return;
20987
- }
20988
- const setHovered = drawing.api.interaction.setHovered;
20989
- setHovered(null);
20990
- }, [drawingId, onTreeObjPointerOut]);
20991
21156
  const nameComponent = rename ? /*#__PURE__*/React.createElement(NameEdit, {
20992
21157
  drawingId: drawingId,
20993
21158
  objId: featureId,
@@ -21034,10 +21199,10 @@ const Feature = ({
21034
21199
  hovered: isHighlighted,
21035
21200
  bordered: true,
21036
21201
  title: String(featureId),
21037
- onClick: onClick,
21202
+ onClick: onTreeObjClick,
21038
21203
  onDoubleClick: onDoubleClick,
21039
- onMouseEnter: onMouseEnter,
21040
- onMouseLeave: onMouseLeave
21204
+ onMouseEnter: onTreeObjPointerOver,
21205
+ onMouseLeave: onTreeObjPointerOut
21041
21206
  }, /*#__PURE__*/React.createElement("div", {
21042
21207
  style: {
21043
21208
  display: 'flex',
@@ -21282,7 +21447,7 @@ const NodeTitle = ({
21282
21447
  return ((_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.objectId) === refId;
21283
21448
  });
21284
21449
  const selected = react.useDrawing(drawingId, d => d.interaction.selected);
21285
- const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.objectId)) || [];
21450
+ const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.prodRefId || -1)) || [];
21286
21451
  const reference = react.useDrawing(drawingId, d => d.structure.tree[refId]);
21287
21452
  const referedId = (reference == null ? void 0 : (_reference$members = reference.members) == null ? void 0 : (_reference$members$pr = _reference$members.productId) == null ? void 0 : _reference$members$pr.value) || NOCCID;
21288
21453
  const localPath = (reference == null ? void 0 : (_reference$members2 = reference.members) == null ? void 0 : (_reference$members2$l = _reference$members2.localPath) == null ? void 0 : _reference$members2$l.value) || EMPTYSTR;
@@ -22053,17 +22218,17 @@ const Solid = ({
22053
22218
  }) => {
22054
22219
  const hoveredId = react.useDrawing(drawingId, d => {
22055
22220
  var _d$interaction$hovere;
22056
- return (_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.graphicId;
22221
+ return (_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.containerId;
22057
22222
  });
22058
22223
  const selected = react.useDrawing(drawingId, d => d.interaction.selected);
22059
- const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.graphicId)) || [];
22224
+ const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.containerId || -1)) || [];
22060
22225
  const solidOwner = useDrawingCCId(drawingId, d => {
22061
22226
  var _d$graphic$containers;
22062
22227
  return (_d$graphic$containers = d.graphic.containers[solidId]) == null ? void 0 : _d$graphic$containers.owner;
22063
22228
  });
22064
22229
  const ccSolid = react.useDrawing(drawingId, d => d.structure.tree[solidOwner]);
22065
22230
  const isHovered = hoveredId === solidId;
22066
- const isSelected = (selectedIds == null ? void 0 : selectedIds.indexOf(solidId)) !== -1;
22231
+ const isSelected = selectedIds.indexOf(solidId) !== -1;
22067
22232
  const isHighlighted = isHovered || isSelected;
22068
22233
  const [rename, setRename] = React.useState(false);
22069
22234
  const onClick = React.useCallback(e => {
@@ -22301,6 +22466,14 @@ const PartModeCmds = (drawingId, rootId) => {
22301
22466
  const featureApi = classcad.ccAPI.feature;
22302
22467
  const pluginApi = core.getDrawing(drawingId).api.plugin;
22303
22468
  const wrapper = cmd => async () => {
22469
+ const activePlugin = core.getDrawing(drawingId).plugin.active.feature;
22470
+ if (activePlugin) {
22471
+ core.showMessage({
22472
+ text: 'Error while attempting to create a new feature: there should be no active feature plugin!',
22473
+ type: 'error'
22474
+ });
22475
+ return;
22476
+ }
22304
22477
  const res = await cmd().catch(console.warn);
22305
22478
  if (res && res.errors && res.errors.length === 0 && res.results[0].result !== null) {
22306
22479
  pluginApi.setActiveFeature(res.results[0].result);
@@ -22479,6 +22652,14 @@ const AssemblyModeCmds = (drawingId, rootId) => {
22479
22652
  const assemblyApi = classcad.ccAPI.assemblyBuilder;
22480
22653
  const pluginApi = core.getDrawing(drawingId).api.plugin;
22481
22654
  const wrapper = cmd => async () => {
22655
+ const activePlugin = core.getDrawing(drawingId).plugin.active.feature;
22656
+ if (activePlugin) {
22657
+ core.showMessage({
22658
+ text: 'Error while attempting to create a new constraint: there should be no active feature plugin!',
22659
+ type: 'error'
22660
+ });
22661
+ return;
22662
+ }
22482
22663
  const res = await cmd().catch(console.warn);
22483
22664
  if (res && res.errors && res.errors.length === 0 && res.results[0].result !== null) {
22484
22665
  pluginApi.setActiveFeature(res.results[0].result);
@@ -22973,6 +23154,7 @@ exports.HUD = HUD;
22973
23154
  exports.HoveredConstraintDisplay = HoveredConstraintDisplay;
22974
23155
  exports.Import = index$1;
22975
23156
  exports.LinearPattern = index$j;
23157
+ exports.MateScope = MateScope;
22976
23158
  exports.Measure = index$g;
22977
23159
  exports.Menu = Menu;
22978
23160
  exports.Messages = Messages;
@@ -22997,6 +23179,7 @@ exports.Sphere = index$t;
22997
23179
  exports.ToolBar = ToolBar;
22998
23180
  exports.TransformByCsys = index$m;
22999
23181
  exports.Translate = index$o;
23182
+ exports.TreeObjScope = TreeObjScope;
23000
23183
  exports.ViewOptionButtons = ViewOptionButtons;
23001
23184
  exports.ViewPlugButtons = ViewPlugButtons;
23002
23185
  exports.WorkAxis = index$e;