@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.
package/build/index.js CHANGED
@@ -1,18 +1,19 @@
1
- import { useDrawing, CameraHelper, useBuerli, usePlugin, useEmbeddedPlugin, GlobalTransform, findBuerliGeometry, BuerliGeometry, usePluginExists, useFeaturePluginDef } from '@buerli.io/react';
1
+ import { useDrawing, CameraHelper, useBuerli, usePlugin, useEmbeddedPlugin, GlobalTransform, BuerliGeometry, usePluginExists, useFeaturePluginDef } from '@buerli.io/react';
2
2
  import * as React from 'react';
3
3
  import React__default, { useMemo, forwardRef, useState, useCallback, useEffect, useRef, memo, useContext, useReducer } from 'react';
4
- import { getDrawing, createGraphicItem, MemberType, MathUtils, api, getPlugin, BuerliScope, createInfo, GraphicType, solidFilter, lineSegmentsFilter, loopFilter, planeFilter, EntityTypes, Measure, MeasureResultType, pointFilter, lineFilter, arcFilter, circleFilter, arcCircleFilter, meshFilter } from '@buerli.io/core';
4
+ import { getDrawing, createGraphicItem, MemberType, MathUtils, api, showMessage, getPlugin, createInfo, BuerliScope, GraphicType, solidFilter, lineSegmentsFilter, loopFilter, planeFilter, EntityTypes, Measure, MeasureResultType, pointFilter, lineFilter, arcFilter, circleFilter, arcCircleFilter, meshFilter } from '@buerli.io/core';
5
5
  import { ccUtils, CCClasses, ccAPI, ReorientedType, FlipType, BooleanOperationType, ExtrusionType, ChamferType, WorkAxisType, WorkPlaneType, WorkPointType, WorkCoordSystemType, DataType } from '@buerli.io/classcad';
6
6
  import * as THREE from 'three';
7
+ import { Matrix4 } from 'three';
7
8
  import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
9
+ import _extends from '@babel/runtime/helpers/esm/extends';
8
10
  import { useFrame, useThree, createPortal, extend } from '@react-three/fiber';
9
- import { Html, useCursor, Merged, Text as Text$3, useBounds } from '@react-three/drei';
11
+ import { Html, useCursor, Text as Text$3, Merged, useBounds } from '@react-three/drei';
10
12
  import create from 'zustand';
11
13
  import vanilla from 'zustand/vanilla';
12
14
  import 'antd/dist/antd.css';
13
15
  import styled, { css, keyframes } from 'styled-components';
14
16
  import { ArrowUpOutlined, CheckOutlined, QuestionCircleFilled, DownOutlined, RightOutlined, EyeFilled, EyeOutlined, EditOutlined, DeleteOutlined, CaretRightOutlined, CaretDownOutlined, PlusOutlined, SelectOutlined, PlusSquareOutlined, ExportOutlined, CloseOutlined, CheckCircleTwoTone, CloseCircleTwoTone, ExclamationCircleTwoTone, InfoCircleTwoTone, MessageOutlined, EditFilled, AppstoreOutlined, FileOutlined, LeftOutlined, AppstoreAddOutlined, FontSizeOutlined, ExpandAltOutlined, CodeSandboxOutlined } from '@ant-design/icons';
15
- import _extends from '@babel/runtime/helpers/esm/extends';
16
17
  import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
17
18
  import { findDOMNode } from 'react-dom';
18
19
  import { Tooltip, Dropdown, Input, Typography, Tag, Space, Tabs as Tabs$1, Divider as Divider$1, Button as Button$1, Badge, Modal, Skeleton as Skeleton$1 } from 'antd';
