@shapediver/viewer.features.drawing-tools 3.1.2 → 3.2.0

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.
Files changed (80) hide show
  1. package/dist/api/implementation/DrawingToolsApi.d.ts.map +1 -1
  2. package/dist/api/implementation/DrawingToolsApi.js +0 -6
  3. package/dist/api/implementation/DrawingToolsApi.js.map +1 -1
  4. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.d.ts +4 -2
  5. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.d.ts.map +1 -1
  6. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.js +17 -11
  7. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.js.map +1 -1
  8. package/dist/api/implementation/restrictions/plane/snap/AxisRestrictionApi.d.ts +7 -0
  9. package/dist/api/implementation/restrictions/plane/snap/AxisRestrictionApi.d.ts.map +1 -0
  10. package/dist/api/implementation/restrictions/{axis → plane/snap}/AxisRestrictionApi.js +2 -2
  11. package/dist/api/implementation/restrictions/plane/snap/AxisRestrictionApi.js.map +1 -0
  12. package/dist/api/interfaces/IDrawingToolsApi.d.ts +1 -2
  13. package/dist/api/interfaces/IDrawingToolsApi.d.ts.map +1 -1
  14. package/dist/business/implementation/DrawingToolsManager.d.ts.map +1 -1
  15. package/dist/business/implementation/DrawingToolsManager.js +0 -1
  16. package/dist/business/implementation/DrawingToolsManager.js.map +1 -1
  17. package/dist/business/implementation/managers/TextVisualizationManager.d.ts.map +1 -1
  18. package/dist/business/implementation/managers/TextVisualizationManager.js +52 -28
  19. package/dist/business/implementation/managers/TextVisualizationManager.js.map +1 -1
  20. package/dist/business/implementation/managers/geometry/GeometryMathManager.d.ts +17 -8
  21. package/dist/business/implementation/managers/geometry/GeometryMathManager.d.ts.map +1 -1
  22. package/dist/business/implementation/managers/geometry/GeometryMathManager.js +31 -16
  23. package/dist/business/implementation/managers/geometry/GeometryMathManager.js.map +1 -1
  24. package/dist/business/implementation/managers/interaction/RestrictionManager.d.ts.map +1 -1
  25. package/dist/business/implementation/managers/interaction/RestrictionManager.js +0 -4
  26. package/dist/business/implementation/managers/interaction/RestrictionManager.js.map +1 -1
  27. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.d.ts +8 -0
  28. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.d.ts.map +1 -1
  29. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.js +107 -43
  30. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.js.map +1 -1
  31. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.d.ts +3 -2
  32. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.d.ts.map +1 -1
  33. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.js +38 -29
  34. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.js.map +1 -1
  35. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AxisRestriction.d.ts +26 -0
  36. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AxisRestriction.d.ts.map +1 -0
  37. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AxisRestriction.js +93 -0
  38. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AxisRestriction.js.map +1 -0
  39. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.d.ts +4 -2
  40. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.d.ts.map +1 -1
  41. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.js +18 -34
  42. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.js.map +1 -1
  43. package/dist/business/interfaces/IDrawingToolsManager.d.ts +2 -3
  44. package/dist/business/interfaces/IDrawingToolsManager.d.ts.map +1 -1
  45. package/dist/business/interfaces/IDrawingToolsManager.js.map +1 -1
  46. package/dist/business/interfaces/IRestriction.d.ts +0 -1
  47. package/dist/business/interfaces/IRestriction.d.ts.map +1 -1
  48. package/dist/business/interfaces/IRestriction.js +0 -1
  49. package/dist/business/interfaces/IRestriction.js.map +1 -1
  50. package/dist/business/interfaces/ISnapRestriction.d.ts +7 -5
  51. package/dist/business/interfaces/ISnapRestriction.d.ts.map +1 -1
  52. package/dist/index.d.ts +2 -2
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +1 -1
  55. package/dist/index.js.map +1 -1
  56. package/package.json +9 -9
  57. package/src/api/implementation/DrawingToolsApi.ts +1 -6
  58. package/src/api/implementation/restrictions/plane/PlaneRestrictionApi.ts +19 -12
  59. package/src/api/implementation/restrictions/{axis → plane/snap}/AxisRestrictionApi.ts +3 -3
  60. package/src/api/interfaces/IDrawingToolsApi.ts +1 -2
  61. package/src/business/implementation/DrawingToolsManager.ts +0 -1
  62. package/src/business/implementation/managers/TextVisualizationManager.ts +52 -28
  63. package/src/business/implementation/managers/geometry/GeometryMathManager.ts +36 -20
  64. package/src/business/implementation/managers/interaction/RestrictionManager.ts +0 -3
  65. package/src/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.ts +127 -47
  66. package/src/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.ts +38 -28
  67. package/src/business/implementation/managers/interaction/restrictions/plane/snap/AxisRestriction.ts +116 -0
  68. package/src/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.ts +21 -37
  69. package/src/business/interfaces/IDrawingToolsManager.ts +2 -3
  70. package/src/business/interfaces/IRestriction.ts +0 -1
  71. package/src/business/interfaces/ISnapRestriction.ts +9 -9
  72. package/src/index.ts +4 -4
  73. package/dist/api/implementation/restrictions/axis/AxisRestrictionApi.d.ts +0 -7
  74. package/dist/api/implementation/restrictions/axis/AxisRestrictionApi.d.ts.map +0 -1
  75. package/dist/api/implementation/restrictions/axis/AxisRestrictionApi.js.map +0 -1
  76. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.d.ts +0 -22
  77. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.d.ts.map +0 -1
  78. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.js +0 -96
  79. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.js.map +0 -1
  80. package/src/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.ts +0 -107
@@ -1,8 +1,15 @@
1
1
  import { AbstractRestriction } from '../AbstractRestriction';
2
2
  import { AngularRestriction, AngularRestrictionProperties } from './snap/AngularRestriction';
3
+ import { AxisRestriction, AxisRestrictionProperties } from './snap/AxisRestriction';
4
+ import {
5
+ CAMERA_TYPE,
6
+ ICameraApi,
7
+ IOrthographicCameraApi,
8
+ ORTHOGRAPHIC_CAMERA_DIRECTION
9
+ } from '@shapediver/viewer';
3
10
  import { DrawingToolsManager } from '../../../../DrawingToolsManager';
4
11
  import { GridRestriction, GridRestrictionProperties } from './snap/GridRestriction';
5
- import { IRay } from '@shapediver/viewer.features.interaction';
12
+ import { IRay, IViewportApi } from '@shapediver/viewer.features.interaction';
6
13
  import { IRestriction, RestrictionMetaData, RestrictionProperties } from '../../../../../interfaces/IRestriction';
7
14
  import { ISnapRestriction } from '../../../../../interfaces/ISnapRestriction';
8
15
  import { mat4, vec3 } from 'gl-matrix';
@@ -39,6 +46,11 @@ export type PlaneRestrictionProperties = {
39
46
  * angular snap restriction
40
47
  */
41
48
  angularSnapRestriction?: AngularRestrictionProperties;
49
+
50
+ /**
51
+ * axis snap restriction
52
+ */
53
+ axisSnapRestriction?: AxisRestrictionProperties;
42
54
  } & RestrictionProperties;
43
55
 
44
56
  // #endregion Type aliases (1)