@@ -199,7 +200,7 @@ function useGlobalToLocalMatrix(drawingId, objId) {
199
200
  function getGlobalToLocalMatrix(drawingId, objId) {
200
201
  const drawing = getDrawing(drawingId);
201
202
  const object = drawing.structure.tree[objId];
202
- const matrix = MathUtils.convertToMatrix4(object.coordinateSystem);
203
+ const matrix = object.coordinateSystem ? MathUtils.convertToMatrix4(object.coordinateSystem) : new THREE.Matrix4();
203
204
  return matrix.invert();
204
205
  }
205
206
  function convertToVector(point) {
@@ -1091,9 +1092,36 @@ const isAngular = dim => ccUtils.base.isA(dim.class, CCClasses.CCAngularDimensio
1091
1092
 
1092
1093
  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; }
1093
1094
  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; }
1095
+ const isFeatureActive = drawingId => {
1096
+ const activePlugin = getDrawing(drawingId).plugin.active.feature;
1097
+ if (activePlugin) {
1098
+ showMessage({
1099
+ text: 'Error: Please close feature before changing the current product!',
1100
+ type: 'error'
1101
+ });
1102
+ return true;
1103
+ }
1104
+ return false;
1105
+ };
1106
+ const isExprPluginActive = drawingId => {
1107
+ const drawing = getDrawing(drawingId);
1108
+ const activeGPlugins = drawing.plugin.active.global;
1109
+ const isExprPluginActive_ = activeGPlugins.findIndex(id => drawing.plugin.refs[id].name === 'Expressions') !== -1;
1110
+ if (isExprPluginActive_) {
1111
+ showMessage({
1112
+ text: 'Error: Please close the Expressions plugin before changing the current product!',
1113
+ type: 'error'
1114
+ });
1115
+ return true;
1116
+ }
1117
+ return false;
1118
+ };
1094
1119
  const appApi = (set, get) => ({
1095
1120
  assemblyTree: {
1096
1121
  startProdEditing: (drawingId, objId) => {
1122
+ if (isFeatureActive(drawingId) || isExprPluginActive(drawingId)) {
1123
+ return;
1124
+ }
1097
1125
  set(state => {
1098
1126
  let res = [];
1099
1127
  const curNode = api.getState().drawing.refs[drawingId].structure.currentNode;
@@ -1110,7 +1138,9 @@ const appApi = (set, get) => ({
1110
1138
  goBack: drawingId => {
1111
1139
  const prodStack = get().assemblyTree.prodStack;
1112
1140
  const prevProd = prodStack[prodStack.length - 1];
1113
- if (!prevProd) return;
1141
+ if (!prevProd || isFeatureActive(drawingId) || isExprPluginActive(drawingId)) {
1142
+ return;
1143
+ }
1114
1144
  set(state => {
1115
1145
  const res = state.assemblyTree.prodStack;
1116
1146
  res.pop();
@@ -1188,13 +1218,19 @@ const BlankDiv = () => {
1188
1218
  }) : null;
1189
1219
  };
1190
1220
 
1221
+ const notoSansFont$1 = 'https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5TRG.woff';
1222
+ const characters$1 = '0123456789-,.';
1223
+ const quat$1 = new THREE.Quaternion();
1224
+ const textMaterial$1 = new THREE.MeshBasicMaterial({
1225
+ depthTest: false,
1226
+ depthWrite: false
1227
+ });
1191
1228
  const mainColor = 0x424242;
1192
1229
  const lineWidth$1 = 0.5;
1193
1230
  const arrowSize = 5;
1194
1231
  const TextValue = ({
1195
1232
  position,
1196
1233
  value,
1197
- onClick,
1198
1234
  backgroundColor
1199
1235
  }) => {
1200
1236
  return /*#__PURE__*/React__default.createElement("group", {
@@ -1202,11 +1238,11 @@ const TextValue = ({
1202
1238
  }, /*#__PURE__*/React__default.createElement(Html, {
1203
1239
  zIndexRange: [0, 0],
1204
1240
  style: {
1205
- marginTop: '22px'
1241
+ marginTop: '22px',
1242
+ pointerEvents: 'none'
1206
1243
  },
1207
1244
  center: true
1208
1245
  }, /*#__PURE__*/React__default.createElement("div", {
1209
- onClick: onClick,
1210
1246
  style: {
1211
1247
  backgroundColor: backgroundColor ? `#${backgroundColor.toString(16)}` : undefined,
1212
1248
  color: `#${mainColor.toString(16)}`,
@@ -1218,12 +1254,14 @@ const TextValue = ({
1218
1254
  const DimValue = ({
1219
1255
  position,
1220
1256
  backgroundColor,
1221
- dimId
1257
+ dimId,
1258
+ disableEvents = false
1222
1259
  }) => {
1223
1260
  var _dimension$members, _tree, _master$members;
1224
1261
  const {
1225
1262
  drawingId
1226
1263
  } = React__default.useContext(DimContext);
1264
+ const textRef = React__default.useRef(null);
1227
1265
  const tree = getDrawing(drawingId).structure.tree;
1228
1266
  const dimension = tree[dimId];
1229
1267
  const masterId = (_dimension$members = dimension.members) == null ? void 0 : _dimension$members.master.value;
@@ -1245,6 +1283,31 @@ const DimValue = ({
1245
1283
  return expr && !isDeg ? expr + ' (' + valueStr + ')' : valueStr;
1246
1284
  }, [master, memberName]);
1247
1285
  const [editMode, setEditMode] = React__default.useState(false);
1286
+ const [isHovered, setIsHovered] = React__default.useState(false);
1287
+ useCursor(isHovered, 'text');
1288
+ const onPointerOver = React__default.useCallback(e => {
1289
+ setIsHovered(true);
1290
+ e.stopPropagation();
1291
+ }, []);
1292
+ const onPointerOut = React__default.useCallback(e => {
1293
+ setIsHovered(false);
1294
+ e.stopPropagation();
1295
+ }, []);
1296
+ const onClick = React__default.useCallback(e => {
1297
+ setIsHovered(false);
1298
+ setEditMode(true);
1299
+ e.stopPropagation();
1300
+ }, []);
1301
+ const stopPropagation = React__default.useCallback(e => {
1302
+ e.stopPropagation();
1303
+ }, []);
1304
+ const handlers = disableEvents ? {} : {
1305
+ onPointerOver,
1306
+ onPointerOut,
1307
+ onClick,
1308
+ onPointerDown: stopPropagation,
1309
+ onPointerUp: stopPropagation
1310
+ };
1248
1311
  React__default.useEffect(() => {
1249
1312
  if (editMode) {
1250
1313
  getCADState().api.blankDiv.show(() => setEditMode(false));
@@ -1255,7 +1318,7 @@ const DimValue = ({
1255
1318
  var _master_$children, _sketchRegion$members, _master_$members, _master_$members2, _master_$members3, _master_$members4, _master_$members5;
1256
1319
  const master_ = getDrawing(drawingId).structure.tree[masterId];
1257
1320
  if (isSketchConstr) {
1258
- ccAPI.base.callSafeAPI(drawingId, 'Sketcher', 'UpdateDimensionValue', [dimId, [valueParam.serverValue.value, valueParam.serverValue.isExpr]]).catch(console.warn);
1321
+ ccAPI.sketcher.updateDimensionValue(drawingId, dimId, valueParam.serverValue).catch(console.warn);
1259
1322
  } else {
1260
1323
  switch (master_.class) {
1261
1324
  case CCClasses.CCExtrusion:
@@ -1290,28 +1353,39 @@ const DimValue = ({
1290
1353
  }
1291
1354
  e.stopPropagation();
1292
1355
  }, [update]);
1356
+ useFrame(args => {
1357
+ if (!textRef.current || !textRef.current.parent) {
1358
+ return;
1359
+ }
1360
+ textRef.current.quaternion.copy(textRef.current.parent.getWorldQuaternion(quat$1)).invert().multiply(args.camera.quaternion);
1361
+ textRef.current.scale.setScalar(1 / args.camera.zoom);
1362
+ });
1293
1363
  return /*#__PURE__*/React__default.createElement("group", {
1294
1364
  position: position
1295
- }, /*#__PURE__*/React__default.createElement(Html, {
1365
+ }, !editMode ? /*#__PURE__*/React__default.createElement(React__default.Suspense, {
1366
+ fallback: null
1367
+ }, /*#__PURE__*/React__default.createElement(Text$3, _extends({
1368
+ ref: textRef,
1369
+ color: "#111111",
1370
+ font: notoSansFont$1,
1371
+ fontSize: 17,
1372
+ letterSpacing: 0.05,
1373
+ anchorY: 17,
1374
+ characters: characters$1,
1375
+ renderOrder: 3000,
1376
+ material: textMaterial$1,
1377
+ userData: {
1378
+ onHUD: true
1379
+ }
1380
+ }, handlers), caption)) : /*#__PURE__*/React__default.createElement(Html, {
1296
1381
  zIndexRange: [blankZIndex + 1, blankZIndex + 1],
1297
1382
  style: {
1298
1383
  transform: 'translate3d(-50%,0,0)',
1299
- marginTop: '14px'
1384
+ marginTop: '10px'
1300
1385
  }
1301
1386
  }, /*#__PURE__*/React__default.createElement("div", {
1302
1387
  onKeyUp: keyHandler
1303
- }, !editMode ? /*#__PURE__*/React__default.createElement("div", {
1304
- onClick: () => {
1305
- setEditMode(true);
1306
- },
1307
- style: {
1308
- backgroundColor: backgroundColor ? `#${backgroundColor.toString(16)}` : undefined,
1309
- color: `#${mainColor.toString(16)}`,
1310
- fontSize: '17px',
1311
- textAlign: 'center',
1312
- cursor: 'text'
1313
- }
1314
- }, caption) : /*#__PURE__*/React__default.createElement("div", {
1388
+ }, /*#__PURE__*/React__default.createElement("div", {
1315
1389
  style: {
1316
1390
  width: '100px'
1317
1391
  }
@@ -1388,7 +1462,8 @@ const hRadius$1 = 6; // Radius of position handler in pixels
1388
1462
  const PositionHandler = ({
1389
1463
  dimId,
1390
1464
  setPosition,
1391
- position
1465
+ position,
1466
+ disableEvents = false
1392
1467
  }) => {
1393
1468
  const isPressed = React__default.useRef(false);
1394
1469
  const isDragged = React__default.useRef(false);
@@ -1455,15 +1530,17 @@ const PositionHandler = ({
1455
1530
  setIsHovered(false);
1456
1531
  e.stopPropagation();
1457
1532
  }, []);
1458
- return /*#__PURE__*/React__default.createElement("mesh", {
1533
+ const handlers = disableEvents ? {} : {
1534
+ onPointerDown,
1535
+ onPointerUp,
1536
+ onPointerOver,
1537
+ onPointerMove,
1538
+ onPointerOut
1539
+ };
1540
+ return /*#__PURE__*/React__default.createElement("mesh", _extends({
1459
1541
  ref: ref,
1460
- position: position,
1461
- onPointerDown: onPointerDown,
1462
- onPointerMove: onPointerMove,
1463
- onPointerUp: onPointerUp,
1464
- onPointerOver: onPointerOver,
1465
- onPointerOut: onPointerOut
1466
- }, /*#__PURE__*/React__default.createElement("sphereGeometry", {
1542
+ position: position
1543
+ }, handlers), /*#__PURE__*/React__default.createElement("sphereGeometry", {
1467
1544
  args: [1.5, 16, 16]
1468
1545
  }), /*#__PURE__*/React__default.createElement("meshBasicMaterial", {
1469
1546
  color: mainColor,
@@ -1475,7 +1552,8 @@ const PositionHandler = ({
1475
1552
  };
1476
1553
 
1477
1554
  const LinearDim = ({
1478
- dimId
1555
+ dimId,
1556
+ disableEvents = false
1479
1557
  }) => {
1480
1558
  const {
1481
1559
  drawingId
@@ -1534,15 +1612,18 @@ const LinearDim = ({
1534
1612
  dir: endDir
1535
1613
  }), /*#__PURE__*/React__default.createElement(DimValue, {
1536
1614
  position: tmpDimP,
1537
- dimId: dimension.id
1615
+ dimId: dimension.id,
1616
+ disableEvents: disableEvents
1538
1617
  }), /*#__PURE__*/React__default.createElement(PositionHandler, {
1539
1618
  position: tmpDimP,
1540
1619
  setPosition: setTmpDimP,
1541
- dimId: dimId
1620
+ dimId: dimId,
1621
+ disableEvents: disableEvents
1542
1622
  }));
1543
1623
  };
1544
1624
  const RadialDim = ({
1545
- dimId
1625
+ dimId,
1626
+ disableEvents = false
1546
1627
  }) => {
1547
1628
  const {
1548
1629
  drawingId
@@ -1580,14 +1661,17 @@ const RadialDim = ({
1580
1661
  }), /*#__PURE__*/React__default.createElement(PositionHandler, {
1581
1662
  position: tmpDimP,
1582
1663
  setPosition: setTmpDimP,
1583
- dimId: dimId
1664
+ dimId: dimId,
1665
+ disableEvents: disableEvents
1584
1666
  }), /*#__PURE__*/React__default.createElement(DimValue, {
1585
1667
  position: tmpDimP,
1586
- dimId: dimension.id
1668
+ dimId: dimension.id,
1669
+ disableEvents: disableEvents
1587
1670
  }));
1588
1671
  };
1589
1672
  const DiametralDim = ({
1590
- dimId
1673
+ dimId,
1674
+ disableEvents = false
1591
1675
  }) => {
1592
1676
  const {
1593
1677
  drawingId
@@ -1629,14 +1713,17 @@ const DiametralDim = ({
1629
1713
  }), /*#__PURE__*/React__default.createElement(PositionHandler, {
1630
1714
  position: tmpDimP,
1631
1715
  setPosition: setTmpDimP,
1632
- dimId: dimId
1716
+ dimId: dimId,
1717
+ disableEvents: disableEvents
1633
1718
  }), /*#__PURE__*/React__default.createElement(DimValue, {
1634
1719
  position: tmpDimP,
1635
- dimId: dimension.id
1720
+ dimId: dimension.id,
1721
+ disableEvents: disableEvents
1636
1722
  }));
1637
1723
  };
1638
1724
  const AngularDim = ({
1639
- dimId
1725
+ dimId,
1726
+ disableEvents = false
1640
1727
  }) => {
1641
1728
  const {
1642
1729
  drawingId
@@ -1720,14 +1807,17 @@ const AngularDim = ({
1720
1807
  }), /*#__PURE__*/React__default.createElement(PositionHandler, {
1721
1808
  dimId: dimId,
1722
1809
  position: tmpDimP,
1723
- setPosition: setTmpDimP
1810
+ setPosition: setTmpDimP,
1811
+ disableEvents: disableEvents
1724
1812
  }), /*#__PURE__*/React__default.createElement(DimValue, {
1725
1813
  position: tmpDimP,
1726
- dimId: dimension.id
1814
+ dimId: dimension.id,
1815
+ disableEvents: disableEvents
1727
1816
  }));
1728
1817
  };
1729
1818
  const DimGraphics = ({
1730
- dimId
1819
+ dimId,
1820
+ disableEvents = false
1731
1821
  }) => {
1732
1822
  const {
1733
1823
  drawingId
@@ -1738,23 +1828,27 @@ const DimGraphics = ({
1738
1828
  });
1739
1829
  if (ccUtils.base.isA(objClass, CCClasses.CCLinearDimension)) {
1740
1830
  return /*#__PURE__*/React__default.createElement(LinearDim, {
1741
- dimId: dimId
1831
+ dimId: dimId,
1832
+ disableEvents: disableEvents
1742
1833
  });
1743
1834
  }
1744
1835
  if (ccUtils.base.isA(objClass, CCClasses.CCAngularDimension)) {
1745
1836
  return /*#__PURE__*/React__default.createElement(AngularDim, {
1746
- dimId: dimId
1837
+ dimId: dimId,
1838
+ disableEvents: disableEvents
1747
1839
  });
1748
1840
  }
1749
1841
  // DiameterDimension is also inherited from RadialDimension, so this check should strictly be first...
1750
1842
  if (ccUtils.base.isA(objClass, CCClasses.CCDiameterDimension)) {
1751
1843
  return /*#__PURE__*/React__default.createElement(DiametralDim, {
1752
- dimId: dimId
1844
+ dimId: dimId,
1845
+ disableEvents: disableEvents
1753
1846
  });
1754
1847
  }
1755
1848
  if (ccUtils.base.isA(objClass, CCClasses.CCRadialDimension)) {
1756
1849
  return /*#__PURE__*/React__default.createElement(RadialDim, {
1757
- dimId: dimId
1850
+ dimId: dimId,
1851
+ disableEvents: disableEvents
1758
1852
  });
1759
1853
  }
1760
1854
  return null;
@@ -2040,12 +2134,26 @@ function ViewImpl$f({
2040
2134
  drawingId,
2041
2135
  pluginId
2042
2136
  }) {
2137
+ var _dimSet$members, _dimSet$members$owner;
2043
2138
  const {
2044
2139
  objectId
2045
2140
  } = getPlugin(drawingId, pluginId);
2046
- const dimSet = useDrawing(drawingId, state => objectId && state.structure.tree[objectId]);
2141
+ const dimSet = useDrawing(drawingId, state => state.structure.tree[objectId || NOCCID]);
2142
+ 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;
2047
2143
  // dimSet here might be undefined for features without constrains
2048
2144
  const children = dimSet && dimSet.children || [];
2145
+
2146
+ // Dimensions shouldn't be interactable if sketch is active and a non-drag handler is active
2147
+ const isOwnerActive = useDrawing(drawingId, d => d.plugin.active.feature === ownerId) || false;
2148
+ const isOwnerSketch = useDrawing(drawingId, d => {
2149
+ var _d$structure$tree$own;
2150
+ return ccUtils.base.isA((_d$structure$tree$own = d.structure.tree[ownerId]) == null ? void 0 : _d$structure$tree$own.class, CCClasses.CCSketch);
2151
+ }) || false;
2152
+ const ownerState = useDrawing(drawingId, d => {
2153
+ var _d$plugin$refs$ownerI;
2154
+ return (_d$plugin$refs$ownerI = d.plugin.refs[ownerId]) == null ? void 0 : _d$plugin$refs$ownerI.state;
2155
+ });
2156
+ const disableEvents = isOwnerActive && isOwnerSketch && (ownerState == null ? void 0 : ownerState.activeHandler) !== undefined && ownerState.activeHandler !== 'drag';
2049
2157
  const matrix = useGlobalToLocalMatrix(drawingId, objectId);
2050
2158
  const contexVal = React__default.useMemo(() => {
2051
2159
  return {
@@ -2069,7 +2177,8 @@ function ViewImpl$f({
2069
2177
  value: contexVal
2070
2178
  }, children.map(dimId => /*#__PURE__*/React__default.createElement(DimGraphics$1, {
2071
2179
  key: dimId,
2072
- dimId: dimId
2180
+ dimId: dimId,
2181
+ disableEvents: disableEvents
2073
2182
  }))));
2074
2183
  }
2075
2184
  const View$f = ({
@@ -2311,7 +2420,6 @@ function useRefsParam(drawingId, objId, memberName) {
2311
2420
 
2312
2421
  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; }
2313
2422
  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; }
2314
-
2315
2423
  /**
2316
2424
  * Implies the following data structure:
2317
2425
  * data: {
@@ -2333,59 +2441,167 @@ const createTreeObjSelItem = (productId, object) => {
2333
2441
  removeCondition: d => d.structure.tree[object.id] === undefined
2334
2442
  };
2335
2443
  };
2444
+
2445
+ // Returns event values that are used in treeObjInteraction events
2446
+ const getEventInfo = e => {
2447
+ const eDef = e;
2448
+ const eRTF = e;
2449
+ if (eRTF.delta !== undefined) {
2450
+ return {
2451
+ delta: eRTF.delta,
2452
+ stopPropagation: eRTF.stopPropagation,
2453
+ shiftKey: eRTF.nativeEvent.shiftKey
2454
+ };
2455
+ } else {
2456
+ return {
2457
+ delta: 0,
2458
+ stopPropagation: undefined,
2459
+ shiftKey: eDef.shiftKey
2460
+ };
2461
+ }
2462
+ };
2336
2463
  function useSelect$1(drawingId, objId) {
2337
2464
  const onClick = React__default.useCallback(e => {
2338
- e.stopPropagation();
2339
- if (e.delta > 1) {
2465
+ var _drawing$plugin$refs, _drawing$structure$tr;
2466
+ const {
2467
+ delta,
2468
+ stopPropagation,
2469
+ shiftKey
2470
+ } = getEventInfo(e);
2471
+ if (delta > 1) {
2340
2472
  return;
2341
2473
  }
2342
- const structure = getDrawing(drawingId).structure;
2343
- const productId = structure.currentProduct;
2344
- if (!productId) return;
2345
- const object = structure.tree[objId];
2346
- const item = createTreeObjSelItem(productId, object);
2347
- const selApi = getDrawing(drawingId).api.selection;
2348
- selApi.isItemSelected(item) ? selApi.unselect(item) : selApi.select(item);
2474
+ const drawing = getDrawing(drawingId);
2475
+ const productId = drawing.structure.currentProduct;
2476
+ const object = drawing.structure.tree[objId];
2477
+ const selection = drawing.selection.refs[drawing.selection.active || ''];
2478
+ const isSelActive = selection !== undefined;
2479
+ const isSelectable = (selection == null ? void 0 : selection.isSelectable(TreeObjScope, {
2480
+ object
2481
+ })) || false;
2482
+ const activeId = ((_drawing$plugin$refs = drawing.plugin.refs[drawing.plugin.active.feature || -1]) == null ? void 0 : _drawing$plugin$refs.id) || -1;
2483
+ const objClass = ((_drawing$structure$tr = drawing.structure.tree[activeId]) == null ? void 0 : _drawing$structure$tr.class) || '';
2484
+ const isSketchActive = ccUtils.base.isA(objClass, CCClasses.CCSketch);
2485
+ if ((isSketchActive || isSelActive) && !isSelectable || !productId) {
2486
+ return;
2487
+ }
2488
+ stopPropagation == null ? void 0 : stopPropagation();
2489
+ if (selection) {
2490
+ if (selection.isSelectable(TreeObjScope, {
2491
+ object
2492
+ })) {
2493
+ const item = createTreeObjSelItem(productId, object);
2494
+ const selApi = drawing.api.selection;
2495
+ selApi.isItemSelected(item) ? selApi.unselect(item) : selApi.select(item);
2496
+ }
2497
+ return;
2498
+ }
2499
+ const interactionInfo = createInfo({
2500
+ objectId: objId,
2501
+ prodRefId: productId
2502
+ });
2503
+ const select = drawing.api.interaction.select;
2504
+ select(interactionInfo, shiftKey);
2349
2505
  }, [drawingId, objId]);
2350
- return {
2506
+ return React__default.useMemo(() => ({
2351
2507
  onClick
2352
- };
2353
- }
2354
- function useIsHovered$1(drawingId, objId) {
2355
- const activeSelId = useDrawing(drawingId, d => d.selection.active);
2356
- const isHovered = useDrawing(drawingId, d => {
2357
- var _d$selection$refs;
2358
- // Unfortunately we need this big selector in useDrawing,
2359
- // without it useIsHovered leads to re-rendering of component each time when hovered of the selection is changed.
2360
- const hoveredItem = (_d$selection$refs = d.selection.refs[activeSelId || '']) == null ? void 0 : _d$selection$refs.hoveredItem;
2361
- if (!hoveredItem) return false;
2362
- const productId = d.structure.currentProduct;
2363
- if (!productId) return false;
2364
- const object = d.structure.tree[objId];
2365
- return createTreeObjSelItem(productId, object).id === hoveredItem.id;
2366
- }) || false;
2367
- return isHovered;
2508
+ }), [onClick]);
2368
2509
  }
2369
2510
  function useHover$1(drawingId, objId) {
2370
2511
  const onPointerOver = React__default.useCallback(e => {
2371
- e.stopPropagation();
2372
- const structure = getDrawing(drawingId).structure;
2373
- const productId = structure.currentProduct;
2374
- if (!productId) return;
2375
- const object = getDrawing(drawingId).structure.tree[objId];
2376
- const item = createTreeObjSelItem(productId, object);
2377
- const selApi = getDrawing(drawingId).api.selection;
2378
- selApi.setHovered(item);
2512
+ var _drawing$plugin$refs2, _drawing$structure$tr2, _drawing$interaction$;
2513
+ const {
2514
+ stopPropagation
2515
+ } = getEventInfo(e);
2516
+ const drawing = getDrawing(drawingId);
2517
+ const productId = drawing.structure.currentProduct;
2518
+ const object = drawing.structure.tree[objId];
2519
+ const selection = drawing.selection.refs[drawing.selection.active || ''];
2520
+ const isSelActive = selection !== undefined;
2521
+ const isSelectable = (selection == null ? void 0 : selection.isSelectable(TreeObjScope, {
2522
+ object
2523
+ })) || false;
2524
+ const activeId = ((_drawing$plugin$refs2 = drawing.plugin.refs[drawing.plugin.active.feature || -1]) == null ? void 0 : _drawing$plugin$refs2.id) || -1;
2525
+ const objClass = ((_drawing$structure$tr2 = drawing.structure.tree[activeId]) == null ? void 0 : _drawing$structure$tr2.class) || '';
2526
+ const isSketchActive = ccUtils.base.isA(objClass, CCClasses.CCSketch);
2527
+ if ((isSketchActive || isSelActive) && !isSelectable || !productId) {
2528
+ return;
2529
+ }
2530
+ stopPropagation == null ? void 0 : stopPropagation();
2531
+ const interactionInfo = createInfo({
2532
+ objectId: objId,
2533
+ prodRefId: productId
2534
+ });
2535
+ if (interactionInfo.uniqueIdent !== ((_drawing$interaction$ = drawing.interaction.hovered) == null ? void 0 : _drawing$interaction$.uniqueIdent)) {
2536
+ const setHovered = drawing.api.interaction.setHovered;
2537
+ setHovered(interactionInfo);
2538
+ }
2379
2539
  }, [drawingId, objId]);
2380
2540
  const onPointerOut = React__default.useCallback(e => {
2381
- e.stopPropagation();
2382
- const selApi = getDrawing(drawingId).api.selection;
2383
- selApi.setHovered(null);
2384
- }, [drawingId]);
2385
- return {
2541
+ var _drawing$interaction$2;
2542
+ const {
2543
+ stopPropagation
2544
+ } = getEventInfo(e);
2545
+ const drawing = getDrawing(drawingId);
2546
+ const productId = drawing.structure.currentProduct;
2547
+ if (!productId) {
2548
+ return;
2549
+ }
2550
+ stopPropagation == null ? void 0 : stopPropagation();
2551
+ const interactionInfo = createInfo({
2552
+ objectId: objId,
2553
+ prodRefId: productId
2554
+ });
2555
+ if (interactionInfo.uniqueIdent === ((_drawing$interaction$2 = drawing.interaction.hovered) == null ? void 0 : _drawing$interaction$2.uniqueIdent)) {
2556
+ const setHovered = getDrawing(drawingId).api.interaction.setHovered;
2557
+ setHovered(null);
2558
+ }
2559
+ }, [drawingId, objId]);
2560
+ return React__default.useMemo(() => ({
2386
2561
  onPointerOut,
2387
2562
  onPointerOver
2388
- };
2563
+ }), [onPointerOut, onPointerOver]);
2564
+ }
2565
+ function useIsSketchActive(drawingId) {
2566
+ const activeId = useDrawing(drawingId, d => {
2567
+ var _d$plugin$refs;
2568
+ return (_d$plugin$refs = d.plugin.refs[d.plugin.active.feature || -1]) == null ? void 0 : _d$plugin$refs.id;
2569
+ }) || -1;
2570
+ const objClass = useDrawing(drawingId, d => {
2571
+ var _d$structure$tree$act;
2572
+ return (_d$structure$tree$act = d.structure.tree[activeId]) == null ? void 0 : _d$structure$tree$act.class;
2573
+ }) || '';
2574
+ return ccUtils.base.isA(objClass, CCClasses.CCSketch);
2575
+ }
2576
+ function useIsGHovered(drawingId, objId) {
2577
+ const isHovered = useDrawing(drawingId, d => {
2578
+ var _d$interaction$hovere;
2579
+ return ((_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.objectId) === objId;
2580
+ }) || false;
2581
+ const isSelActive = useDrawing(drawingId, d => d.selection.active !== null) || false;
2582
+ const isSketchActive = useIsSketchActive(drawingId);
2583
+ return !isSelActive && !isSketchActive && isHovered;
2584
+ }
2585
+ function useIsGSelected(drawingId, objId) {
2586
+ const isGSelected = useDrawing(drawingId, d => {
2587
+ var _d$interaction$select;
2588
+ return ((_d$interaction$select = d.interaction.selected) == null ? void 0 : _d$interaction$select.findIndex(info => info.objectId === objId)) !== -1;
2589
+ }) || false;
2590
+ const isSelActive = useDrawing(drawingId, d => d.selection.active !== null) || false;
2591
+ const isSketchActive = useIsSketchActive(drawingId);
2592
+ return !isSelActive && !isSketchActive && isGSelected;
2593
+ }
2594
+ function useIsSHovered(drawingId, objId) {
2595
+ const object = useDrawing(drawingId, d => d.structure.tree[objId]);
2596
+ const isHovered = useDrawing(drawingId, d => {
2597
+ var _d$interaction$hovere2;
2598
+ return ((_d$interaction$hovere2 = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere2.objectId) === objId;
2599
+ }) || false;
2600
+ const selection = useDrawing(drawingId, d => d.selection.refs[d.selection.active || '']);
2601
+ const isSelectable = (selection == null ? void 0 : selection.isSelectable(TreeObjScope, {
2602
+ object
2603
+ })) || false;
2604
+ return isSelectable && isHovered;
2389
2605
  }
2390
2606
 
2391
2607
  /**
@@ -2400,57 +2616,46 @@ function useHover$1(drawingId, objId) {
2400
2616
  * @param objId
2401
2617
  * @returns
2402
2618
  */
2403
- function useIsSelected$1(drawingId, objId) {
2404
- // Re-render if selectedItems is changed
2405
- const activeSelId = useDrawing(drawingId, d => d.selection.active);
2406
- const selectedItems = useDrawing(drawingId, d => {
2407
- var _d$selection$refs2;
2408
- return (_d$selection$refs2 = d.selection.refs[activeSelId || '']) == null ? void 0 : _d$selection$refs2.items;
2619
+ function useIsSSelected(drawingId, objId) {
2620
+ // Re-render if selItems is changed
2621
+ const selItems = useDrawing(drawingId, d => {
2622
+ var _d$selection$refs;
2623
+ return (_d$selection$refs = d.selection.refs[d.selection.active || '']) == null ? void 0 : _d$selection$refs.items;
2409
2624
  });
2410
2625
  const isSelected = React__default.useMemo(() => {
2411
- if (!selectedItems) return false;
2412
- const structure = getDrawing(drawingId).structure;
2413
- const productId = structure.currentProduct;
2414
- if (!productId) return false;
2415
- const object = structure.tree[objId];
2416
- const selApi = getDrawing(drawingId).api.selection;
2626
+ if (!selItems) {
2627
+ return false;
2628
+ }
2629
+ const drawing = getDrawing(drawingId);
2630
+ const productId = drawing.structure.currentProduct;
2631
+ if (!productId) {
2632
+ return false;
2633
+ }
2634
+ const object = drawing.structure.tree[objId];
2635
+ const selApi = drawing.api.selection;
2417
2636
  return selApi.isItemSelected(createTreeObjSelItem(productId, object));
2418
- }, [drawingId, objId, selectedItems]);
2637
+ }, [drawingId, objId, selItems]);
2419
2638
  return isSelected;
2420
2639
  }
2421
- function useTreeObjSelection(drawingId, objId) {
2422
- const activeSelId = useDrawing(drawingId, drawing => drawing.selection.active);
2423
- const isSelectableFunc = useDrawing(drawingId, d => {
2424
- var _d$selection$refs3;
2425
- return (_d$selection$refs3 = d.selection.refs[activeSelId || '']) == null ? void 0 : _d$selection$refs3.isSelectable;
2426
- });
2427
- const isSelectable = React__default.useMemo(() => {
2428
- if (!isSelectableFunc) return false;
2429
- const object = getDrawing(drawingId).structure.tree[objId];
2430
- const res = isSelectableFunc(TreeObjScope, {
2431
- object: object
2432
- });
2433
- return res;
2434
- }, [drawingId, objId, isSelectableFunc]);
2640
+ function useTreeObjInteraction(drawingId, objId) {
2435
2641
  const hHandlers = useHover$1(drawingId, objId);
2436
- const isHovered = useIsHovered$1(drawingId, objId);
2437
2642
  const sHandlers = useSelect$1(drawingId, objId);
2438
- const isSelected = useIsSelected$1(drawingId, objId);
2439
- const handlers = React__default.useMemo(() => {
2440
- if (isSelectable) {
2441
- return _objectSpread$p(_objectSpread$p({}, hHandlers), sHandlers);
2442
- }
2443
- return {};
2444
- }, [isSelectable, hHandlers, sHandlers]);
2643
+ const isGHovered = useIsGHovered(drawingId, objId);
2644
+ const isGSelected = useIsGSelected(drawingId, objId);
2645
+ const isSHovered = useIsSHovered(drawingId, objId);
2646
+ const isSSelected = useIsSSelected(drawingId, objId);
2647
+ const handlers = React__default.useMemo(() => _objectSpread$p(_objectSpread$p({}, hHandlers), sHandlers), [hHandlers, sHandlers]);
2445
2648
  return React__default.useMemo(() => {
2446
2649
  // 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.
2447
2650
  // Thus, we don't want hovered and selected to be true if the object is not selectable.
2448
2651
  return {
2449
- isHovered: isHovered && isSelectable,
2450
- isSelected: isSelected && isSelectable,
2652
+ isGHovered,
2653
+ isGSelected,
2654
+ isSHovered,
2655
+ isSSelected,
2451
2656
  handlers
2452
2657
  };
2453
- }, [isHovered, isSelected, isSelectable, handlers]);
2658
+ }, [isGHovered, isSHovered, isGSelected, isSSelected, handlers]);
2454
2659
  }
2455
2660
 
2456
2661
  const pickGraphicId = itemData => itemData.graphicId;
@@ -6558,6 +6763,13 @@ const TmpAngularDim = props => {
6558
6763
  }));
6559
6764
  };
6560
6765
 
6766
+ const tolerance$4 = 1e-6;
6767
+
6768
+ /**
6769
+ * Allowed pixel offset for onClick handler events in case the pointer was slightly moved
6770
+ */
6771
+ const deltaTolerance = 4;
6772
+
6561
6773
  const getInitialState = () => {
6562
6774
  return {
6563
6775
  alwaysShowConstr: false,
@@ -6612,9 +6824,6 @@ const description$f = {
6612
6824
  initialState: getInitialState()
6613
6825
  };
6614
6826
 
6615
- // TODO: not realy the best file for const declaration.
6616
- const tolerance$3 = 1e-6;
6617
-
6618
6827
  function getSketchState(drawingId, pluginId) {
6619
6828
  const plugin = getPlugin(drawingId, pluginId);
6620
6829
  if (!plugin || plugin.name !== description$f.name) {
@@ -6661,8 +6870,6 @@ function CreateAngle(drawingId, pluginId) {
6661
6870
  // Local state:
6662
6871
  const tmpDimensionId = guid();
6663
6872
  let entities = [];
6664
- let isMoved = false;
6665
- let isPressed = false;
6666
6873
  const updateDimensionPreview = params => {
6667
6874
  set(state_ => {
6668
6875
  const tmpAngularDimension = state_.tmpObjects[tmpDimensionId];
@@ -6727,39 +6934,29 @@ function CreateAngle(drawingId, pluginId) {
6727
6934
  });
6728
6935
  }
6729
6936
  };
6730
-
6731
- // Pointer Handlers:
6732
- const onPointerDown = e => {
6733
- if (e.nativeEvent.buttons !== 1)
6734
- // Continue only if 'primary' mouse button is pressed
6937
+ const onClick = e => {
6938
+ if (e.delta > deltaTolerance) {
6939
+ // Continue only if the user hasn't moved mouse considerably.
6735
6940
  return;
6736
- isMoved = false;
6737
- isPressed = true;
6738
- e.stopPropagation();
6739
- };
6740
- const onPointerUp = e => {
6741
- if (!isMoved && isPressed) {
6742
- const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
6743
- const {
6744
- dir0,
6745
- dir1,
6746
- center,
6747
- dimPos,
6748
- reflex
6749
- } = tmpObjects[tmpDimensionId];
6750
- const sector = calcSector(dimPos, dir0, dir1, center);
6751
- const previewValue = calcPreviewValue(dir0, dir1, sector, reflex);
6752
- const degValue = radiansToDegrees(previewValue) + 'g';
6753
- ccAPI.sketcher.addConstraints(drawingId, sketchId, ['Ang'], [CCClasses.CC2DAngleConstraint], [entities], [degValue], [dimPos], [[sector, reflex]]).catch(console.warn);
6754
- isPressed = false;
6755
- set({
6756
- activeHandler: HandlersList.DRAG
6757
- });
6758
6941
  }
6942
+ const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
6943
+ const {
6944
+ dir0,
6945
+ dir1,
6946
+ center,
6947
+ dimPos,
6948
+ reflex
6949
+ } = tmpObjects[tmpDimensionId];
6950
+ const sector = calcSector(dimPos, dir0, dir1, center);
6951
+ const previewValue = calcPreviewValue(dir0, dir1, sector, reflex);
6952
+ const degValue = radiansToDegrees(previewValue) + 'g';
6953
+ ccAPI.sketcher.addConstraints(drawingId, sketchId, ['Ang'], [CCClasses.CC2DAngleConstraint], [entities], [degValue], [dimPos], [[sector, reflex]]).catch(console.warn);
6954
+ set({
6955
+ activeHandler: HandlersList.DRAG
6956
+ });
6759
6957
  e.stopPropagation();
6760
6958
  };
6761
6959
  const onPointerMove = e => {
6762
- isMoved = true;
6763
6960
  const dimPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
6764
6961
  updateDimensionPreview({
6765
6962
  dimPos
@@ -6772,9 +6969,8 @@ function CreateAngle(drawingId, pluginId) {
6772
6969
  onActivate,
6773
6970
  onDeactivate,
6774
6971
  pointerHandlers: {
6775
- onPointerDown,
6776
- onPointerUp,
6777
- onPointerMove
6972
+ onPointerMove,
6973
+ onClick
6778
6974
  },
6779
6975
  keyHandlers: {
6780
6976
  keydown,
@@ -7136,7 +7332,7 @@ const createArcMaterial = () => {
7136
7332
 
7137
7333
  // Max number of instances to be handled by Merged
7138
7334
  const limit = 10000;
7139
- const tolerance$2 = 1e-6;
7335
+ const tolerance$3 = 1e-6;
7140
7336
 
7141
7337
  // We need to create mesh instances which will be used later in Merged component.
7142
7338
  // InstancedMesh from three.js use the single mesh but applies different transformations to different instances of the mesh
@@ -7243,7 +7439,7 @@ const InstancedGeometry = ({
7243
7439
  const instances = arcMesh_.userData.instances;
7244
7440
  for (i = 0; i < instances.length; i++) {
7245
7441
  instanceRef = instances[i].current;
7246
- if (Math.abs(instanceRef.radius - radiusArr[i]) > tolerance$2) {
7442
+ if (Math.abs(instanceRef.radius - radiusArr[i]) > tolerance$3) {
7247
7443
  radiusArr[i] = instanceRef.radius;
7248
7444
  radiusAtt.needsUpdate = true;
7249
7445
  }
@@ -7251,7 +7447,7 @@ const InstancedGeometry = ({
7251
7447
  tubeRadiusArr[i] = instanceRef.tubeRadius;
7252
7448
  tubeRadiusAtt.needsUpdate = true;
7253
7449
  }
7254
- if (Math.abs(instanceRef.angularLength - angularLengthArr[i]) > tolerance$2) {
7450
+ if (Math.abs(instanceRef.angularLength - angularLengthArr[i]) > tolerance$3) {
7255
7451
  angularLengthArr[i] = instanceRef.angularLength;
7256
7452
  angularLengthAtt.needsUpdate = true;
7257
7453
  }
@@ -7548,7 +7744,7 @@ function Drag(drawingId, pluginId, camControls) {
7548
7744
  const snappedDiff = snapDraggedPoints(diff, drawingId);
7549
7745
  diff = snappedDiff || diff;
7550
7746
  const selected = getSketchState(drawingId, pluginId).selected;
7551
- if (diff.length() > tolerance$3) {
7747
+ if (diff.length() > tolerance$4) {
7552
7748
  if (promise) {
7553
7749
  // If we are waiting for the response from server, defer next diff and make it after current change.
7554
7750
  defferedDiff = diff;
@@ -7584,7 +7780,6 @@ function DrawPoint(drawingId, pluginId) {
7584
7780
 
7585
7781
  // Local state:
7586
7782
  const tmpPointId = guid();
7587
- let isMoved = false;
7588
7783
  const filter = object => {
7589
7784
  return object && ccUtils.base.isA(object.class, CCClasses.CCSketch);
7590
7785
  };
@@ -7607,32 +7802,24 @@ function DrawPoint(drawingId, pluginId) {
7607
7802
  mousePos: undefined
7608
7803
  });
7609
7804
  };
7610
-
7611
- // Pointer Handlers:
7612
- const onPointerDown = e => {
7613
- if (e.nativeEvent.buttons !== 1)
7614
- // Continue only if 'primary' mouse button is pressed
7805
+ const onClick = e => {
7806
+ if (e.delta > deltaTolerance) {
7807
+ // Continue only if the user hasn't moved mouse considerably.
7615
7808
  return;
7616
- isMoved = false;
7617
- e.stopPropagation();
7618
- };
7619
- const onPointerUp = e => {
7620
- if (!isMoved) {
7621
- const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
7622
- const pointPos = tmpObjects[tmpPointId].position.clone();
7623
- ccAPI.sketcher.addGeometry(drawingId, sketchId, 'Point', {
7624
- pos: pointPos
7625
- }, {
7626
- fixation: true,
7627
- incidence: true,
7628
- tangency: false,
7629
- vertAndHoriz: false
7630
- }).catch(console.warn);
7631
7809
  }
7810
+ const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
7811
+ const pointPos = tmpObjects[tmpPointId].position.clone();
7812
+ ccAPI.sketcher.addGeometry(drawingId, sketchId, 'Point', {
7813
+ pos: pointPos
7814
+ }, {
7815
+ fixation: true,
7816
+ incidence: true,
7817
+ tangency: false,
7818
+ vertAndHoriz: false
7819
+ }).catch(console.warn);
7632
7820
  e.stopPropagation();
7633
7821
  };
7634
7822
  const onPointerMove = e => {
7635
- isMoved = true;
7636
7823
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
7637
7824
  const snappedPos = snapPoint(localPos);
7638
7825
  const mousePos = snappedPos || localPos;
@@ -7655,9 +7842,8 @@ function DrawPoint(drawingId, pluginId) {
7655
7842
  onActivate,
7656
7843
  onDeactivate,
7657
7844
  pointerHandlers: {
7658
- onPointerDown,
7659
- onPointerUp,
7660
- onPointerMove
7845
+ onPointerMove,
7846
+ onClick
7661
7847
  }
7662
7848
  };
7663
7849
  }
@@ -7674,7 +7860,6 @@ function DrawLine(drawingId, pluginId) {
7674
7860
  // Local state:
7675
7861
  let firstPointIsSet = false;
7676
7862
  let lastAddedEndPointId = NOCCID;
7677
- let isMoved = false;
7678
7863
  let promise = null;
7679
7864
  const tmpStartPId = guid();
7680
7865
  const tmpEndPId = guid();
@@ -7720,17 +7905,11 @@ function DrawLine(drawingId, pluginId) {
7720
7905
  return false;
7721
7906
  }
7722
7907
  };
7723
- const onPointerDown = e => {
7724
- if (e.nativeEvent.buttons !== 1 || promise !== null)
7725
- // Continue only if 'primary' mouse button is pressed and we are not waiting for server response.
7726
- return;
7727
- isMoved = false;
7728
- e.stopPropagation();
7729
- };
7730
- const onPointerUp = e => {
7731
- if (isMoved || promise !== null)
7732
- // Continue only if user hasn't moved mouse and line adding is finished.
7908
+ const onClick = e => {
7909
+ if (e.delta > deltaTolerance || promise !== null) {
7910
+ // Continue only if the user hasn't moved mouse considerably, and adding the previous line is finished.
7733
7911
  return;
7912
+ }
7734
7913
  if (!firstPointIsSet) {
7735
7914
  set(state => {
7736
7915
  const tmpEndP = state.tmpObjects[tmpEndPId];
@@ -7800,7 +7979,6 @@ function DrawLine(drawingId, pluginId) {
7800
7979
  e.stopPropagation();
7801
7980
  };
7802
7981
  const onPointerMove = e => {
7803
- isMoved = true;
7804
7982
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
7805
7983
  const snappedPos = snapPoint(localPos);
7806
7984
  const mousePos = snappedPos || localPos;
@@ -7823,9 +8001,8 @@ function DrawLine(drawingId, pluginId) {
7823
8001
  onActivate,
7824
8002
  onDeactivate,
7825
8003
  pointerHandlers: {
7826
- onPointerDown,
7827
- onPointerUp,
7828
- onPointerMove
8004
+ onPointerMove,
8005
+ onClick
7829
8006
  },
7830
8007
  keyHandlers: {
7831
8008
  escape: escHandler
@@ -7843,8 +8020,7 @@ function DrawRectangle(drawingId, pluginId) {
7843
8020
 
7844
8021
  // Local state:
7845
8022
  let additionIndex = 0; // state of handler: 0 - drawing the first point, 1 - drawing tmp rectangle
7846
- let isMoved = false;
7847
- let isPressed = false;
8023
+
7848
8024
  const tmpRectId = guid();
7849
8025
  const tmpPointId = guid();
7850
8026
  const onActivate = () => {
@@ -7894,16 +8070,11 @@ function DrawRectangle(drawingId, pluginId) {
7894
8070
  return false;
7895
8071
  }
7896
8072
  };
7897
- const onPointerDown = e => {
7898
- if (e.nativeEvent.buttons !== 1)
7899
- // Continue only if 'primary' mouse button is pressed
8073
+ const onClick = e => {
8074
+ if (e.delta > deltaTolerance) {
8075
+ // Continue only if the user hasn't moved mouse considerably.
7900
8076
  return;
7901
- isMoved = false;
7902
- isPressed = true;
7903
- e.stopPropagation();
7904
- };
7905
- const onPointerUp = e => {
7906
- if (isMoved || !isPressed) return;
8077
+ }
7907
8078
  if (additionIndex === 0) {
7908
8079
  set(state => {
7909
8080
  const tmpPoint = state.tmpObjects[tmpPointId];
@@ -7964,11 +8135,9 @@ function DrawRectangle(drawingId, pluginId) {
7964
8135
  });
7965
8136
  additionIndex = 0;
7966
8137
  }
7967
- isPressed = false;
7968
8138
  e.stopPropagation();
7969
8139
  };
7970
8140
  const onPointerMove = e => {
7971
- isMoved = true;
7972
8141
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
7973
8142
  const snappedPos = snapPoint(localPos) || localPos;
7974
8143
  set(state => {
@@ -8040,9 +8209,8 @@ function DrawRectangle(drawingId, pluginId) {
8040
8209
  onActivate,
8041
8210
  onDeactivate,
8042
8211
  pointerHandlers: {
8043
- onPointerDown,
8044
- onPointerUp,
8045
- onPointerMove
8212
+ onPointerMove,
8213
+ onClick
8046
8214
  },
8047
8215
  keyHandlers: {
8048
8216
  escape: escHandler,
@@ -8223,7 +8391,6 @@ function DrawArc(drawingId, pluginId, arcType) {
8223
8391
  // Local state:
8224
8392
  let additionIndex = 0;
8225
8393
  let lastAddedEndPointId = NOCCID;
8226
- let isMoved = false;
8227
8394
  let tangent = new THREE.Vector3();
8228
8395
  let lastMousePos = new THREE.Vector3();
8229
8396
  let promise = null;
@@ -8301,13 +8468,6 @@ function DrawArc(drawingId, pluginId, arcType) {
8301
8468
  }
8302
8469
  return false;
8303
8470
  };
8304
- const onPointerDown = e => {
8305
- if (e.nativeEvent.buttons !== 1 || promise !== null)
8306
- // Continue only if 'primary' mouse button is pressed and we are not waiting for server response.
8307
- return;
8308
- isMoved = false;
8309
- e.stopPropagation();
8310
- };
8311
8471
  const calculateCenterPoint = (start, end, hint) => {
8312
8472
  if (arcType === HandlersList.DRAWARCCENTER) {
8313
8473
  const dir1 = end.clone().sub(start);
@@ -8324,7 +8484,7 @@ function DrawArc(drawingId, pluginId, arcType) {
8324
8484
  const v3 = new THREE.Vector3(length2End - length2Hint, length2Hint - length2Start, length2Start - length2End);
8325
8485
  const v4 = new THREE.Vector3(end.y - hint.y, hint.y - start.y, start.y - end.y);
8326
8486
  const denominator = v2.dot(v4);
8327
- if (Math.abs(denominator) < tolerance$3) {
8487
+ if (Math.abs(denominator) < tolerance$4) {
8328
8488
  return undefined;
8329
8489
  }
8330
8490
  const x = -0.5 * v1.dot(v3) / denominator;
@@ -8358,10 +8518,11 @@ function DrawArc(drawingId, pluginId, arcType) {
8358
8518
  }
8359
8519
  return false;
8360
8520
  };
8361
- const onPointerUp = e => {
8362
- if (isMoved || promise !== null)
8363
- // Continue only if user hasn't moved mouse and arc adding is finished.
8521
+ const onClick = e => {
8522
+ if (e.delta > deltaTolerance || promise !== null) {
8523
+ // Continue only if the user hasn't moved mouse considerably, and adding the previous arc is finished.
8364
8524
  return;
8525
+ }
8365
8526
  const tree = getDrawing(drawingId).structure.tree;
8366
8527
  const tmpObjects = getSketchState(drawingId, pluginId).tmpObjects;
8367
8528
  if (additionIndex === 0) {
@@ -8371,7 +8532,7 @@ function DrawArc(drawingId, pluginId, arcType) {
8371
8532
  const startPos = tmpObjects[tmpStartPId].position.clone();
8372
8533
  const matchingPointIds = getDescendants(tree, sketch.id).filter(id => ccUtils.base.isA(tree[id].class, CCClasses.CCPoint) && (tree[id].name === 'startPoint' || tree[id].name === 'endPoint')).filter(id => {
8373
8534
  var _tree$id$members;
8374
- return convertToVector((_tree$id$members = tree[id].members) == null ? void 0 : _tree$id$members.pos).distanceToSquared(startPos) < tolerance$3;
8535
+ return convertToVector((_tree$id$members = tree[id].members) == null ? void 0 : _tree$id$members.pos).distanceToSquared(startPos) < tolerance$4;
8375
8536
  });
8376
8537
  if (matchingPointIds.length !== 1) {
8377
8538
  // TODO: Add some message for the user
@@ -8510,7 +8671,6 @@ function DrawArc(drawingId, pluginId, arcType) {
8510
8671
  e.stopPropagation();
8511
8672
  };
8512
8673
  const onPointerMove = e => {
8513
- isMoved = true;
8514
8674
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
8515
8675
  const snappedPos = snapPoint(localPos);
8516
8676
  lastMousePos = snappedPos || localPos;
@@ -8579,9 +8739,8 @@ function DrawArc(drawingId, pluginId, arcType) {
8579
8739
  onActivate,
8580
8740
  onDeactivate,
8581
8741
  pointerHandlers: {
8582
- onPointerDown,
8583
- onPointerUp,
8584
- onPointerMove
8742
+ onPointerMove,
8743
+ onClick
8585
8744
  },
8586
8745
  keyHandlers: {
8587
8746
  escape: escHandler
@@ -8599,7 +8758,6 @@ function DrawCircle(drawingId, pluginId) {
8599
8758
 
8600
8759
  // Local state:
8601
8760
  let additionIndex = 0;
8602
- let isMoved = false;
8603
8761
  let lastMousePos = new THREE.Vector3();
8604
8762
  const tmpCenterPId = guid();
8605
8763
  const tmpCircleId = guid();
@@ -8647,15 +8805,11 @@ function DrawCircle(drawingId, pluginId) {
8647
8805
  return false;
8648
8806
  }
8649
8807
  };
8650
- const onPointerDown = e => {
8651
- if (e.nativeEvent.buttons !== 1)
8652
- // Continue only if 'primary' mouse button is pressed
8808
+ const onClick = e => {
8809
+ if (e.delta > deltaTolerance) {
8810
+ // Continue only if the user hasn't moved mouse considerably.
8653
8811
  return;
8654
- isMoved = false;
8655
- e.stopPropagation();
8656
- };
8657
- const onPointerUp = e => {
8658
- if (isMoved) return;
8812
+ }
8659
8813
  if (additionIndex === 0) {
8660
8814
  set(state => {
8661
8815
  const tmpCenterP = state.tmpObjects[tmpCenterPId];
@@ -8701,7 +8855,6 @@ function DrawCircle(drawingId, pluginId) {
8701
8855
  e.stopPropagation();
8702
8856
  };
8703
8857
  const onPointerMove = e => {
8704
- isMoved = true;
8705
8858
  const localPos = e.point.clone().applyMatrix4(getGlobalToLocalMatrix(drawingId, sketchId));
8706
8859
  const snappedPos = snapPoint(localPos);
8707
8860
  lastMousePos = (snappedPos || localPos).clone();
@@ -8737,9 +8890,8 @@ function DrawCircle(drawingId, pluginId) {
8737
8890
  onActivate,
8738
8891
  onDeactivate,
8739
8892
  pointerHandlers: {
8740
- onPointerDown,
8741
- onPointerUp,
8742
- onPointerMove
8893
+ onPointerMove,
8894
+ onClick
8743
8895
  },
8744
8896
  keyHandlers: {
8745
8897
  escape: escHandler
@@ -9036,7 +9188,7 @@ const getOriginByPoint = (drawingId, pointId, objectIds) => {
9036
9188
  const object = tree[objectIds[i]];
9037
9189
  if (ccUtils.base.isA(object.class, CCClasses.CCPoint)) {
9038
9190
  var _object$members;
9039
- if (convertToVector((_object$members = object.members) == null ? void 0 : _object$members.pos).distanceToSquared(pointPos) < tolerance$3) {
9191
+ if (convertToVector((_object$members = object.members) == null ? void 0 : _object$members.pos).distanceToSquared(pointPos) < tolerance$4) {
9040
9192
  return {
9041
9193
  index: i
9042
9194
  };
@@ -9049,7 +9201,7 @@ const getOriginByPoint = (drawingId, pointId, objectIds) => {
9049
9201
  var _childPoint$members;
9050
9202
  const childPoint = childPoints.find(p => p.name === name);
9051
9203
  const pos = childPoint ? convertToVector((_childPoint$members = childPoint.members) == null ? void 0 : _childPoint$members.pos) : undefined;
9052
- return pos && pos.distanceToSquared(pointPos) < tolerance$3;
9204
+ return pos && pos.distanceToSquared(pointPos) < tolerance$4;
9053
9205
  });
9054
9206
  if (matchingPoint) {
9055
9207
  return {
@@ -9980,8 +10132,10 @@ const Constraints$2 = () => {
9980
10132
  width: size.width,
9981
10133
  sidepadding: size.sidePadding,
9982
10134
  iconmargin: size.iconMargin
9983
- }, sortedConstraints.map(constrClass => /*#__PURE__*/React__default.createElement(ConstrBtn, {
9984
- key: constrClass,
10135
+ }, sortedConstraints.map((constrClass, i) => /*#__PURE__*/React__default.createElement(ConstrBtn
10136
+ // Use index as key instead of constrClass for the same element to retain its position; This is needed for tooltip to behave correctly
10137
+ , {
10138
+ key: i,
9985
10139
  constrClass: constrClass,
9986
10140
  disabled: allowedConstraints.indexOf(constrClass) === -1
9987
10141
  })))));
@@ -10211,7 +10365,7 @@ function recognizeFilletByArc(object, tree, sketchId) {
10211
10365
 
10212
10366
  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; }
10213
10367
  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; }
10214
- function Fillet(drawingId, pluginId, camControls) {
10368
+ function Fillet(drawingId, pluginId) {
10215
10369
  const plugin = getPlugin(drawingId, pluginId);
10216
10370
  const set = plugin.set;
10217
10371
  const sketchId = plugin.objectId;
@@ -10222,7 +10376,6 @@ function Fillet(drawingId, pluginId, camControls) {
10222
10376
  const tmpFilletPId = guid();
10223
10377
  const tmpLine1Id = guid();
10224
10378
  const tmpLine2Id = guid();
10225
- let isPressed = false;
10226
10379
  const filter = object => object && (ccUtils.base.isA(object.class, CCClasses.CCPoint) || ccUtils.base.isA(object.class, CCClasses.CCArc));
10227
10380
  const onDeactivate = () => {
10228
10381
  set({
@@ -10329,18 +10482,11 @@ function Fillet(drawingId, pluginId, camControls) {
10329
10482
  });
10330
10483
  e.stopPropagation();
10331
10484
  };
10332
- const onPointerDown = e => {
10333
- if (e.nativeEvent.buttons !== 1)
10334
- // Continue only if 'primary' mouse button is pressed
10485
+ const onClick = e => {
10486
+ if (e.delta > deltaTolerance) {
10487
+ // Continue only if the user hasn't moved mouse considerably.
10335
10488
  return;
10336
- isPressed = true;
10337
- camControls.enabled = false;
10338
- e.target.setPointerCapture(e.nativeEvent.pointerId);
10339
- e.stopPropagation();
10340
- };
10341
- const onPointerUp = e => {
10342
- if (!isPressed) return;
10343
- camControls.enabled = true;
10489
+ }
10344
10490
  const hoveredId = e.object.userData.objId;
10345
10491
  const tree = getDrawing(drawingId).structure.tree;
10346
10492
  const hoveredObject = tree[hoveredId];
@@ -10373,8 +10519,6 @@ function Fillet(drawingId, pluginId, camControls) {
10373
10519
  cursor: null
10374
10520
  });
10375
10521
  }
10376
- isPressed = false;
10377
- e.target.releasePointerCapture(e.nativeEvent.pointerId);
10378
10522
  e.stopPropagation();
10379
10523
  };
10380
10524
  return {
@@ -10384,8 +10528,7 @@ function Fillet(drawingId, pluginId, camControls) {
10384
10528
  pointerHandlers: {
10385
10529
  onPointerOver,
10386
10530
  onPointerOut,
10387
- onPointerDown,
10388
- onPointerUp
10531
+ onClick
10389
10532
  }
10390
10533
  };
10391
10534
  }
@@ -10430,6 +10573,10 @@ function Trim(drawingId, pluginId) {
10430
10573
  };
10431
10574
  const onClick = e => {
10432
10575
  var _tree2;
10576
+ if (e.delta > deltaTolerance) {
10577
+ // Continue only if the user hasn't moved mouse considerably.
10578
+ return;
10579
+ }
10433
10580
  const tree = getDrawing(drawingId).structure.tree;
10434
10581
  if (ccUtils.base.isA((_tree2 = tree[tree[e.object.userData.objId].parent || NOCCID]) == null ? void 0 : _tree2.class, CCClasses.CCContainer)) {
10435
10582
  ccAPI.sketcher.removeObjects(drawingId, sketchId, [e.object.userData.objId], false).catch(console.warn);
@@ -10511,12 +10658,16 @@ const useGeomParams = objId => {
10511
10658
  drawingId,
10512
10659
  pluginId
10513
10660
  } = React__default.useContext(ViewContext);
10661
+ // TODO: Rename lSelected / gSelected consts because it seems wrong to call sketch selection local and selector-selection global...
10662
+ const lHovered = useSketchState(drawingId, pluginId, state => state.hovered === objId);
10514
10663
  const lSelected = useSketchState(drawingId, pluginId, state => state.selected.indexOf(objId) !== -1);
10515
- // gSelected - true if object is selected in a global selection
10516
- const gSelected = useIsSelected$1(drawingId, objId);
10664
+ // gHovered - true if object is selector-hovered
10665
+ const gHovered = useIsSHovered(drawingId, objId);
10666
+ // gSelected - true if object is selector-selected
10667
+ const gSelected = useIsSSelected(drawingId, objId);
10517
10668
  const isSelected = lSelected || gSelected;
10669
+ const isHovered = lHovered || gHovered;
10518
10670
  const isHighlighted = useSketchState(drawingId, pluginId, state => state.highlighted.indexOf(objId) !== -1);
10519
- const isHovered = useSketchState(drawingId, pluginId, state => state.hovered === objId);
10520
10671
  const {
10521
10672
  renderOrder,
10522
10673
  offsetUnits
@@ -10613,7 +10764,7 @@ const getConstrColor = objState => {
10613
10764
  if (isHighlighted) return 0xbbecdd;
10614
10765
  return 0xdddddd;
10615
10766
  };
10616
- const getColor$1 = (object, objState) => {
10767
+ const getColor = (object, objState) => {
10617
10768
  const {
10618
10769
  isGHovered,
10619
10770
  isSketchActive,
@@ -10671,10 +10822,11 @@ const useColor = (objId, gHovered) => {
10671
10822
  isActive
10672
10823
  } = React__default.useContext(ViewContext);
10673
10824
 
10825
+ // TODO: Rename lSelected / gSelected consts because it seems wrong to call sketch selection local and selector-selection global...
10674
10826
  // Selected locally, in the sketcher.
10675
10827
  const lSelected = useSketchState(drawingId, pluginId, state => state.selected.indexOf(objId) !== -1);
10676
- // Globally selected by some of selection elements.
10677
- const gSelected = useIsSelected$1(drawingId, objId);
10828
+ // gSelected - true if object is selector-selected
10829
+ const gSelected = useIsSSelected(drawingId, objId);
10678
10830
  const isSelected = lSelected || gSelected;
10679
10831
  const isHighlighted = useSketchState(drawingId, pluginId, state => state.highlighted.indexOf(objId) !== -1);
10680
10832
  const isHovered = useSketchState(drawingId, pluginId, state => state.hovered === objId);
@@ -10684,7 +10836,7 @@ const useColor = (objId, gHovered) => {
10684
10836
  });
10685
10837
  const color = React__default.useMemo(() => {
10686
10838
  const object = getDrawing(drawingId).structure.tree[objId];
10687
- return getColor$1(object, {
10839
+ return getColor(object, {
10688
10840
  isSketchActive: isActive,
10689
10841
  isHighlighted,
10690
10842
  isHovered,
@@ -10725,11 +10877,11 @@ const defaultHandlers = {
10725
10877
  };
10726
10878
 
10727
10879
  const useHandlersAndColor = (drawingId, objId) => {
10728
- const activeSelection = useDrawing(drawingId, d => d.selection.active);
10729
- const globalSelection = useTreeObjSelection(drawingId, objId);
10880
+ const isSelActive = useDrawing(drawingId, d => d.selection.active);
10881
+ const treeObjInteraction = useTreeObjInteraction(drawingId, objId);
10730
10882
  const sketchPointerHandlers = useSketchHandlers(objId);
10731
- const pointerHandlers = activeSelection ? globalSelection.handlers : sketchPointerHandlers;
10732
- const color = useColor(objId, globalSelection.isHovered);
10883
+ const pointerHandlers = isSelActive ? treeObjInteraction.handlers : sketchPointerHandlers;
10884
+ const color = useColor(objId, treeObjInteraction.isSHovered);
10733
10885
  return React__default.useMemo(() => ({
10734
10886
  handlers: pointerHandlers || defaultHandlers,
10735
10887
  color
@@ -10748,7 +10900,7 @@ const HUD = ({
10748
10900
  gl.autoClear = false;
10749
10901
  gl.clearDepth();
10750
10902
  gl.render(virtualScene, camera);
10751
- }, 2);
10903
+ }, 3);
10752
10904
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, createPortal( /*#__PURE__*/React__default.createElement("group", null, children), virtualScene));
10753
10905
  };
10754
10906
 
@@ -10910,7 +11062,7 @@ const Constraints$1 = props => {
10910
11062
  var _tree$pointId$members;
10911
11063
  return convertToArray((_tree$pointId$members = tree[pointId].members) == null ? void 0 : _tree$pointId$members.pos);
10912
11064
  }).reduce((sum, current) => [sum[0] + current[0], sum[1] + current[1], sum[2] + current[2]]).map(x => x / pointChildrenIds.length));
10913
- const suitableRow = constrRows.find(row => row.position.distanceTo(position) < tolerance$3);
11065
+ const suitableRow = constrRows.find(row => row.position.distanceTo(position) < tolerance$4);
10914
11066
  if (suitableRow) {
10915
11067
  suitableRow.constrIds.push(constraint.id);
10916
11068
  } else {
@@ -11620,7 +11772,7 @@ const SketchPlane = ({
11620
11772
  objId
11621
11773
  }
11622
11774
  })), /*#__PURE__*/React__default.createElement("gridHelper", {
11623
- args: [step * linesCount, linesCount, 0x000000, 0x888888],
11775
+ args: [step * linesCount, linesCount, 0x000000, 0x444444],
11624
11776
  "geometry-computeBoundingBox": zeroBounds,
11625
11777
  quaternion: planeQuaternion,
11626
11778
  onUpdate: update
@@ -11640,7 +11792,10 @@ const Sketch = ({
11640
11792
  } = getPlugin(drawingId, pluginId);
11641
11793
  const containerIds = React__default.useMemo(() => {
11642
11794
  const tree = getDrawing(drawingId).structure.tree;
11643
- return sketch.children && sketch.children.filter(id => ccUtils.base.isA(tree[id].class, CCClasses.CCContainer));
11795
+ // Not using ccUtils.isA here because sketch may contain other containers, CCUseSet in particular.
11796
+ // Since trim geometry is recognized as CCContainer's children, it is crucial for now to make a direct class check.
11797
+ // TODO: Change how this is handled on the serverside. For example, by using a unique class for trim container.
11798
+ return sketch.children && sketch.children.filter(id => tree[id].class === CCClasses.CCContainer);
11644
11799
  }, [sketch.children, drawingId]);
11645
11800
  const drawnObjects = React__default.useMemo(() => {
11646
11801
  let res = [];
@@ -11985,7 +12140,11 @@ const RubberBandRectangle = () => {
11985
12140
  // TODO: handle font in some other way?
11986
12141
  const notoSansFont = 'https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5TRG.woff';
11987
12142
  const characters = '0123456789-,.';
11988
- const pos = new THREE.Vector3();
12143
+ const quat = new THREE.Quaternion();
12144
+ const textMaterial = new THREE.MeshBasicMaterial({
12145
+ depthTest: false,
12146
+ depthWrite: false
12147
+ });
11989
12148
  const MousePosition = () => {
11990
12149
  const {
11991
12150
  drawingId,
@@ -11995,16 +12154,15 @@ const MousePosition = () => {
11995
12154
  const sketchId = usePlugin(drawingId, pluginId, p => p.objectId);
11996
12155
  const mousePos = useSketchState(drawingId, pluginId, state => state.mousePos);
11997
12156
  useFrame(args => {
11998
- if (!ref.current || !mousePos || !sketchId) {
12157
+ if (!ref.current || !ref.current.parent || !mousePos || !sketchId) {
11999
12158
  return;
12000
12159
  }
12001
- pos.copy(mousePos).applyMatrix4(getDrawing(drawingId).api.structure.calculateGlobalTransformation(sketchId));
12002
12160
  const scale = getScale(drawingId, pluginId);
12003
- ref.current.position.set(pos.x, pos.y, pos.z);
12004
- ref.current.quaternion.copy(args.camera.quaternion);
12161
+ ref.current.position.set(mousePos.x, mousePos.y, mousePos.z);
12162
+ ref.current.quaternion.copy(ref.current.parent.getWorldQuaternion(quat)).invert().multiply(args.camera.quaternion);
12005
12163
  ref.current.scale.setScalar(scale);
12006
12164
  });
12007
- return mousePos ? /*#__PURE__*/React__default.createElement(HUD, null, /*#__PURE__*/React__default.createElement(React__default.Suspense, {
12165
+ return mousePos ? /*#__PURE__*/React__default.createElement(React__default.Suspense, {
12008
12166
  fallback: null
12009
12167
  }, /*#__PURE__*/React__default.createElement(Text$3, {
12010
12168
  ref: ref,
@@ -12014,8 +12172,10 @@ const MousePosition = () => {
12014
12172
  letterSpacing: 0.05,
12015
12173
  anchorX: -3,
12016
12174
  anchorY: 4,
12017
- characters: characters
12018
- }, `${mousePos.x.toFixed(2)}, ${mousePos.y.toFixed(2)}`))) : null;
12175
+ characters: characters,
12176
+ renderOrder: 3001,
12177
+ material: textMaterial
12178
+ }, `${mousePos.x.toFixed(2)}, ${mousePos.y.toFixed(2)}`)) : null;
12019
12179
  };
12020
12180
 
12021
12181
  function useSetScale(drawingId, pluginId) {
@@ -12024,7 +12184,7 @@ function useSetScale(drawingId, pluginId) {
12024
12184
  if (!plugin) return;
12025
12185
  const state = plugin.state;
12026
12186
  const sketchObj = getDrawing(drawingId).structure.tree[plugin.objectId];
12027
- const sketchMatrix = MathUtils.convertToMatrix4(sketchObj.coordinateSystem);
12187
+ const sketchMatrix = sketchObj.coordinateSystem ? MathUtils.convertToMatrix4(sketchObj.coordinateSystem) : new THREE.Matrix4();
12028
12188
  const sketchOriginGlobal = new THREE.Vector3(0.0, 0.0, 0.0).applyMatrix4(sketchMatrix);
12029
12189
  const approxScale = CameraHelper.calculateScaleFactor(sketchOriginGlobal, 7, args.camera, args.size);
12030
12190
  const newStep = Math.pow(10.0, Math.floor(Math.log10(approxScale * 30) + 1e-3));
@@ -12196,17 +12356,17 @@ const DrawingMode = ({
12196
12356
  const plane = getDrawing(drawingId).structure.tree[planeRef];
12197
12357
  const normal = convertToVector(plane == null ? void 0 : (_plane$members = plane.members) == null ? void 0 : _plane$members.Normal);
12198
12358
  const csys = getDrawing(drawingId).structure.tree[sketchId].coordinateSystem;
12199
- const transformMatrix = MathUtils.convertToMatrix3(csys);
12359
+ const transformMatrix = csys ? MathUtils.convertToMatrix3(csys) : new THREE.Matrix3();
12200
12360
  const upVector = new THREE.Vector3(0, 1, 0).applyMatrix3(transformMatrix).normalize();
12201
12361
 
12202
12362
  // If box.min === box.max add (1,1,0) to box.max to make box not empty
12203
12363
  const box = bounds.box;
12204
- if (box.min.distanceTo(box.max) < tolerance$3) {
12364
+ if (box.min.distanceTo(box.max) < tolerance$4) {
12205
12365
  box.set(box.min, box.min.clone().add(new THREE.Vector3(1000, 1000, 1000)));
12206
12366
  }
12207
12367
 
12208
12368
  // Convert local box coordinates to global
12209
- const matrix4 = MathUtils.convertToMatrix4(csys);
12369
+ const matrix4 = csys ? MathUtils.convertToMatrix4(csys) : new THREE.Matrix4();
12210
12370
  const globCenter = bounds.center.clone().applyMatrix4(matrix4);
12211
12371
  const globBox = box.clone().applyMatrix4(matrix4);
12212
12372
  camera.position.copy(globCenter.clone().addScaledVector(normal, (bounds.radius || 1) * 100 * 2));
@@ -12222,7 +12382,7 @@ const DrawingMode = ({
12222
12382
  boundsControls == null ? void 0 : boundsControls.refresh().fit();
12223
12383
  };
12224
12384
  // eslint-disable-next-line react-hooks/exhaustive-deps
12225
- }, [boundsMember]);
12385
+ }, []);
12226
12386
 
12227
12387
  // Add handlers to pluginState when sketcher is enabled
12228
12388
  React__default.useEffect(() => {
@@ -13148,13 +13308,13 @@ const ObjTitle = ({
13148
13308
  return (_d$structure$tree$obj2 = d.structure.tree[objId]) == null ? void 0 : _d$structure$tree$obj2.class;
13149
13309
  });
13150
13310
  const activeHandler = useSketchState(drawingId, pluginId, state => state.activeHandler);
13151
- const globalSelection = useTreeObjSelection(drawingId, objId);
13152
- const isGHovered = globalSelection.isHovered;
13153
- const isGSelected = globalSelection.isSelected;
13154
- const onClickSel = globalSelection.handlers.onClick;
13311
+ const treeObjInteraction = useTreeObjInteraction(drawingId, objId);
13312
+ const isSHovered = treeObjInteraction.isSHovered;
13313
+ const isSSelected = treeObjInteraction.isSSelected;
13314
+ const onClickSel = treeObjInteraction.handlers.onClick;
13155
13315
  const isHovered = useSketchState(drawingId, pluginId, s => s.hovered === objId);
13156
13316
  const isSelected = useSketchState(drawingId, pluginId, s => s.selected.indexOf(objId) !== -1);
13157
- const color = isSelected || isGSelected ? '#ffa500' : isHovered || isGHovered ? '#28d79f' : undefined;
13317
+ const color = isSelected || isSSelected ? '#ffa500' : isHovered || isSHovered ? '#28d79f' : undefined;
13158
13318
 
13159
13319
  // TODO: Rename resources so that they have more generic names, i.e. 'CC_Point' instead of 'drawPoint', etc
13160
13320
  const imgName = React__default.useMemo(() => {
@@ -13299,7 +13459,7 @@ const Details = () => {
13299
13459
  const refGeometry_ = ccUseGeometry.map(member => [member.members[0].value, member.members[1].value]) || [];
13300
13460
  const geometry_ = (sketchChildren == null ? void 0 : sketchChildren.filter(id => isSketchGeometry(tree[id].class) && refGeometry_.findIndex(refArr => refArr[0] === id) === -1)) || [];
13301
13461
  const constraints_ = (sketchChildren == null ? void 0 : sketchChildren.filter(id => is2DConstraint(tree[id].class))) || [];
13302
- const isTrimActive_ = (sketchChildren == null ? void 0 : sketchChildren.findIndex(id => ccUtils.base.isA(tree[id].class, CCClasses.CCContainer))) !== -1;
13462
+ const isTrimActive_ = (sketchChildren == null ? void 0 : sketchChildren.findIndex(id => tree[id].class === CCClasses.CCContainer)) !== -1;
13303
13463
  return {
13304
13464
  refGeometry: refGeometry_,
13305
13465
  geometry: geometry_,
@@ -13940,8 +14100,7 @@ var index$f = /*#__PURE__*/Object.freeze({
13940
14100
  __proto__: null,
13941
14101
  Root: Root$f,
13942
14102
  View: View$d,
13943
- description: description$f,
13944
- tolerance: tolerance$3
14103
+ description: description$f
13945
14104
  });
13946
14105
 
13947
14106
  function useRefsReset(type, refs) {
@@ -14128,16 +14287,29 @@ const WorkAxisObj = ({
14128
14287
  }));
14129
14288
  };
14130
14289
 
14131
- function getColor(hovered, selected, direction, type) {
14132
- if (hovered) {
14133
- return 0x28d79f;
14134
- } else if (selected) {
14135
- return 0xa70b0b;
14136
- } else if (direction.distanceTo(new THREE.Vector3(1, 0, 0)) < tolerance$3 && type === WorkAxisType.WA_FIXED) {
14290
+ const getHighlightedColor = (isGHovered, isGSelected, isSHovered, isSSelected) => {
14291
+ if (isSHovered) {
14292
+ return '#3280ff';
14293
+ }
14294
+ if (isSSelected) {
14295
+ return '#8040c0';
14296
+ }
14297
+ if (isGHovered) {
14298
+ return 'green';
14299
+ }
14300
+ if (isGSelected) {
14301
+ return 'red';
14302
+ }
14303
+ return undefined;
14304
+ };
14305
+
14306
+ const tolerance$2 = 1e-6;
14307
+ function getBaseColor(direction, type) {
14308
+ if (direction.distanceTo(new THREE.Vector3(1, 0, 0)) < tolerance$2 && type === WorkAxisType.WA_FIXED) {
14137
14309
  return 0xd52828;
14138
- } else if (direction.distanceTo(new THREE.Vector3(0, 1, 0)) < tolerance$3 && type === WorkAxisType.WA_FIXED) {
14310
+ } else if (direction.distanceTo(new THREE.Vector3(0, 1, 0)) < tolerance$2 && type === WorkAxisType.WA_FIXED) {
14139
14311
  return 0x28a628;
14140
- } else if (direction.distanceTo(new THREE.Vector3(0, 0, 1)) < tolerance$3 && type === WorkAxisType.WA_FIXED) {
14312
+ } else if (direction.distanceTo(new THREE.Vector3(0, 0, 1)) < tolerance$2 && type === WorkAxisType.WA_FIXED) {
14141
14313
  return 0x2828d7;
14142
14314
  } else {
14143
14315
  return 0x111111;
@@ -14154,11 +14326,13 @@ const ViewImpl$c = ({
14154
14326
  const workAxisObj = useDrawing(drawingId, drawing => drawing.structure.tree[objectId]);
14155
14327
  const direction = convertToVector(workAxisObj == null ? void 0 : (_workAxisObj$members = workAxisObj.members) == null ? void 0 : _workAxisObj$members.Direction);
14156
14328
  const {
14157
- isHovered,
14158
- isSelected,
14329
+ isGHovered,
14330
+ isGSelected,
14331
+ isSHovered,
14332
+ isSSelected,
14159
14333
  handlers
14160
- } = useTreeObjSelection(drawingId, objectId);
14161
- const color = getColor(isHovered, isSelected, direction, workAxisObj == null ? void 0 : (_workAxisObj$members2 = workAxisObj.members) == null ? void 0 : _workAxisObj$members2.Type.value);
14334
+ } = useTreeObjInteraction(drawingId, objectId);
14335
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected) || getBaseColor(direction, workAxisObj == null ? void 0 : (_workAxisObj$members2 = workAxisObj.members) == null ? void 0 : _workAxisObj$members2.Type.value);
14162
14336
  return /*#__PURE__*/React__default.createElement(HUD, null, /*#__PURE__*/React__default.createElement(WorkAxisObj, {
14163
14337
  drawingId: drawingId,
14164
14338
  objectId: objectId,
@@ -14529,18 +14703,27 @@ const ViewImpl$b = ({
14529
14703
  objectId = -1
14530
14704
  } = getPlugin(drawingId, pluginId);
14531
14705
  const {
14532
- isHovered,
14533
- isSelected,
14706
+ isGHovered,
14707
+ isGSelected,
14708
+ isSHovered,
14709
+ isSSelected,
14534
14710
  handlers
14535
- } = useTreeObjSelection(drawingId, objectId);
14536
- const color = isHovered ? 0x18b77f : isSelected ? 0xa70b0b : 0x34424f;
14537
- return /*#__PURE__*/React__default.createElement(WorkPlaneObj, {
14711
+ } = useTreeObjInteraction(drawingId, objectId);
14712
+ const isHighlighted = isGHovered || isGSelected || isSHovered || isSSelected;
14713
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected) || 0x34424f;
14714
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, !isHighlighted && /*#__PURE__*/React__default.createElement(WorkPlaneObj, {
14538
14715
  drawingId: drawingId,
14539
14716
  objectId: objectId,
14540
14717
  color: color,
14541
14718
  opacity: 0.5,
14542
14719
  handlers: handlers
14543
- });
14720
+ }), isHighlighted && /*#__PURE__*/React__default.createElement(HUD, null, /*#__PURE__*/React__default.createElement(WorkPlaneObj, {
14721
+ drawingId: drawingId,
14722
+ objectId: objectId,
14723
+ color: color,
14724
+ opacity: 0.3,
14725
+ handlers: handlers
14726
+ })));
14544
14727
  };
14545
14728
  const View$b = ({
14546
14729
  drawingId,
@@ -14722,11 +14905,13 @@ const ViewImpl$a = ({
14722
14905
  objectId = -1
14723
14906
  } = getPlugin(drawingId, pluginId);
14724
14907
  const {
14725
- isHovered,
14726
- isSelected,
14908
+ isGHovered,
14909
+ isGSelected,
14910
+ isSHovered,
14911
+ isSSelected,
14727
14912
  handlers
14728
- } = useTreeObjSelection(drawingId, objectId);
14729
- const color = isHovered ? 0x28d79f : isSelected ? 0xa70b0b : 0x111111;
14913
+ } = useTreeObjInteraction(drawingId, objectId);
14914
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected) || 0x111111;
14730
14915
  return /*#__PURE__*/React__default.createElement(HUD, null, /*#__PURE__*/React__default.createElement(WorkPointObj, {
14731
14916
  drawingId: drawingId,
14732
14917
  objectId: objectId,
@@ -14882,12 +15067,11 @@ function createCSysParam(coordSystem) {
14882
15067
  return value;
14883
15068
  }
14884
15069
  function useCSysParam(drawingId, objId) {
14885
- // TODO: Fix lint error without disabling it
14886
- // eslint-disable-next-line react-hooks/exhaustive-deps
14887
- const coordSystem = useDrawing(drawingId, d => {
15070
+ const objCsys = useDrawing(drawingId, d => {
14888
15071
  var _d$structure$tree$obj;
14889
15072
  return (_d$structure$tree$obj = d.structure.tree[objId]) == null ? void 0 : _d$structure$tree$obj.coordinateSystem;
14890
- }) || [[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]];
15073
+ });
15074
+ const coordSystem = React__default.useMemo(() => objCsys || MathUtils.convertToCoordinateSystem(new Matrix4()), [objCsys]);
14891
15075
  const [userValue, setUserValue] = React__default.useState(createCSysParam(coordSystem));
14892
15076
  React__default.useEffect(() => {
14893
15077
  setUserValue(createCSysParam(coordSystem));
@@ -14924,7 +15108,7 @@ const typeCaptions = {
14924
15108
  [WorkCoordSystemType.WCS_XYAXISORIGIN]: 'Set'
14925
15109
  };
14926
15110
  const tolerance$1 = 1e-6;
14927
- const getObjectPosition = obj => {
15111
+ const getObjectPosition = (drawingId, obj) => {
14928
15112
  if (obj.position) {
14929
15113
  return obj.position.clone();
14930
15114
  }
@@ -14932,14 +15116,18 @@ const getObjectPosition = obj => {
14932
15116
  return obj.center.clone();
14933
15117
  }
14934
15118
  const members = obj.members;
14935
- return convertToVector((members == null ? void 0 : members.Position) || (members == null ? void 0 : members.pos));
15119
+ const pos = convertToVector((members == null ? void 0 : members.Position) || (members == null ? void 0 : members.pos));
15120
+ const matrix = getDrawing(drawingId).api.structure.calculateGlobalTransformation(obj.id);
15121
+ return pos.applyMatrix4(matrix);
14936
15122
  };
14937
- const getObjectDirection = obj => {
15123
+ const getObjectDirection = (drawingId, obj) => {
14938
15124
  if (obj.end) {
14939
15125
  return obj.end.clone().sub(obj.start).normalize();
14940
15126
  }
14941
15127
  const members = obj.members;
14942
- return convertToVector((members == null ? void 0 : members.Direction) || (members == null ? void 0 : members.direction)).normalize();
15128
+ const dir = convertToVector((members == null ? void 0 : members.Direction) || (members == null ? void 0 : members.direction)).normalize();
15129
+ const matrix = getDrawing(drawingId).api.structure.calculateGlobalTransformation(obj.id);
15130
+ return dir.applyMatrix4(matrix).normalize();
14943
15131
  };
14944
15132
  function RootImpl$b({
14945
15133
  drawingId,
@@ -15001,7 +15189,7 @@ function RootImpl$b({
15001
15189
  });
15002
15190
  return;
15003
15191
  }
15004
- originPos = getObjectPosition(origin);
15192
+ originPos = getObjectPosition(drawingId, origin);
15005
15193
  } else {
15006
15194
  originPos = new THREE.Vector3(csys.userValue[CSysRows.Position].x, csys.userValue[CSysRows.Position].y, csys.userValue[CSysRows.Position].z);
15007
15195
  }
@@ -15022,7 +15210,7 @@ function RootImpl$b({
15022
15210
  });
15023
15211
  return;
15024
15212
  }
15025
- xDir = getObjectDirection(primaryAxis);
15213
+ xDir = getObjectDirection(drawingId, primaryAxis);
15026
15214
  } else {
15027
15215
  xDir = new THREE.Vector3(csys.userValue[CSysRows.XAxis].x, csys.userValue[CSysRows.XAxis].y, csys.userValue[CSysRows.XAxis].z);
15028
15216
  }
@@ -15043,7 +15231,7 @@ function RootImpl$b({
15043
15231
  });
15044
15232
  return;
15045
15233
  }
15046
- yDir = getObjectDirection(secondaryAxis);
15234
+ yDir = getObjectDirection(drawingId, secondaryAxis);
15047
15235
  } else {
15048
15236
  yDir = new THREE.Vector3(csys.userValue[CSysRows.YAxis].x, csys.userValue[CSysRows.YAxis].y, csys.userValue[CSysRows.YAxis].z);
15049
15237
  }
@@ -15268,14 +15456,16 @@ function ViewImpl$9({
15268
15456
  return calcluateTransform(originPos_, xDir_, yDir_, offset, rotation, inverted);
15269
15457
  }, [originPos, xDir, yDir, offset, rotation, inverted]);
15270
15458
  const {
15271
- isHovered,
15272
- isSelected,
15459
+ isGHovered,
15460
+ isGSelected,
15461
+ isSHovered,
15462
+ isSSelected,
15273
15463
  handlers
15274
- } = useTreeObjSelection(drawingId, objectId);
15464
+ } = useTreeObjInteraction(drawingId, objectId);
15275
15465
 
15276
15466
  // This color is used only for the hovered and selected state,
15277
15467
  // undefined means default color which defined in Csys component.
15278
- const color = isHovered ? 0x28d79f : isSelected ? 0xa70b0b : undefined;
15468
+ const color = getHighlightedColor(isGHovered, isGSelected, isSHovered, isSSelected);
15279
15469
  return /*#__PURE__*/React__default.createElement(HUD, null, /*#__PURE__*/React__default.createElement("group", null, /*#__PURE__*/React__default.createElement(WorkCoordSystemObj, {
15280
15470
  drawingId: drawingId,
15281
15471
  objectId: objectId,
@@ -16253,6 +16443,7 @@ const CSysWrapper = ({
16253
16443
  } = userData;
16254
16444
  const currentNode = useDrawing(drawingId, drawing => drawing.structure.currentNode);
16255
16445
  const matrix = useCsysMatrix(drawingId, csysId, flip, reoriented);
16446
+ const activeColor = getHighlightedColor(false, false, false, true);
16256
16447
  const onPointerMove_ = React__default.useCallback(() => onPointerMove && onPointerMove(csysId, matePath), [onPointerMove, matePath, csysId]);
16257
16448
  const onPointerOut_ = React__default.useCallback(() => onPointerOut && onPointerOut(csysId, matePath), [onPointerOut, matePath, csysId]);
16258
16449
  return /*#__PURE__*/React__default.createElement(GlobalTransform, {
@@ -16263,7 +16454,7 @@ const CSysWrapper = ({
16263
16454
  matePath: matePath
16264
16455
  }, isSelected ? /*#__PURE__*/React__default.createElement(SelectedCsys, {
16265
16456
  matrix: matrix,
16266
- color: isActive ? 0xa70b0b : undefined,
16457
+ color: isActive ? activeColor : undefined,
16267
16458
  opacity: 1.0,
16268
16459
  userData: userData
16269
16460
  }) : /*#__PURE__*/React__default.createElement("group", {
@@ -16342,12 +16533,15 @@ const CSysDisplayImpl = ({
16342
16533
  }) => {
16343
16534
  // If we are in part mode, the products array contains the id of the CC_Part and no product references!
16344
16535
  // TODO: Split the products array into `products` and `productRefs` in the drawing state.
16345
- const currentNode = useDrawing(drawingId, drawing => drawing.structure.currentNode);
16346
- const rigidSets = useDrawing(drawingId, drawing => currentNode && drawing.structure.tree[currentNode].children);
16536
+ const currentNode = useDrawingCCId(drawingId, drawing => drawing.structure.currentNode);
16537
+ const rigidSets = useDrawingArr(drawingId, drawing => drawing.structure.tree[currentNode].children);
16347
16538
  const productIds = useDrawing(drawingId, drawing => drawing.structure.products);
16348
16539
  const selectors = useDrawing(drawingId, drawing => drawing.selection.refs);
16349
16540
  const activeSelector = useDrawing(drawingId, drawing => drawing.selection.active && drawing.selection.refs[drawing.selection.active]);
16350
- const [hoveredProductId, setHoveredProductId] = React__default.useState(undefined);
16541
+ const hoveredId = useDrawing(drawingId, drawing => {
16542
+ var _drawing$interaction$;
16543
+ return (_drawing$interaction$ = drawing.interaction.hovered) == null ? void 0 : _drawing$interaction$.prodRefId;
16544
+ }) || undefined;
16351
16545
  const [hoveredProductIds, setHoveredProductIds] = React__default.useState([]);
16352
16546
  const prevHoveredIdRef = React__default.useRef(undefined);
16353
16547
  const displayTimers = React__default.useRef({});
@@ -16368,21 +16562,21 @@ const CSysDisplayImpl = ({
16368
16562
  const timerKey = prevHoveredId.toString();
16369
16563
  displayTimers.current[timerKey] = timerId;
16370
16564
  }
16371
- prevHoveredIdRef.current = hoveredProductId;
16372
- if (hoveredProductId !== undefined) {
16565
+ prevHoveredIdRef.current = hoveredId;
16566
+ if (hoveredId !== undefined) {
16373
16567
  setHoveredProductIds(hoveredProductIds_ => {
16374
- if (hoveredProductIds_.indexOf(hoveredProductId) !== -1) {
16568
+ if (hoveredProductIds_.indexOf(hoveredId) !== -1) {
16375
16569
  return hoveredProductIds_;
16376
16570
  }
16377
- return [...hoveredProductIds_, hoveredProductId];
16571
+ return [...hoveredProductIds_, hoveredId];
16378
16572
  });
16379
- const timerKey = `${hoveredProductId}`;
16573
+ const timerKey = `${hoveredId}`;
16380
16574
  if (displayTimers.current[timerKey]) {
16381
16575
  window.clearTimeout(displayTimers.current[timerKey]);
16382
16576
  displayTimers.current[timerKey] = undefined;
16383
16577
  }
16384
16578
  }
16385
- }, [hoveredProductId]);
16579
+ }, [hoveredId]);
16386
16580
  const [hoveredCSysIds, setHoveredCSysIds] = React__default.useState([]);
16387
16581
  const onPointerMove = React__default.useCallback((csysId, matePath) => {
16388
16582
  setHoveredCSysIds(hoveredCSysIds_ => {
@@ -16425,13 +16619,17 @@ const CSysDisplayImpl = ({
16425
16619
  const activeSelItems = React__default.useMemo(() => {
16426
16620
  return activeSelector ? activeSelector.items.filter(item => item.scope === MateScope) : [];
16427
16621
  }, [activeSelector]);
16428
- const selRigidSets = React__default.useMemo(() => {
16622
+ const inactiveSelRS = React__default.useMemo(() => {
16429
16623
  return selItems.map(item => {
16624
+ if (activeSelItems.indexOf(item) !== -1) {
16625
+ // Obviously, if item is active, it (and it's rigidset) is not inactive. So it should be excluded from the array...
16626
+ return undefined;
16627
+ }
16430
16628
  const activeRefId = getActiveReference(drawingId, item.data.matePath, activeProducts);
16431
16629
  const rigidSet = activeRefId && rigidSets && getProductRigidSet(drawingId, activeRefId, rigidSets);
16432
16630
  return rigidSet;
16433
- });
16434
- }, [drawingId, activeProducts, rigidSets, selItems]);
16631
+ }).filter(id => id);
16632
+ }, [drawingId, activeProducts, rigidSets, selItems, activeSelItems]);
16435
16633
  const csysUDataArray = React__default.useMemo(() => {
16436
16634
  const csysUDataArray_ = [];
16437
16635
  const prToCsysMap = {};
@@ -16454,11 +16652,15 @@ const CSysDisplayImpl = ({
16454
16652
  onHUD: true
16455
16653
  });
16456
16654
  });
16655
+ if (hoveredOnly && !activeSelector) {
16656
+ // In hoveredOnly mode, only display inactive selected mates if no selector is active
16657
+ return csysUDataArray_;
16658
+ }
16457
16659
  const ids = hoveredOnly ? hoveredProductIds : activeProducts;
16458
16660
  ids == null ? void 0 : ids.forEach(id => {
16459
16661
  var _tree$id, _tree$id$members, _tree$id$members$prod, _tree$id2;
16460
- const rigidSet = rigidSets && getProductRigidSet(drawingId, id, rigidSets);
16461
- if (selRigidSets.indexOf(rigidSet) !== -1) {
16662
+ const rigidSet = getProductRigidSet(drawingId, id, rigidSets);
16663
+ if (rigidSet && inactiveSelRS.indexOf(rigidSet) !== -1) {
16462
16664
  return;
16463
16665
  }
16464
16666
  const matePath = getMatePath(drawingId, id);
@@ -16492,35 +16694,8 @@ const CSysDisplayImpl = ({
16492
16694
  });
16493
16695
  }
16494
16696
  return csysUDataArray_;
16495
- }, [drawingId, hoveredOnly, activeProducts, hoveredProductIds, hoveredCSysIds, selItems, activeSelItems, rigidSets, selRigidSets]);
16496
- const lnTh = useThree(state => {
16497
- var _state$raycaster$para;
16498
- return (_state$raycaster$para = state.raycaster.params.Line) == null ? void 0 : _state$raycaster$para.threshold;
16499
- });
16500
- const ptsTh = useThree(state => {
16501
- var _state$raycaster$para2;
16502
- return (_state$raycaster$para2 = state.raycaster.params.Points) == null ? void 0 : _state$raycaster$para2.threshold;
16503
- });
16504
- const {
16505
- camera,
16506
- size
16507
- } = useThree();
16508
- const {
16509
- lineThreshold,
16510
- pointThreshold
16511
- } = React__default.useMemo(() => {
16512
- return {
16513
- lineThreshold: lnTh || CameraHelper.calculateScaleFactor(camera.position, 4, camera, size),
16514
- pointThreshold: ptsTh || CameraHelper.calculateScaleFactor(camera.position, 6, camera, size)
16515
- };
16516
- }, [camera, size, lnTh, ptsTh]);
16517
- const onInfiniteMove = React__default.useCallback(e => {
16518
- const geom = findBuerliGeometry(e, lineThreshold, pointThreshold)[0];
16519
- setHoveredProductId(geom == null ? void 0 : geom.productId);
16520
- }, [setHoveredProductId, lineThreshold, pointThreshold]);
16521
- return /*#__PURE__*/React__default.createElement(HUD, null, /*#__PURE__*/React__default.createElement("infinityPlane", {
16522
- onPointerMove: onInfiniteMove
16523
- }), /*#__PURE__*/React__default.createElement("group", null, csysUDataArray.map(userData => /*#__PURE__*/React__default.createElement(CSysWrapper, {
16697
+ }, [drawingId, hoveredOnly, activeProducts, hoveredProductIds, hoveredCSysIds, activeSelector, selItems, activeSelItems, rigidSets, inactiveSelRS]);
16698
+ return /*#__PURE__*/React__default.createElement(HUD, null, /*#__PURE__*/React__default.createElement("group", null, csysUDataArray.map(userData => /*#__PURE__*/React__default.createElement(CSysWrapper, {
16524
16699
  key: getCSysKey$1(userData),
16525
16700
  drawingId: drawingId,
16526
16701
  csys: csys,
@@ -16557,7 +16732,7 @@ const SelectableMate = ({
16557
16732
  isSelected,
16558
16733
  handlers
16559
16734
  } = useMateSelection(drawingId, matePath, csysId);
16560
- const color = isHovered ? 0x28d79f : isSelected ? 0xa70b0b : undefined;
16735
+ const color = getHighlightedColor(false, false, isHovered, isSelected);
16561
16736
  return /*#__PURE__*/React__default.createElement(Csys, {
16562
16737
  matrix: matrix,
16563
16738
  opacity: 1.0,
@@ -19366,6 +19541,18 @@ class OutlineEffect extends Effect {
19366
19541
  this.outlinePass.render(renderer, null, this.outlineRT);
19367
19542
  };
19368
19543
  }
19544
+ set edgeColor1(value) {
19545
+ const uniform = this.uniforms.get('edgeColor1');
19546
+ uniform.value = new THREE.Color(value);
19547
+ }
19548
+ set edgeColor2(value) {
19549
+ const uniform = this.uniforms.get('edgeColor2');
19550
+ uniform.value = new THREE.Color(value);
19551
+ }
19552
+ set edgeColor3(value) {
19553
+ const uniform = this.uniforms.get('edgeColor3');
19554
+ uniform.value = new THREE.Color(value);
19555
+ }
19369
19556
  set selectionLayer(value) {
19370
19557
  this.selections1.forEach(selection => {
19371
19558
  selection.layer = value;
@@ -19472,7 +19659,9 @@ const Outline = /*#__PURE__*/React__default.forwardRef(function Outline(_ref, fo
19472
19659
  width,
19473
19660
  height,
19474
19661
  kernelSize
19475
- }), [scene, camera, edgeStrength, edgeColor1, edgeColor2, edgeColor3, width, height, kernelSize]);
19662
+ }),
19663
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19664
+ [scene, camera, edgeStrength, width, height, kernelSize]);
19476
19665
  React__default.useEffect(() => {
19477
19666
  if (selections1) {
19478
19667
  effect.selections1 = selections1.map(selection => new Selection(selection, selectionLayer));
@@ -19509,6 +19698,27 @@ const Outline = /*#__PURE__*/React__default.forwardRef(function Outline(_ref, fo
19509
19698
  }
19510
19699
  // eslint-disable-next-line react-hooks/exhaustive-deps
19511
19700
  }, [effect, selections3]);
19701
+ React__default.useEffect(() => {
19702
+ if (edgeColor1) {
19703
+ effect.edgeColor1 = edgeColor1;
19704
+ invalidate();
19705
+ }
19706
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19707
+ }, [effect, edgeColor1]);
19708
+ React__default.useEffect(() => {
19709
+ if (edgeColor2) {
19710
+ effect.edgeColor2 = edgeColor2;
19711
+ invalidate();
19712
+ }
19713
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19714
+ }, [effect, edgeColor2]);
19715
+ React__default.useEffect(() => {
19716
+ if (edgeColor3) {
19717
+ effect.edgeColor3 = edgeColor3;
19718
+ invalidate();
19719
+ }
19720
+ // eslint-disable-next-line react-hooks/exhaustive-deps
19721
+ }, [effect, edgeColor3]);
19512
19722
  React__default.useEffect(() => {
19513
19723
  effect.selectionLayer = selectionLayer;
19514
19724
  invalidate();
@@ -20899,71 +21109,27 @@ const Feature = ({
20899
21109
  });
20900
21110
  const visible = useDrawing(drawingId, d => d.plugin.visible.indexOf(featureId) >= 0);
20901
21111
  const {
21112
+ isGHovered,
21113
+ isGSelected,
21114
+ isSHovered,
20902
21115
  handlers
20903
- } = useTreeObjSelection(drawingId, featureId);
21116
+ } = useTreeObjInteraction(drawingId, featureId);
20904
21117
  const onTreeObjClick = handlers.onClick;
20905
21118
  const onTreeObjPointerOver = handlers.onPointerOver;
20906
21119
  const onTreeObjPointerOut = handlers.onPointerOut;
20907
- const selected = useDrawing(drawingId, d => d.interaction.selected);
20908
- const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.objectId)) || [];
20909
- const isHovered = useDrawing(drawingId, d => {
20910
- var _d$interaction$hovere;
20911
- return ((_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.objectId) === featureId;
20912
- });
20913
- const isSelected = (selectedIds == null ? void 0 : selectedIds.indexOf(featureId)) !== -1;
20914
- const isHighlighted = isHovered || isSelected;
21120
+ const isHovered = isGHovered || isSHovered;
21121
+ const isHighlighted = isHovered || isGSelected;
20915
21122
  const hasGraphics = useHasView(drawingId, featureId);
20916
21123
  const isActive = useDrawing(drawingId, d => d.plugin.active.feature === featureId);
20917
21124
  const isCustom = useIsCustom(drawingId, featureRefId);
20918
21125
  const disabled = useIsDisabled(drawingId, featureId);
20919
21126
  const errorId = usePrecheckErrorId(drawingId, featureId);
20920
21127
  const [rename, setRename] = React__default.useState(false);
20921
- const onClick = React__default.useCallback(e => {
20922
- const drawing = getDrawing(drawingId);
20923
- const isSelActive = drawing.selection.active !== null;
20924
- if (isSelActive && onTreeObjClick) {
20925
- onTreeObjClick(e);
20926
- return;
20927
- }
20928
- const select = drawing.api.interaction.select;
20929
- const multi = e.shiftKey;
20930
- const curNodeId = drawing.structure.currentNode;
20931
- const curProdId = drawing.structure.currentProduct;
20932
- select(createInfo({
20933
- objectId: featureId,
20934
- prodRefId: curNodeId || curProdId
20935
- }), multi);
20936
- }, [drawingId, featureId, onTreeObjClick]);
20937
21128
  const onDoubleClick = React__default.useCallback(() => {
20938
21129
  if (!disabled) {
20939
21130
  getDrawing(drawingId).api.plugin.setActiveFeature(featureId);
20940
21131
  }
20941
21132
  }, [disabled, featureId, drawingId]);
20942
- const onMouseEnter = React__default.useCallback(e => {
20943
- const drawing = getDrawing(drawingId);
20944
- const isSelActive = drawing.selection.active !== null;
20945
- if (isSelActive && onTreeObjPointerOver) {
20946
- onTreeObjPointerOver(e);
20947
- return;
20948
- }
20949
- const setHovered = drawing.api.interaction.setHovered;
20950
- const curNodeId = drawing.structure.currentNode;
20951
- const curProdId = drawing.structure.currentProduct;
20952
- setHovered(createInfo({
20953
- objectId: featureId,
20954
- prodRefId: curNodeId || curProdId
20955
- }));
20956
- }, [drawingId, featureId, onTreeObjPointerOver]);
20957
- const onMouseLeave = React__default.useCallback(e => {
20958
- const drawing = getDrawing(drawingId);
20959
- const isSelActive = drawing.selection.active !== null;
20960
- if (isSelActive && onTreeObjPointerOut) {
20961
- onTreeObjPointerOut(e);
20962
- return;
20963
- }
20964
- const setHovered = drawing.api.interaction.setHovered;
20965
- setHovered(null);
20966
- }, [drawingId, onTreeObjPointerOut]);
20967
21133
  const nameComponent = rename ? /*#__PURE__*/React__default.createElement(NameEdit, {
20968
21134
  drawingId: drawingId,
20969
21135
  objId: featureId,
@@ -21010,10 +21176,10 @@ const Feature = ({
21010
21176
  hovered: isHighlighted,
21011
21177
  bordered: true,
21012
21178
  title: String(featureId),
21013
- onClick: onClick,
21179
+ onClick: onTreeObjClick,
21014
21180
  onDoubleClick: onDoubleClick,
21015
- onMouseEnter: onMouseEnter,
21016
- onMouseLeave: onMouseLeave
21181
+ onMouseEnter: onTreeObjPointerOver,
21182
+ onMouseLeave: onTreeObjPointerOut
21017
21183
  }, /*#__PURE__*/React__default.createElement("div", {
21018
21184
  style: {
21019
21185
  display: 'flex',
@@ -21258,7 +21424,7 @@ const NodeTitle = ({
21258
21424
  return ((_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.objectId) === refId;
21259
21425
  });
21260
21426
  const selected = useDrawing(drawingId, d => d.interaction.selected);
21261
- const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.objectId)) || [];
21427
+ const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.prodRefId || -1)) || [];
21262
21428
  const reference = useDrawing(drawingId, d => d.structure.tree[refId]);
21263
21429
  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;
21264
21430
  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;
@@ -22029,17 +22195,17 @@ const Solid = ({
22029
22195
  }) => {
22030
22196
  const hoveredId = useDrawing(drawingId, d => {
22031
22197
  var _d$interaction$hovere;
22032
- return (_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.graphicId;
22198
+ return (_d$interaction$hovere = d.interaction.hovered) == null ? void 0 : _d$interaction$hovere.containerId;
22033
22199
  });
22034
22200
  const selected = useDrawing(drawingId, d => d.interaction.selected);
22035
- const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.graphicId)) || [];
22201
+ const selectedIds = (selected == null ? void 0 : selected.map(sel => sel.containerId || -1)) || [];
22036
22202
  const solidOwner = useDrawingCCId(drawingId, d => {
22037
22203
  var _d$graphic$containers;
22038
22204
  return (_d$graphic$containers = d.graphic.containers[solidId]) == null ? void 0 : _d$graphic$containers.owner;
22039
22205
  });
22040
22206
  const ccSolid = useDrawing(drawingId, d => d.structure.tree[solidOwner]);
22041
22207
  const isHovered = hoveredId === solidId;
22042
- const isSelected = (selectedIds == null ? void 0 : selectedIds.indexOf(solidId)) !== -1;
22208
+ const isSelected = selectedIds.indexOf(solidId) !== -1;
22043
22209
  const isHighlighted = isHovered || isSelected;
22044
22210
  const [rename, setRename] = React__default.useState(false);
22045
22211
  const onClick = React__default.useCallback(e => {
@@ -22277,6 +22443,14 @@ const PartModeCmds = (drawingId, rootId) => {
22277
22443
  const featureApi = ccAPI.feature;
22278
22444
  const pluginApi = getDrawing(drawingId).api.plugin;
22279
22445
  const wrapper = cmd => async () => {
22446
+ const activePlugin = getDrawing(drawingId).plugin.active.feature;
22447
+ if (activePlugin) {
22448
+ showMessage({
22449
+ text: 'Error while attempting to create a new feature: there should be no active feature plugin!',
22450
+ type: 'error'
22451
+ });
22452
+ return;
22453
+ }
22280
22454
  const res = await cmd().catch(console.warn);
22281
22455
  if (res && res.errors && res.errors.length === 0 && res.results[0].result !== null) {
22282
22456
  pluginApi.setActiveFeature(res.results[0].result);
@@ -22455,6 +22629,14 @@ const AssemblyModeCmds = (drawingId, rootId) => {
22455
22629
  const assemblyApi = ccAPI.assemblyBuilder;
22456
22630
  const pluginApi = getDrawing(drawingId).api.plugin;
22457
22631
  const wrapper = cmd => async () => {
22632
+ const activePlugin = getDrawing(drawingId).plugin.active.feature;
22633
+ if (activePlugin) {
22634
+ showMessage({
22635
+ text: 'Error while attempting to create a new constraint: there should be no active feature plugin!',
22636
+ type: 'error'
22637
+ });
22638
+ return;
22639
+ }
22458
22640
  const res = await cmd().catch(console.warn);
22459
22641
  if (res && res.errors && res.errors.length === 0 && res.results[0].result !== null) {
22460
22642
  pluginApi.setActiveFeature(res.results[0].result);
@@ -22924,4 +23106,4 @@ const Drawing = ({
22924
23106
  })), /*#__PURE__*/React__default.createElement(BlankDiv, null));
22925
23107
  };
22926
23108
 
22927
- export { index$x as Boolean, index$a as BoundingBoxInfo, index$u as Box, CADApi, CSysDisplay, index$p as Chamfer, index$i as CircularPattern, index$r as Cone, Constraints, index$s as Cylinder, index$4 as Cylindrical, index$y as Dimensions, Drawing, index$9 as Expressions, index$w as Extrusion, index$7 as Fastened, index$8 as FastenedOrigin, FeaturePlugin, index$q as Fillet, FtVisibilityController$1 as FtVisibilityController, GlobalPlugins, HUD, HoveredConstraintDisplay, index$1 as Import, index$j as LinearPattern, index$g as Measure, Menu, Messages, index$h as Mirror, ModelTree, Outline, index$2 as Parallel, index$3 as Planar, index as ProductManagement, Readfile$1 as Readfile, index$5 as Revolute, index$v as Revolve, index$n as Rotate, SelectedMateObj, SideBar, index$f as Sketch, index$l as Slice, index$k as SliceBySheet, index$6 as Slider, Solids, index$t as Sphere, ToolBar, index$m as TransformByCsys, index$o as Translate, ViewOptionButtons, ViewPlugButtons, index$e as WorkAxis, WorkAxisObj, index$b as WorkCoordSystem, WorkCoordSystemObj, index$d as WorkPlane, WorkPlaneObj, index$c as WorkPoint, WorkPointObj, getCADState, getMateRefIds, useAllObjects, useCADStore, useHasPending, useIsLoading };
23109
+ export { index$x as Boolean, index$a as BoundingBoxInfo, index$u as Box, CADApi, CSysDisplay, index$p as Chamfer, index$i as CircularPattern, index$r as Cone, Constraints, index$s as Cylinder, index$4 as Cylindrical, index$y as Dimensions, Drawing, index$9 as Expressions, index$w as Extrusion, index$7 as Fastened, index$8 as FastenedOrigin, FeaturePlugin, index$q as Fillet, FtVisibilityController$1 as FtVisibilityController, GlobalPlugins, HUD, HoveredConstraintDisplay, index$1 as Import, index$j as LinearPattern, MateScope, index$g as Measure, Menu, Messages, index$h as Mirror, ModelTree, Outline, index$2 as Parallel, index$3 as Planar, index as ProductManagement, Readfile$1 as Readfile, index$5 as Revolute, index$v as Revolve, index$n as Rotate, SelectedMateObj, SideBar, index$f as Sketch, index$l as Slice, index$k as SliceBySheet, index$6 as Slider, Solids, index$t as Sphere, ToolBar, index$m as TransformByCsys, index$o as Translate, TreeObjScope, ViewOptionButtons, ViewPlugButtons, index$e as WorkAxis, WorkAxisObj, index$b as WorkCoordSystem, WorkCoordSystemObj, index$d as WorkPlane, WorkPlaneObj, index$c as WorkPoint, WorkPointObj, getCADState, getMateRefIds, useAllObjects, useCADStore, useHasPending, useIsLoading };