@@ -46,56 +58,61 @@ export type PlaneRestrictionProperties = {
46
58
  // #region Classes (1)
47
59
 
48
60
  export class PlaneRestriction extends AbstractRestriction implements IRestriction {
49
- // #region Properties (10)
61
+ // #region Properties (14)
50
62
 
63
+ readonly #properties: PlaneRestrictionProperties;
51
64
  readonly #uuidGenerator = UuidGenerator.instance;
65
+ readonly #viewport: IViewportApi;
52
66
 
53
67
  #angularRestriction: AngularRestriction;
68
+ #axisRestriction: AxisRestriction;
69
+ #cameraId: string = '';
54
70
  #gridRestriction: GridRestriction;
55
- #normal: vec3;
56
- #origin: vec3;
71
+ #normal: vec3 = vec3.create();
72
+ #origin: vec3 = vec3.create();
57
73
  #snapRestrictions: { [key: string]: ISnapRestriction };
58
74
  #transformationFromXYPlaneMatrix: mat4 = mat4.create();
59
75
  #transformationToXYPlaneMatrix: mat4 = mat4.create();
60
- #vectorU: vec3;
61
- #vectorV: vec3;
76
+ #vectorU: vec3 = vec3.create();
77
+ #vectorV: vec3 = vec3.create();
62
78
 
63
- // #endregion Properties (10)
79
+ // #endregion Properties (14)
64
80
 
65
81
  // #region Constructors (1)
66
82
 
67
83
  constructor(drawingToolsManager: DrawingToolsManager, id: string, properties: PlaneRestrictionProperties) {
68
84
  super(drawingToolsManager, id);
69
- properties.vector_u = properties.vector_u ? vec3.normalize(vec3.create(), properties.vector_u) : vec3.fromValues(1, 0, 0);
70
- properties.vector_v = properties.vector_v ? vec3.normalize(vec3.create(), properties.vector_v) : vec3.fromValues(0, 1, 0);
71
85
 
72
- this.#normal = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), properties.vector_u, properties.vector_v));
73
- if (vec3.dot(properties.vector_u, properties.vector_v) !== 0)
74
- properties.vector_v = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), this.#normal, properties.vector_u));
86
+ this.#viewport = drawingToolsManager.viewport;
87
+ this.#cameraId = this.#viewport.camera!.id;
75
88
 
76
- this.#vectorU = properties.vector_u;
77
- this.#vectorV = properties.vector_v;
78
- this.#origin = properties.origin || vec3.create();
89
+ this.#properties = properties;
79
90
 
80
- this.createTransformationMatrices();
91
+ this.#gridRestriction = new GridRestriction(drawingToolsManager, this, this.#properties.gridSnapRestriction);
92
+ this.#angularRestriction = new AngularRestriction(drawingToolsManager, this, this.#properties.angularSnapRestriction);
93
+ this.#axisRestriction = new AxisRestriction(drawingToolsManager, this, this.#properties.axisSnapRestriction);
81
94
 
82
- this.#gridRestriction = new GridRestriction(drawingToolsManager, this, properties.gridSnapRestriction);
83
- this.#angularRestriction = new AngularRestriction(drawingToolsManager, this, properties.angularSnapRestriction);
95
+ this.updatePlaneDefinition();
84
96
 
85
97
  this.#snapRestrictions = {
86
98
  grid: this.#gridRestriction,
87
- angular: this.#angularRestriction
99
+ angular: this.#angularRestriction,
100
+ axis: this.#axisRestriction
88
101
  };
89
102
  }
90
103
 
91
104
  // #endregion Constructors (1)
92
105
 
93
- // #region Public Getters And Setters (13)
106
+ // #region Public Getters And Setters (14)
94
107
 
95
108
  public get angularRestriction(): AngularRestriction {
96
109
  return this.#angularRestriction;
97
110
  }
98
111
 
112
+ public get axisRestriction(): AxisRestriction {
113
+ return this.#axisRestriction;
114
+ }
115
+
99
116
  public get gridRestriction(): GridRestriction {
100
117
  return this.#gridRestriction;
101
118
  }
@@ -110,8 +127,7 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
110
127
 
111
128
  public set origin(value: vec3) {
112
129
  this.#origin = value;
113
- this.#gridRestriction.updatePlaneDefinition(this.#origin, this.#vectorU, this.#vectorV, this.#normal);
114
- this.createTransformationMatrices();
130
+ this.updatePlaneDefinition();
115
131
  }
116
132
 
117
133
  public get priority(): number {
@@ -135,15 +151,8 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
135
151
  }
136
152
 
137
153
  public set vectorU(value: vec3) {
138
- this.#vectorU = value;
139
- this.#normal = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), this.#vectorU, this.#vectorV));
140
-
141
- if (vec3.dot(this.#vectorU, this.#vectorV) !== 0)
142
- this.#vectorV = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), this.#normal, this.#vectorU));
143
-
144
- this.createTransformationMatrices();
145
- this.#gridRestriction.updatePlaneDefinition(this.#origin, this.#vectorU, this.#vectorV, this.#normal);
146
- this.#angularRestriction.updatePlaneDefinition(this.#origin, this.#vectorU, this.#vectorV, this.#normal);
154
+ this.#properties.vector_u = value;
155
+ this.updatePlaneDefinition();
147
156
  }
148
157
 
149
158
  public get vectorV(): vec3 {
@@ -151,24 +160,19 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
151
160
  }
152
161
 
153
162
  public set vectorV(value: vec3) {
154
- this.#vectorV = value;
155
- this.#normal = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), this.#vectorU, this.#vectorV));
156
-
157
- if (vec3.dot(this.#vectorU, this.#vectorV) !== 0)
158
- this.#vectorV = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), this.#normal, this.#vectorU));
159
-
160
- this.createTransformationMatrices();
161
- this.#gridRestriction.updatePlaneDefinition(this.#origin, this.#vectorU, this.#vectorV, this.#normal);
162
- this.#angularRestriction.updatePlaneDefinition(this.#origin, this.#vectorU, this.#vectorV, this.#normal);
163
+ this.#properties.vector_v = value;
164
+ this.updatePlaneDefinition();
163
165
  }
164
166
 
165
- // #endregion Public Getters And Setters (13)
167
+ // #endregion Public Getters And Setters (14)
166
168
 
167
169
  // #region Public Methods (1)
168
170
 
169
171
  public rayTrace(ray: IRay, metaData?: RestrictionMetaData): vec3 | undefined {
170
172
  if (this.enabled === false) return vec3.create();
171
173
 
174
+ if (this.#cameraId !== this.#viewport.camera!.id) this.updatePlaneDefinition();
175
+
172
176
  let origin = this.#origin;
173
177
  if (metaData?.referencePoint)
174
178
  origin = vec3.sub(vec3.create(), this.#origin, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), this.#origin, metaData.referencePoint), this.#normal)));
@@ -176,7 +180,7 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
176
180
  // find intersection of ray and plane
177
181
  const t = (vec3.dot(origin, this.#normal) - vec3.dot(ray.origin, this.#normal)) / vec3.dot(ray.direction, this.#normal);
178
182
  const intersection = vec3.add(vec3.create(), ray.origin, vec3.multiply(vec3.create(), ray.direction, vec3.fromValues(t, t, t)));
179
- return this.snap(intersection, metaData);
183
+ return this.snap(ray, intersection, metaData);
180
184
  }
181
185
 
182
186
  // #endregion Public Methods (1)
@@ -187,7 +191,28 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
187
191
 
188
192
  // #endregion Protected Methods (1)
189
193
 
190
- // #region Private Methods (2)
194
+ // #region Private Methods (4)
195
+
196
+ private createDefaultPlane(camera: ICameraApi): void {
197
+ if (camera.type === CAMERA_TYPE.PERSPECTIVE ||
198
+ (camera.type === CAMERA_TYPE.ORTHOGRAPHIC && (camera as IOrthographicCameraApi).direction === ORTHOGRAPHIC_CAMERA_DIRECTION.CUSTOM)) {
199
+ this.#vectorU = vec3.fromValues(1, 0, 0);
200
+ this.#vectorV = vec3.fromValues(0, 1, 0);
201
+ this.#normal = vec3.fromValues(0, 0, 1);
202
+ this.#origin = vec3.fromValues(0, 0, 0);
203
+ } else {
204
+ const orthographicCamera = camera as IOrthographicCameraApi;
205
+ const direction = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), orthographicCamera.target, orthographicCamera.position));
206
+ const up =
207
+ orthographicCamera.direction === ORTHOGRAPHIC_CAMERA_DIRECTION.TOP || orthographicCamera.direction === ORTHOGRAPHIC_CAMERA_DIRECTION.BOTTOM ?
208
+ vec3.fromValues(0, 1, 0) : vec3.fromValues(0, 0, 1);
209
+
210
+ this.#origin = vec3.fromValues(0, 0, 0);
211
+ this.#normal = vec3.negate(vec3.create(), direction);
212
+ this.#vectorU = vec3.clone(up);
213
+ this.#vectorV = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), this.#normal, this.#vectorU));
214
+ }
215
+ }
191
216
 
192
217
  private createTransformationMatrices(): void {
193
218
  // Calculate the transformation matrix for the rotation
@@ -198,7 +223,10 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
198
223
  0, 0, 0, 1
199
224
  );
200
225
 
201
- const rotationMatrixInverse = mat4.invert(mat4.create(), rotationMatrix);
226
+ let rotationMatrixInverse = mat4.invert(mat4.create(), rotationMatrix);
227
+ if (!rotationMatrixInverse)
228
+ rotationMatrixInverse = mat4.create();
229
+
202
230
  const pivotMatrix = mat4.fromTranslation(mat4.create(), vec3.fromValues(this.#origin[0], this.#origin[1], this.#origin[2]));
203
231
  const pivotMatrixInverse = mat4.fromTranslation(mat4.create(), vec3.fromValues(-this.#origin[0], -this.#origin[1], -this.#origin[2]));
204
232
 
@@ -209,9 +237,11 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
209
237
  mat4.multiply(this.#transformationFromXYPlaneMatrix, this.#transformationFromXYPlaneMatrix, pivotMatrixInverse);
210
238
  }
211
239
 
212
- private snap(point: vec3, metaData?: RestrictionMetaData): vec3 | undefined {
240
+ private snap(ray: IRay, point: vec3, metaData?: RestrictionMetaData): vec3 | undefined {
213
241
  if (this.enabled === false) return;
214
242
 
243
+ if (this.#cameraId !== this.#viewport.camera!.id) this.updatePlaneDefinition();
244
+
215
245
  const sortedSnapRestrictions = Object.values(this.#snapRestrictions).sort((a, b) => b.priority - a.priority);
216
246
 
217
247
  // group snap restrictions by priority
@@ -225,7 +255,7 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
225
255
  for (const snapRestrictions of Object.values(groupedSnapRestrictions)) {
226
256
  const results = [];
227
257
  for (const snapRestriction of snapRestrictions) {
228
- results.push(snapRestriction.snap(point, metaData));
258
+ results.push(snapRestriction.snap(ray, point, metaData));
229
259
  }
230
260
 
231
261
  const indexedResults = results.map((value, index) => ({ index, value }));
@@ -251,7 +281,57 @@ export class PlaneRestriction extends AbstractRestriction implements IRestrictio
251
281
  return point;
252
282
  }
253
283
 
254
- // #endregion Private Methods (2)
284
+ private updatePlaneDefinition(): void {
285
+ const camera = this.#viewport.camera!;
286
+ this.#cameraId = camera!.id;
287
+
288
+ const origin = this.#properties.origin ? vec3.clone(this.#properties.origin) : undefined;
289
+ const vectorU = this.#properties.vector_u ? vec3.clone(this.#properties.vector_u) : undefined;
290
+ const vectorV = this.#properties.vector_v ? vec3.clone(this.#properties.vector_v) : undefined;
291
+
292
+ const planeDefined = origin && vectorU && vectorV;
293
+
294
+ let normal = vec3.fromValues(0, 0, 1);
295
+
296
+ if (planeDefined) {
297
+ vec3.normalize(vectorU, vectorU);
298
+ vec3.normalize(vectorV, vectorV);
299
+
300
+ normal = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), vectorU, vectorV));
301
+ if (vec3.dot(vectorU, vectorV) !== 0)
302
+ vec3.normalize(vectorV, vec3.cross(vec3.create(), normal, vectorU));
303
+
304
+ if (camera.type === CAMERA_TYPE.ORTHOGRAPHIC) {
305
+ const cameraApi = camera as IOrthographicCameraApi;
306
+ const cameraDirection = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), cameraApi.target, cameraApi.position));
307
+
308
+ // if the dot product of the camera direction and the normal tells us that they are parallel
309
+ // the plane is perpendicular to the camera direction
310
+ if (Math.abs(vec3.dot(cameraDirection, normal)) < 0.0001) {
311
+ this.createDefaultPlane(camera);
312
+ } else {
313
+ this.#vectorU = vectorU;
314
+ this.#vectorV = vectorV;
315
+ this.#normal = normal;
316
+ this.#origin = origin;
317
+ }
318
+ } else {
319
+ this.#vectorU = vectorU;
320
+ this.#vectorV = vectorV;
321
+ this.#normal = normal;
322
+ this.#origin = origin;
323
+ }
324
+ } else {
325
+ this.createDefaultPlane(camera);
326
+ }
327
+
328
+ this.createTransformationMatrices();
329
+ this.#gridRestriction.updatePlaneDefinition();
330
+ this.#angularRestriction.updatePlaneDefinition();
331
+ this.#axisRestriction.updatePlaneDefinition();
332
+ }
333
+
334
+ // #endregion Private Methods (4)
255
335
  }
256
336
 
257
337
  // #endregion Classes (1)
@@ -2,6 +2,7 @@ import { AbstractRestriction } from '../../AbstractRestriction';
2
2
  import { CSS2DObject } from '../../../../../../../three/CSS2DRenderer';
3
3
  import { DrawingToolsManager } from '../../../../../DrawingToolsManager';
4
4
  import { GeometryMathManager } from '../../../../geometry/GeometryMathManager';
5
+ import { IRay } from '@shapediver/viewer.features.interaction';
5
6
  import { ISnapRestriction, SnapRestrictionProperties } from '../../../../../../interfaces/ISnapRestriction';
6
7
  import { numberCleaner } from '../../../../../utils/numberCleaner';
7
8
  import { PlaneRestriction } from '../PlaneRestriction';
@@ -30,7 +31,7 @@ export type AngularRestrictionProperties = {
30
31
  // #region Classes (1)
31
32
 
32
33
  export class AngularRestriction extends AbstractRestriction implements ISnapRestriction {
33
- // #region Properties (16)
34
+ // #region Properties (13)
34
35
 
35
36
  readonly #activationKey: string;
36
37
  readonly #drawingToolsManager: DrawingToolsManager;
@@ -48,12 +49,9 @@ export class AngularRestriction extends AbstractRestriction implements ISnapRest
48
49
  #angles: number[] = [];
49
50
  #labelNext?: CSS2DObject;
50
51
  #labelPrevious?: CSS2DObject;
51
- #normal: vec3;
52
52
  #priority: number = 0;
53
- #vectorU: vec3;
54
- #vectorV: vec3;
55
53
 
56
- // #endregion Properties (16)
54
+ // #endregion Properties (13)
57
55
 
58
56
  // #region Constructors (1)
59
57
 
@@ -66,13 +64,6 @@ export class AngularRestriction extends AbstractRestriction implements ISnapRest
66
64
 
67
65
  this.#planeRestriction = planeRestriction;
68
66
 
69
- // we store the properties of the plane restriction
70
- // as we need them to calculate the transformation matrices
71
- // and the offset of the grid size to the origin
72
- this.#vectorU = planeRestriction.vectorU!;
73
- this.#vectorV = planeRestriction.vectorV!;
74
- this.#normal = planeRestriction.normal;
75
-
76
67
  this.#activationKey = properties?.activationKey || 'a';
77
68
  this.enabled = properties?.enabled ?? false;
78
69
  this._enabledEditable = properties?.enabledEditable ?? true;
@@ -135,7 +126,7 @@ export class AngularRestriction extends AbstractRestriction implements ISnapRest
135
126
 
136
127
  // #region Public Methods (2)
137
128
 
138
- public snap(point: vec3, metaData?: RestrictionMetaData): vec3 | undefined {
129
+ public snap(ray: IRay, point: vec3, metaData?: RestrictionMetaData): vec3 | undefined {
139
130
  // if the restriction is not enabled OR the activation key is set and the key is not pressed, return
140
131
  if (this.enabled === false && this.#drawingToolsManager.keyPressed(this.#activationKey) === false) return;
141
132
 
@@ -184,10 +175,10 @@ export class AngularRestriction extends AbstractRestriction implements ISnapRest
184
175
  const previousPreviousPointFromData = vec3.fromValues(positionArray.at((previousPreviousIndex * 3))!, positionArray.at((previousPreviousIndex * 3) + 1)!, positionArray.at((previousPreviousIndex * 3) + 2)!);
185
176
 
186
177
  // project them onto the same plane as the point
187
- const nextPointProjected = vec3.sub(vec3.create(), nextPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), nextPointFromData, point), this.#normal)));
188
- const nextNextPointProjected = vec3.sub(vec3.create(), nextNextPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), nextNextPointFromData, point), this.#normal)));
189
- const previousPointProjected = vec3.sub(vec3.create(), previousPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), previousPointFromData, point), this.#normal)));
190
- const previousPreviousPointProjected = vec3.sub(vec3.create(), previousPreviousPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), previousPreviousPointFromData, point), this.#normal)));
178
+ const nextPointProjected = vec3.sub(vec3.create(), nextPointFromData, vec3.scale(vec3.create(), this.#planeRestriction.normal, vec3.dot(vec3.sub(vec3.create(), nextPointFromData, point), this.#planeRestriction.normal)));
179
+ const nextNextPointProjected = vec3.sub(vec3.create(), nextNextPointFromData, vec3.scale(vec3.create(), this.#planeRestriction.normal, vec3.dot(vec3.sub(vec3.create(), nextNextPointFromData, point), this.#planeRestriction.normal)));
180
+ const previousPointProjected = vec3.sub(vec3.create(), previousPointFromData, vec3.scale(vec3.create(), this.#planeRestriction.normal, vec3.dot(vec3.sub(vec3.create(), previousPointFromData, point), this.#planeRestriction.normal)));
181
+ const previousPreviousPointProjected = vec3.sub(vec3.create(), previousPreviousPointFromData, vec3.scale(vec3.create(), this.#planeRestriction.normal, vec3.dot(vec3.sub(vec3.create(), previousPreviousPointFromData, point), this.#planeRestriction.normal)));
191
182
 
192
183
  // project the point onto the XY-Plane
193
184
  const pointProjected = vec3.transformMat4(vec3.create(), point, this.#planeRestriction.transformationToXYPlaneMatrix);
@@ -262,11 +253,7 @@ export class AngularRestriction extends AbstractRestriction implements ISnapRest
262
253
  }
263
254
  }
264
255
 
265
- public updatePlaneDefinition(origin: vec3, vectorU: vec3, vectorV: vec3, normal: vec3): void {
266
- this.#vectorU = vectorU;
267
- this.#vectorV = vectorV;
268
- this.#normal = normal;
269
- }
256
+ public updatePlaneDefinition(): void { }
270
257
 
271
258
  // #endregion Public Methods (2)
272
259
 
@@ -300,31 +287,54 @@ export class AngularRestriction extends AbstractRestriction implements ISnapRest
300
287
 
301
288
  const text = document.createElement('div');
302
289
  text.className = 'label';
290
+ label = new CSS2DObject(text);
303
291
 
292
+ // remove the old style, if there is one
293
+ document.head.querySelectorAll('style').forEach(style => {
294
+ if (style.textContent?.includes(label!.uuid))
295
+ document.head.removeChild(style);
296
+ });
297
+
298
+ const parent = document.createElement('div');
299
+ parent.className = `angular-label-parent-${label!.uuid}`;
304
300
  const child = document.createElement('div');
305
- child.className = 'angular-label';
301
+ child.className = `angular-label-${label!.uuid}`;
306
302
 
307
303
  const style = document.createElement('style');
308
304
  style.textContent = `
309
- .angular-label {
305
+ .angular-label-${label!.uuid} {
310
306
  display: flex;
311
307
  justify-content: center;
312
308
  align-items: center;
313
- width: 40px;
314
- height: 40px;
309
+ width: 32px;
310
+ height: 32px;
315
311
  color: white;
316
312
  background-color: ${this.#settings.visualization.points.color_1};
317
313
  border-radius: 50%;
318
314
  font-size: 16px;
319
315
  text-align: center;
320
316
  }
317
+
318
+ .angular-label-parent-${label!.uuid} {
319
+ display: flex;
320
+ justify-content: center;
321
+ align-items: center;
322
+ width: 40px; /* 32px + 2 * 4px border width */
323
+ height: 40px; /* 32px + 2 * 4px border width */
324
+ border-radius: 50%;
325
+ background: conic-gradient(
326
+ ${this.#settings.visualization.points.color_2} 0% ${(angle / Math.PI) * 100}%,
327
+ ${this.#settings.visualization.points.color_1} ${(angle / Math.PI) * 100}% 100%
328
+ );
329
+ }
321
330
  `;
322
331
  document.head.appendChild(style);
323
332
 
333
+ parent.appendChild(child);
334
+
324
335
  child.textContent = `${numberCleaner((angle / Math.PI) * 180)}°`;
325
- text.appendChild(child);
336
+ text.appendChild(parent);
326
337
 
327
- label = new CSS2DObject(text);
328
338
  label.position.set(position[0], position[1], position[2]);
329
339
  label.visible = false;
330
340
  this._object3D.add(label);
@@ -0,0 +1,116 @@
1
+ import { AbstractRestriction } from '../../AbstractRestriction';
2
+ import { DrawingToolsManager } from '../../../../../DrawingToolsManager';
3
+ import { GeometryMathManager } from '../../../../geometry/GeometryMathManager';
4
+ import { IRay } from '@shapediver/viewer.features.interaction';
5
+ import { ISnapRestriction, SnapRestrictionProperties } from '../../../../../../interfaces/ISnapRestriction';
6
+ import { PlaneRestriction } from '../PlaneRestriction';
7
+ import { RestrictionMetaData } from '../../../../../../interfaces/IRestriction';
8
+ import { vec3 } from 'gl-matrix';
9
+
10
+ // #region Type aliases (1)
11
+
12
+ export type AxisRestrictionProperties = {
13
+ activationKeyX?: string;
14
+ activationKeyY?: string;
15
+ activationKeyZ?: string;
16
+ activationKeyPlane?: string;
17
+ } & SnapRestrictionProperties;
18
+
19
+ // #endregion Type aliases (1)
20
+
21
+ // #region Classes (1)
22
+
23
+ export class AxisRestriction extends AbstractRestriction implements ISnapRestriction {
24
+ // #region Properties (8)
25
+
26
+ readonly #activationKeyX: string;
27
+ readonly #activationKeyY: string;
28
+ readonly #activationKeyZ: string;
29
+ readonly #activationKeyPlane: string;
30
+ readonly #drawingToolsManager: DrawingToolsManager;
31
+ readonly #planeRestriction: PlaneRestriction;
32
+
33
+ #active: boolean = false;
34
+ #geometryMathManager: GeometryMathManager;
35
+ #priority: number = 0;
36
+
37
+ // #endregion Properties (8)
38
+
39
+ // #region Constructors (1)
40
+
41
+ constructor(drawingToolsManager: DrawingToolsManager, planeRestriction: PlaneRestriction, properties?: AxisRestrictionProperties) {
42
+ super(drawingToolsManager, 'axis');
43
+ this.#drawingToolsManager = drawingToolsManager;
44
+ this.#planeRestriction = planeRestriction;
45
+ this.#geometryMathManager = drawingToolsManager.geometryMathManager;
46
+
47
+ this.#activationKeyX = properties?.activationKeyX || 'x';
48
+ this.#activationKeyY = properties?.activationKeyY || 'y';
49
+ this.#activationKeyZ = properties?.activationKeyZ || 'z';
50
+ this.#activationKeyPlane = properties?.activationKeyPlane || 'p';
51
+
52
+ this.#priority = properties?.priority || 1;
53
+ }
54
+
55
+ // #endregion Constructors (1)
56
+
57
+ // #region Public Getters And Setters (5)
58
+
59
+ public get active(): boolean {
60
+ return this.#active;
61
+ }
62
+
63
+ public set active(value: boolean) {
64
+ this.#active = value;
65
+
66
+ // if (this.#gridHelper) this.#gridHelper.visible = value;
67
+ }
68
+
69
+ public get enabledEditable(): boolean {
70
+ return this._enabledEditable;
71
+ }
72
+
73
+ public get priority(): number {
74
+ return this.#priority;
75
+ }
76
+
77
+ public set priority(value: number) {
78
+ this.#priority = value;
79
+ }
80
+
81
+ // #endregion Public Getters And Setters (5)
82
+
83
+ // #region Public Methods (2)
84
+
85
+ public snap(ray: IRay, point: vec3, metaData?: RestrictionMetaData): vec3 | undefined {
86
+ if (this.enabled === false) return;
87
+ if (!metaData || !metaData.referencePoint) return;
88
+
89
+ const xPressed = this.#drawingToolsManager.keyPressed(this.#activationKeyX);
90
+ const yPressed = this.#drawingToolsManager.keyPressed(this.#activationKeyY);
91
+ const zPressed = this.#drawingToolsManager.keyPressed(this.#activationKeyZ);
92
+ const pPressed = this.#drawingToolsManager.keyPressed('p');
93
+
94
+ if (xPressed) {
95
+ return this.#geometryMathManager.closestPoint({ origin: metaData.referencePoint, direction: this.#planeRestriction.vectorU }, point);
96
+ } else if (yPressed) {
97
+ return this.#geometryMathManager.closestPoint({ origin: metaData.referencePoint, direction: this.#planeRestriction.vectorV }, point);
98
+ } else if (zPressed) {
99
+ return this.#geometryMathManager.closestPointsRayRay({ origin: metaData.referencePoint, direction: this.#planeRestriction.normal }, ray).closestPointOnRay1;
100
+ } else if (pPressed) {
101
+ return this.#geometryMathManager.closestPointOnPlane(this.#planeRestriction.origin, this.#planeRestriction.normal, point);
102
+ }
103
+ }
104
+
105
+ public updatePlaneDefinition(): void {}
106
+
107
+ // #endregion Public Methods (2)
108
+
109
+ // #region Protected Methods (1)
110
+
111
+ protected visibilityChanged(): void { }
112
+
113
+ // #endregion Protected Methods (1)
114
+ }
115
+
116
+ // #endregion Classes (1)