@wandelbots/wandelbots-js-react-components 4.7.1 → 4.7.2-pr.dev-RB-3348-v1-clean-up.560.cbf9c17

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 (109) hide show
  1. package/README.md +11 -32
  2. package/dist/3d-BOCs0RwR.cjs +2 -0
  3. package/dist/3d-BOCs0RwR.cjs.map +1 -0
  4. package/dist/3d-BTtdSlR9.js +1206 -0
  5. package/dist/3d-BTtdSlR9.js.map +1 -0
  6. package/dist/3d.cjs.js +1 -2
  7. package/dist/3d.esm.js +2 -0
  8. package/dist/auth0-spa-js.production.esm-8ppNz0la.js +5007 -0
  9. package/dist/auth0-spa-js.production.esm-8ppNz0la.js.map +1 -0
  10. package/dist/auth0-spa-js.production.esm-cNFf2AtX.cjs +5 -0
  11. package/dist/auth0-spa-js.production.esm-cNFf2AtX.cjs.map +1 -0
  12. package/dist/components/3d-viewport/CoordinateSystemTransform.d.ts +1 -1
  13. package/dist/components/3d-viewport/CoordinateSystemTransform.d.ts.map +1 -1
  14. package/dist/components/3d-viewport/SafetyZonesRenderer.d.ts +1 -2
  15. package/dist/components/3d-viewport/SafetyZonesRenderer.d.ts.map +1 -1
  16. package/dist/components/3d-viewport/TrajectoryRenderer.d.ts +2 -2
  17. package/dist/components/3d-viewport/TrajectoryRenderer.d.ts.map +1 -1
  18. package/dist/components/3d-viewport/collider/ColliderCollection.d.ts +1 -1
  19. package/dist/components/3d-viewport/collider/ColliderElement.d.ts +1 -1
  20. package/dist/components/3d-viewport/collider/CollisionSceneRenderer.d.ts +2 -2
  21. package/dist/components/3d-viewport/collider/colliderShapeToBufferGeometry.d.ts +1 -1
  22. package/dist/components/jogging/JoggingStore.d.ts +5 -11
  23. package/dist/components/jogging/JoggingStore.d.ts.map +1 -1
  24. package/dist/core-DtLSGTAb.js +18258 -0
  25. package/dist/core-DtLSGTAb.js.map +1 -0
  26. package/dist/core-DufB-Zu5.cjs +52 -0
  27. package/dist/core-DufB-Zu5.cjs.map +1 -0
  28. package/dist/core.cjs.js +1 -2
  29. package/dist/core.esm.js +3 -0
  30. package/dist/index.cjs.js +1 -2
  31. package/dist/index.d.ts +0 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.esm.js +4 -0
  34. package/dist/interpolation-BmgrXVQ7.js +5859 -0
  35. package/dist/interpolation-BmgrXVQ7.js.map +1 -0
  36. package/dist/interpolation-Cz29Pgpr.cjs +8 -0
  37. package/dist/interpolation-Cz29Pgpr.cjs.map +1 -0
  38. package/dist/lib/ConnectedMotionGroup.d.ts +2 -3
  39. package/dist/lib/ConnectedMotionGroup.d.ts.map +1 -1
  40. package/dist/lib/MotionStreamConnection.d.ts +0 -1
  41. package/dist/lib/MotionStreamConnection.d.ts.map +1 -1
  42. package/dist/themes/createDarkTheme.d.ts.map +1 -1
  43. package/dist/themes/themeTypes.d.ts +0 -4
  44. package/dist/themes/themeTypes.d.ts.map +1 -1
  45. package/package.json +21 -24
  46. package/src/components/3d-viewport/CoordinateSystemTransform.tsx +29 -18
  47. package/src/components/3d-viewport/SafetyZonesRenderer.tsx +13 -96
  48. package/src/components/3d-viewport/TrajectoryRenderer.tsx +8 -8
  49. package/src/components/3d-viewport/collider/ColliderCollection.tsx +1 -1
  50. package/src/components/3d-viewport/collider/ColliderElement.tsx +1 -1
  51. package/src/components/3d-viewport/collider/CollisionSceneRenderer.tsx +2 -2
  52. package/src/components/3d-viewport/collider/colliderShapeToBufferGeometry.ts +1 -1
  53. package/src/components/jogging/JoggingStore.ts +5 -5
  54. package/src/components/utils/interpolation.test.ts +3 -3
  55. package/src/index.ts +0 -1
  56. package/src/lib/ConnectedMotionGroup.ts +0 -5
  57. package/src/lib/MotionStreamConnection.ts +0 -5
  58. package/src/themes/createDarkTheme.ts +1 -22
  59. package/src/themes/themeTypes.ts +0 -5
  60. package/dist/3d.cjs.js.map +0 -1
  61. package/dist/3d.es.js +0 -19
  62. package/dist/3d.es.js.map +0 -1
  63. package/dist/LoadingCover-B3UN1lnU.js +0 -81
  64. package/dist/LoadingCover-B3UN1lnU.js.map +0 -1
  65. package/dist/LoadingCover-DXcsXWDy.cjs +0 -2
  66. package/dist/LoadingCover-DXcsXWDy.cjs.map +0 -1
  67. package/dist/MotionGroupVisualizer-7Mw9PINy.js +0 -1366
  68. package/dist/MotionGroupVisualizer-7Mw9PINy.js.map +0 -1
  69. package/dist/MotionGroupVisualizer-C0ll-LQF.cjs +0 -2
  70. package/dist/MotionGroupVisualizer-C0ll-LQF.cjs.map +0 -1
  71. package/dist/WandelscriptEditor-6sAoniLC.cjs +0 -2
  72. package/dist/WandelscriptEditor-6sAoniLC.cjs.map +0 -1
  73. package/dist/WandelscriptEditor-kWC2VyG_.js +0 -140
  74. package/dist/WandelscriptEditor-kWC2VyG_.js.map +0 -1
  75. package/dist/auth0-spa-js.production.esm-DNao6_S5.js +0 -4064
  76. package/dist/auth0-spa-js.production.esm-DNao6_S5.js.map +0 -1
  77. package/dist/auth0-spa-js.production.esm-DaBMfOV8.cjs +0 -5
  78. package/dist/auth0-spa-js.production.esm-DaBMfOV8.cjs.map +0 -1
  79. package/dist/components/wandelscript-editor/WandelscriptEditor.d.ts +0 -16
  80. package/dist/components/wandelscript-editor/WandelscriptEditor.d.ts.map +0 -1
  81. package/dist/components/wandelscript-editor/wandelscript.tmLanguage.d.ts +0 -45
  82. package/dist/components/wandelscript-editor/wandelscript.tmLanguage.d.ts.map +0 -1
  83. package/dist/core.cjs.js.map +0 -1
  84. package/dist/core.es.js +0 -54
  85. package/dist/core.es.js.map +0 -1
  86. package/dist/externalizeComponent-B98tgTPP.cjs +0 -24
  87. package/dist/externalizeComponent-B98tgTPP.cjs.map +0 -1
  88. package/dist/externalizeComponent-BOqKMZMc.js +0 -526
  89. package/dist/externalizeComponent-BOqKMZMc.js.map +0 -1
  90. package/dist/index.cjs.js.map +0 -1
  91. package/dist/index.es.js +0 -72
  92. package/dist/index.es.js.map +0 -1
  93. package/dist/interpolation-B8AcxfdD.js +0 -7167
  94. package/dist/interpolation-B8AcxfdD.js.map +0 -1
  95. package/dist/interpolation-SWzo5zr4.cjs +0 -20
  96. package/dist/interpolation-SWzo5zr4.cjs.map +0 -1
  97. package/dist/theming-BKpqgTRM.js +0 -22360
  98. package/dist/theming-BKpqgTRM.js.map +0 -1
  99. package/dist/theming-CatQaIl_.cjs +0 -115
  100. package/dist/theming-CatQaIl_.cjs.map +0 -1
  101. package/dist/wandelscript.cjs.js +0 -2
  102. package/dist/wandelscript.cjs.js.map +0 -1
  103. package/dist/wandelscript.d.ts +0 -2
  104. package/dist/wandelscript.d.ts.map +0 -1
  105. package/dist/wandelscript.es.js +0 -5
  106. package/dist/wandelscript.es.js.map +0 -1
  107. package/src/components/wandelscript-editor/WandelscriptEditor.tsx +0 -142
  108. package/src/components/wandelscript-editor/wandelscript.tmLanguage.ts +0 -62
  109. package/src/wandelscript.ts +0 -2
package/README.md CHANGED
@@ -13,7 +13,7 @@ See the [Storybook](https://wandelbotsgmbh.github.io/wandelbots-js-react-compone
13
13
  ## Install
14
14
 
15
15
  ```bash
16
- npm install @wandelbots/wandelbots-js-react-components react react-dom @mui/material @emotion/react @emotion/styled
16
+ pnpm add @wandelbots/wandelbots-js-react-components react react-dom @mui/material @emotion/react @emotion/styled
17
17
  ```
18
18
 
19
19
  Some modules require extra dependencies, like three.js. If you don't need 3D rendering in your application, always import from `/core`.
@@ -33,16 +33,10 @@ For 3D-enabled components, use `/3d`:
33
33
  import { Robot, RobotCard } from "@wandelbots/wandelbots-js-react-components/3d"
34
34
  ```
35
35
 
36
- For the code editor, use `/wandelscript`:
37
-
38
- ```typescript
39
- import { WandelscriptEditor } from "@wandelbots/wandelbots-js-react-components/wandelscript"
40
- ```
41
-
42
36
  You can also import from the top-level package, but then you'll need to provide all optional dependencies:
43
37
 
44
38
  ```bash
45
- npm install @wandelbots/wandelbots-js-react-components \
39
+ pnpm add @wandelbots/wandelbots-js-react-components \
46
40
  react react-dom \
47
41
  @mui/material @mui/icons-material @emotion/react @emotion/styled \
48
42
  three @react-three/fiber @react-three/drei three-stdlib \
@@ -56,7 +50,6 @@ npm install @wandelbots/wandelbots-js-react-components \
56
50
  | **Main** (`.`) | All components | React 18+, MUI v6/v7, @emotion/react, @emotion/styled, @mui/icons-material + all below |
57
51
  | **`/core`** | Base components (AppHeader, ProgramControl, SafetyBar, VelocitySlider, JoggingPanel, DataGrid, Timer, themes, i18n, etc.) | React 18+, MUI v6/v7, @emotion/react, @emotion/styled, @mui/icons-material |
58
52
  | **`/3d`** | 3D visualization (Robot, RobotCard, CollisionSceneRenderer, SafetyZonesRenderer, TrajectoryRenderer) | All from `/core` + three, @react-three/fiber, @react-three/drei, three-stdlib |
59
- | **`/wandelscript`** | Code editor (WandelscriptEditor) | All from `/core` + @monaco-editor/react, shiki, @shikijs/monaco |
60
53
 
61
54
  ## 4.x Core Changes
62
55
 
@@ -146,16 +139,6 @@ Safety components for production environments.
146
139
  - Real-time safety monitoring
147
140
  - Emergency stop integration
148
141
 
149
- ### Code Editing
150
-
151
- Code editing capabilities for robot programming.
152
-
153
- **[WandelscriptEditor](https://wandelbotsgmbh.github.io/wandelbots-js-react-components/?path=/docs/wandelscript-wandelscripteditor--docs)** - Code editor
154
-
155
- - Monaco editor integration
156
- - Wandelscript syntax highlighting
157
- - IntelliSense support
158
-
159
142
  ### Data & Interface Components
160
143
 
161
144
  UI components for data display and user interaction.
@@ -230,10 +213,6 @@ Components integrate with the Wandelbots Nova ecosystem:
230
213
  - @react-three/drei
231
214
  - three-stdlib
232
215
 
233
- **For `/wandelscript` (code editor):**
234
-
235
- - @monaco-editor/react
236
-
237
216
  ## Development
238
217
 
239
218
  To set up the project for development:
@@ -241,8 +220,8 @@ To set up the project for development:
241
220
  ```bash
242
221
  git clone https://github.com/wandelbotsgmbh/wandelbots-js-react-components.git
243
222
  cd wandelbots-js-react-components
244
- npm install
245
- npm run dev # Start Storybook development server
223
+ pnpm install
224
+ pnpm run dev # Start Storybook development server
246
225
  ```
247
226
 
248
227
  ## Robot Model Testing
@@ -252,9 +231,9 @@ View Robot Models in web view:
252
231
  ```bash
253
232
  git clone https://github.com/wandelbotsgmbh/wandelbots-js-react-components.git
254
233
  cd wandelbots-js-react-components
255
- npm install
256
- npm run td <instanceProviderURL> # instanceProviderURL can be provided via an instanceProviderConfig.json file. The entire command can be substituted by writing a nova instance ip into a file named .env.local
257
- npm run dev # Start Storybook development server
234
+ pnpm install
235
+ pnpm run td <instanceProviderURL> # instanceProviderURL can be provided via an instanceProviderConfig.json file. The entire command can be substituted by writing a nova instance ip into a file named .env.local
236
+ pnpm run dev # Start Storybook development server
258
237
  ```
259
238
 
260
239
  instanceProviderConfig.json file:
@@ -275,12 +254,12 @@ CELL_ID=cell
275
254
  Build and test the package locally:
276
255
 
277
256
  ```bash
278
- npm run build
279
- npm pack
280
- npm install /path/to/wandelbots-wandelbots-js-react-components-x.x.x.tgz
257
+ pnpm run build
258
+ pnpm pack
259
+ pnpm add /path/to/wandelbots-wandelbots-js-react-components-x.x.x.tgz
281
260
  ```
282
261
 
283
- > **Note:** Use `npm install` with the `.tgz` file instead of `npm link` due to peer dependency requirements with React Three Fiber components.
262
+ > **Note:** Use `pnpm add` with the `.tgz` file instead of `pnpm link` due to peer dependency requirements with React Three Fiber components.
284
263
 
285
264
  ## Contributing
286
265
 
@@ -0,0 +1,2 @@
1
+ const e=require(`./interpolation-Cz29Pgpr.cjs`);let t=require(`three`);t=e.S(t);let n=require(`three-stdlib`),r=require(`react`);r=e.S(r);let i=require(`@react-three/drei`),a=require(`@react-three/fiber`),o=require(`@mui/material`),s=require(`mobx-react-lite`),c=require(`react-i18next`),l=require(`react-error-boundary`);function u(e){switch(e.shape_type){case`convex_hull`:return new n.ConvexGeometry(e.vertices.map(e=>new t.Vector3(e[0]/1e3,e[1]/1e3,e[2]/1e3)));case`box`:return new t.BoxGeometry(e.size_x/1e3,e.size_y/1e3,e.size_z/1e3);case`sphere`:return new t.SphereGeometry(e.radius/1e3);case`capsule`:return new t.CapsuleGeometry(e.radius/1e3,e.cylinder_height/1e3);case`cylinder`:return new t.CylinderGeometry(e.radius/1e3,e.radius/1e3,e.height/1e3);case`rectangle`:return new t.BoxGeometry(e.size_x/1e3,e.size_y/1e3,0);default:return console.warn(`${e.shape_type} is not supported`),new t.BufferGeometry}}var d=e.b();function f({name:e,collider:n,children:r}){let i=n.pose?.position??[0,0,0],a=n.pose?.orientation??[0,0,0];return n.margin&&console.warn(`${e} margin is not supported`),(0,d.jsx)(`mesh`,{name:e,position:new t.Vector3(i[0],i[1],i[2]).divideScalar(1e3),rotation:new t.Euler(a[0],a[1],a[2],`XYZ`),geometry:u(n.shape),children:r})}function p({name:e,colliders:t,meshChildrenProvider:n,...r}){return(0,d.jsx)(`group`,{name:e,...r,children:Object.entries(t).map(([e,t])=>(0,d.jsx)(f,{name:e,collider:t,children:n(e,t)},e))})}function m({scene:e,meshChildrenProvider:t}){let n=e.colliders;return(0,d.jsx)(`group`,{children:n&&(0,d.jsx)(p,{meshChildrenProvider:t,colliders:n})})}function h(){return(0,d.jsx)(i.Environment,{children:(0,d.jsx)(g,{})})}function g({positions:e=[2,0,2,0,2,0,2,0]}){return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(i.Lightformer,{intensity:5,"rotation-x":Math.PI/2,position:[0,5,-9],scale:[10,10,1]}),(0,d.jsx)(`group`,{rotation:[0,.5,0],children:(0,d.jsx)(`group`,{children:e.map((e,t)=>(0,d.jsx)(i.Lightformer,{form:`circle`,intensity:5,rotation:[Math.PI/2,0,0],position:[e,4,t*4],scale:[3,1,1]},t))})}),(0,d.jsx)(i.Lightformer,{intensity:40,"rotation-y":Math.PI/2,position:[-5,1,-1],scale:[20,.1,1]}),(0,d.jsx)(i.Lightformer,{intensity:20,"rotation-y":-Math.PI,position:[-5,-2,-1],scale:[20,.1,1]}),(0,d.jsx)(i.Lightformer,{"rotation-y":Math.PI/2,position:[-5,-1,-1],scale:[20,.5,1],intensity:5}),(0,d.jsx)(i.Lightformer,{"rotation-y":-Math.PI/2,position:[10,1,0],scale:[20,1,1],intensity:10}),(0,d.jsx)(i.Lightformer,{form:`ring`,color:`white`,intensity:5,scale:10,position:[-15,4,-18],target:[0,0,0]})]})}function _({safetyZones:i,dhParameters:a,...o}){let s={attach:`material`,color:`#009f4d`,opacity:.2,depthTest:!1,depthWrite:!1,transparent:!0,polygonOffset:!0},c=e.g(a??[]),l=(r,i)=>{if(!i?.pose?.position||!i?.pose?.orientation)return null;let a=new t.Vector3(i.pose.position[0]/1e3,i.pose.position[1]/1e3,i.pose.position[2]/1e3),o=new t.Vector3(i.pose.orientation[0],i.pose.orientation[1],i.pose.orientation[2]),l,u=i.shape.shape_type===`plane`?{...s,side:t.DoubleSide}:{...s,side:t.FrontSide};switch(i.shape.shape_type){case`plane`:l=(0,d.jsx)(`planeGeometry`,{args:[c,c]});break;case`sphere`:l=(0,d.jsx)(`sphereGeometry`,{args:[(i?.shape).radius/1e3]});break;case`capsule`:l=(0,d.jsx)(`capsuleGeometry`,{args:[(i?.shape).radius/1e3,(i?.shape).cylinder_height/1e3]});break;case`convex_hull`:{let r=(i?.shape).vertices.map(e=>new t.Vector3(e[0]/1e3,e[1]/1e3,e[2]/1e3)),a=e.y(r);if(a.isCoplanar&&a.normal){let e=new t.Vector3().addVectors(r[0],a.normal.multiplyScalar(1e-4));r.push(e)}try{l=(0,d.jsx)(`primitive`,{object:new n.ConvexGeometry(r),attach:`geometry`})}catch(e){return console.log(`Error creating ConvexGeometry:`,e),null}break}case`rectangular_capsule`:{let e=i.shape,t=e.radius/1e3;l=(0,d.jsx)(`primitive`,{object:new n.RoundedBoxGeometry(e.sphere_center_distance_x/1e3,e.sphere_center_distance_y/1e3,t*2,2,t),attach:`geometry`});break}default:console.warn(`Unsupported safety zone shape type:`,i.shape.shape_type),l=null}return(0,d.jsxs)(`mesh`,{renderOrder:r,position:a,quaternion:e._(o),children:[l,(0,d.jsx)(`meshStandardMaterial`,{...u,polygonOffsetFactor:-r})]},`safety-zone-${i.shape.shape_type}-${r}`)},u=(0,r.useMemo)(()=>Object.values(i??{}).map((e,t)=>l(t,e)),[i,c]);return(0,d.jsx)(`group`,{...o,children:u})}function v({trajectory:e,...n}){let r=e?.map(e=>e.position?.length?new t.Vector3(e.position[0]/1e3,e.position[2]/1e3,-e.position[1]/1e3):null).filter(e=>e!==null)||[];return(0,d.jsx)(`group`,{...n,children:r.length>0&&(0,d.jsx)(i.Line,{points:r,lineWidth:3,polygonOffset:!0,polygonOffsetFactor:10,polygonOffsetUnits:10})})}var y=new Map;async function b(t,n){if(y.has(t))return y.get(t);let r=(async()=>{let r=new e.s({instanceUrl:n||``}),i=r.api.motionGroupModels;i.axios?.interceptors&&i.axios.interceptors.request.use(e=>(e.url?.includes(`/glb`)&&(e.responseType=`blob`),e));try{let e=await r.api.motionGroupModels.getMotionGroupGlbModel(t);return URL.createObjectURL(e)}catch(e){throw console.error(`Failed to fetch model:`,e),e}})();return y.set(t,r),r}function x(e){function t(e){return e.children.length===0?[e]:[e,...e.children.flatMap(e=>t(e))]}return t(e).filter(e=>C(e))}function S(e){return e.name.endsWith(`_FLG`)}function C(e){return/_J[0-9]+$/.test(e.name)}function w(e,t){let n,r=[];function i(e){if(S(e)){if(n)throw Error(`Found multiple flange groups in robot model ${t}; first ${n.name} then ${e.name}. Only one _FLG group is allowed.`);n=e}C(e)&&r.push(e),e.children.map(i)}if(i(e.scene),!n)throw Error(`No flange group found in robot model ${t}. Flange must be identified with a name ending in _FLG.`);return{gltf:e}}function T({rapidlyChangingMotionState:t,dhParameters:n,onRotationChanged:i,children:o}){let s=(0,r.useRef)([]),c=(0,r.useRef)([]),l=(0,r.useRef)(null),{invalidate:u}=(0,a.useThree)();(0,r.useEffect)(()=>(l.current=new e.t(t.joint_position.filter(e=>e!==void 0),{tension:120,friction:20,threshold:.001}),()=>{l.current?.destroy()}),[]),(0,a.useFrame)((e,t)=>{if(l.current){let e=l.current.update(t);p(),e||u()}});function f(e){e&&(c.current=x(e),p(),u())}function p(){let e=l.current?.getCurrentValues()||[];if(i)i(c.current,e);else for(let[t,r]of c.current.entries()){let i=n[t],a=i.theta||0,o=i.reverse_rotation_direction?-1:1;r.rotation.y=o*(e[t]||0)+a}}let m=(0,r.useCallback)(()=>{let e=t.joint_position.filter(e=>e!==void 0);requestAnimationFrame(()=>{s.current=e,l.current?.setTarget(e)})},[t]);return(0,r.useEffect)(()=>{m()},[t,m]),e.i(()=>{m()}),(0,d.jsx)(`group`,{ref:f,children:o})}var E=`line`,D=`mesh`;function O({rapidlyChangingMotionState:e,dhParameters:n,...a}){let o=new t.Matrix4,s=(0,r.useRef)([]),c=(0,r.useRef)([]);r.default.useEffect(()=>{s.current=Array(n.length).fill(null),c.current=Array(n.length).fill(null)},[n.length]);function l(e,n){let r=new t.Vector3,i=new t.Quaternion,a=new t.Vector3;o.decompose(r,i,a);let s=r.clone(),c=new t.Matrix4().makeRotationY(e.theta+n*(e.reverse_rotation_direction?-1:1)).multiply(new t.Matrix4().makeTranslation(0,e.d/1e3,0)).multiply(new t.Matrix4().makeTranslation(e.a/1e3,0,0)).multiply(new t.Matrix4().makeRotationX(e.alpha));return o.multiply(c),o.decompose(r,i,a),{a:s,b:r}}function u(e,t,r,i){if(!n)return;let a=n[e];if(!a)return;let{a:o,b:s}=l(a,i);t.geometry.setPositions([o.toArray(),s.toArray()].flat()),r.position.set(s.x,s.y,s.z)}function f(e,t){o.identity();for(let n=0;n<Math.min(e.length,t.length);n++){let e=s.current[n],r=c.current[n];e&&r&&u(n,e,r,t[n])}}return(0,d.jsx)(d.Fragment,{children:(0,d.jsx)(T,{rapidlyChangingMotionState:e,dhParameters:n,onRotationChanged:f,children:(0,d.jsxs)(`group`,{...a,name:`Scene`,children:[(0,d.jsxs)(`mesh`,{children:[(0,d.jsx)(`sphereGeometry`,{args:[.01,32,32]}),(0,d.jsx)(`meshStandardMaterial`,{color:`black`,depthTest:!0})]}),n.map((t,n)=>{let{a:r,b:a}=l(t,e.joint_position[n]??0),o=`dhrobot_J0${n}`;return(0,d.jsxs)(`group`,{name:o,children:[(0,d.jsx)(i.Line,{ref:e=>{s.current[n]=e},name:E,points:[r,a],color:`white`,lineWidth:5}),(0,d.jsxs)(`mesh`,{ref:e=>{c.current[n]=e},name:D,position:a,children:[(0,d.jsx)(`sphereGeometry`,{args:[.01,32,32]}),(0,d.jsx)(`meshStandardMaterial`,{color:`black`,depthTest:!0})]},`mesh_`+n)]},o)})]})})})}var k=console.warn;function A(){return(0,r.useEffect)(()=>{console.warn=e=>{e!==`Cannot call the manual advancement of rafz whilst frameLoop is not set as demand`&&k(e)}},[]),(0,d.jsx)(d.Fragment,{})}function j(e){return e.type===`Mesh`}function M({url:e,flangeRef:t,postModelRender:n,...a}){let o=(0,i.useGLTF)(e),s;try{s=w(o,`robot.glb`).gltf}catch(e){throw e}let c=(0,r.useCallback)(e=>{e&&n&&n()},[n]);function l(e){try{return j(e)?e.geometry?(0,d.jsx)(`mesh`,{name:e.name,geometry:e.geometry,material:e.material,position:e.position,rotation:e.rotation},e.uuid):(0,d.jsx)(`group`,{name:e.name,position:e.position,rotation:e.rotation},e.uuid):(0,d.jsx)(`group`,{name:e.name,position:e.position,rotation:e.rotation,ref:S(e)?t:void 0,children:e.children.map(l)},e.uuid)}catch(t){return console.warn(`Error rendering node`,e.name,t),null}}return(0,d.jsx)(`group`,{...a,dispose:null,ref:c,children:l(s.scene)})}function N({modelURL:e,flangeRef:t,postModelRender:n,...i}){let[a,o]=(0,r.useState)(null);return(0,r.useEffect)(()=>{(async()=>{try{o(typeof e==`string`?e:await e)}catch(e){console.error(`Failed to resolve model URL:`,e)}})()},[e]),a?(0,d.jsx)(M,{url:a,flangeRef:t,postModelRender:n,...i}):null}var P=(e,n)=>{e.userData.isGhost||(e.traverse(e=>{if(e instanceof t.Mesh){e.material instanceof t.Material&&(e.material.colorWrite=!1);let r=e.clone(),i=e.clone();r.material=new t.MeshStandardMaterial({depthTest:!0,depthWrite:!0,colorWrite:!1,polygonOffset:!0,polygonOffsetFactor:-1,side:t.DoubleSide}),r.userData.isGhost=!0,i.material=new t.MeshStandardMaterial({color:n,opacity:.3,depthTest:!0,depthWrite:!1,transparent:!0,polygonOffset:!0,polygonOffsetFactor:-2,side:t.DoubleSide}),i.userData.isGhost=!0,e.parent&&(e.parent.add(r),e.parent.add(i))}}),e.userData.isGhost=!0)},F=e=>{if(!e.userData.isGhost)return;let n=[];e.traverse(e=>{e instanceof t.Mesh&&(e.userData?.isGhost?n.push(e):e.material instanceof t.Material&&(e.material.colorWrite=!0))}),n.forEach(e=>{e.parent&&e.parent.remove(e)}),e.userData.isGhost=!1},I=e.m(({rapidlyChangingMotionState:e,modelFromController:t,dhParameters:n,getModel:i=b,flangeRef:a,postModelRender:o,transparentColor:s,instanceUrl:c,...u})=>{let[f,p]=(0,r.useState)(null),m=(0,r.useCallback)(e=>{p(e)},[]);(0,r.useEffect)(()=>{f&&(s?P(f,s):F(f))},[f,s]);let h=(0,d.jsx)(O,{rapidlyChangingMotionState:e,dhParameters:n,...u});return(0,d.jsxs)(l.ErrorBoundary,{fallback:h,onError:e=>{console.warn(e)},children:[(0,d.jsx)(r.Suspense,{fallback:h,children:(0,d.jsx)(`group`,{ref:m,children:(0,d.jsx)(T,{rapidlyChangingMotionState:e,dhParameters:n,children:(0,d.jsx)(N,{modelURL:(()=>{let e=i(t,c);if(!e){let e=new Blob([],{type:`model/gltf-binary`}),n=new File([e],`${t}.glb`,{type:`model/gltf-binary`});return Promise.resolve(URL.createObjectURL(n))}return e})(),postModelRender:o,flangeRef:a,...u})})})}),(0,d.jsx)(A,{})]})});function L({connectedMotionGroup:e,getModel:t=b,flangeRef:n,transparentColor:r,postModelRender:i,...a}){return e.dhParameters?(0,d.jsx)(I,{rapidlyChangingMotionState:e.rapidlyChangingMotionState,modelFromController:e.modelFromController||``,dhParameters:e.dhParameters,getModel:t,flangeRef:n,transparentColor:r,postModelRender:i,...a}):null}var R=e.m((0,s.observer)(({robotName:t,programState:n,safetyState:s,operationMode:l,driveToHomeEnabled:u=!1,onDriveToHomePress:f,onDriveToHomeRelease:p,connectedMotionGroup:m,robotComponent:g=L,customContentComponent:_,className:v})=>{let y=(0,o.useTheme)(),{t:b}=(0,c.useTranslation)(),[x,S]=(0,r.useState)(!1),C=(0,r.useRef)(null),w=(0,r.useRef)(null),[T,E]=(0,r.useState)(!1),[D,O]=(0,r.useState)({width:400,height:600}),[k,A]=(0,r.useState)(0);(0,r.useEffect)(()=>{let e=()=>{if(w.current){let{offsetWidth:e,offsetHeight:t}=w.current;E(e>t),O({width:e,height:t})}};e();let t=new ResizeObserver(e);return w.current&&t.observe(w.current),()=>{t.disconnect()}},[]);let j=(0,r.useCallback)(()=>{A(e=>e+1)},[]),M=(0,r.useCallback)(()=>{!u||!f||(S(!0),f())},[u,f]),N=(0,r.useCallback)(()=>{!u||!p||(S(!1),p())},[u,p]),P=(0,r.useCallback)(()=>{x&&p&&(S(!1),p())},[x,p]),F=T?D.width<350:D.height<200,I=T?D.height<310:D.height<450;return(0,d.jsx)(o.Card,{ref:w,className:v,sx:{width:`100%`,height:`100%`,display:`flex`,flexDirection:T?`row`:`column`,position:`relative`,overflow:`hidden`,minWidth:{xs:180,sm:220,md:250},minHeight:T?{xs:200,sm:240,md:260}:{xs:150,sm:180,md:220},border:`1px solid ${y.palette.divider}`,borderRadius:`18px`,boxShadow:`none`,backgroundColor:y.palette.backgroundPaperElevation?.[8]||`#2A2A3F`,backgroundImage:`none`},children:T?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(o.Box,{sx:{flex:`0 0 50%`,position:`relative`,height:`100%`,minHeight:`100%`,maxHeight:`100%`,borderRadius:1,m:{xs:1.5,sm:2,md:3},mr:{xs:.75,sm:1,md:1.5},overflow:`hidden`,display:F?`none`:`block`},children:!F&&(0,d.jsxs)(a.Canvas,{orthographic:!0,camera:{position:[3,2,3],zoom:1},shadows:!0,frameloop:`demand`,style:{borderRadius:y.shape.borderRadius,width:`100%`,height:`100%`,background:`transparent`,position:`absolute`,top:0,left:0},dpr:[1,2],gl:{alpha:!0,antialias:!0},children:[(0,d.jsx)(h,{}),(0,d.jsx)(i.Bounds,{fit:!0,observe:!0,margin:1,maxDuration:1,children:(0,d.jsx)(g,{connectedMotionGroup:m,postModelRender:j})})]})}),(0,d.jsxs)(o.Box,{sx:{flex:`1`,display:`flex`,flexDirection:`column`,justifyContent:`flex-start`,width:F?`100%`:`50%`},children:[(0,d.jsxs)(o.Box,{sx:{p:{xs:1.5,sm:2,md:3},pb:{xs:1,sm:1.5,md:2},textAlign:`left`},children:[(0,d.jsx)(o.Typography,{variant:`h6`,component:`h2`,sx:{mb:1},children:t}),(0,d.jsx)(e.d,{programState:n,safetyState:s,operationMode:l})]}),(0,d.jsxs)(o.Box,{sx:{p:{xs:1.5,sm:2,md:3},pt:0,flex:`1`,display:`flex`,flexDirection:`column`,justifyContent:`space-between`},children:[!I&&_&&(0,d.jsxs)(o.Box,{children:[(0,d.jsx)(_,{}),(0,d.jsx)(o.Divider,{sx:{mt:1,mb:0,borderColor:y.palette.divider,opacity:.5}})]}),(0,d.jsx)(o.Box,{sx:{mt:!I&&_?`auto`:0},children:(0,d.jsx)(o.Box,{sx:{display:`flex`,justifyContent:`flex-start`,mt:{xs:1,sm:1.5,md:2},mb:{xs:.5,sm:.75,md:1}},children:(0,d.jsx)(o.Button,{ref:C,variant:`contained`,color:`secondary`,size:`small`,disabled:!u,onMouseDown:M,onMouseUp:N,onMouseLeave:P,onTouchStart:M,onTouchEnd:N,sx:{textTransform:`none`,px:1.5,py:.5},children:b(`RobotCard.DriveToHome.bt`)})})})]})]})]}):(0,d.jsx)(d.Fragment,{children:(0,d.jsxs)(o.Box,{sx:{p:3,height:`100%`,display:`flex`,flexDirection:`column`},children:[(0,d.jsxs)(o.Box,{children:[(0,d.jsx)(o.Typography,{variant:`h6`,component:`h2`,sx:{mb:1},children:t}),(0,d.jsx)(e.d,{programState:n,safetyState:s,operationMode:l})]}),(0,d.jsx)(o.Box,{sx:{flex:+!F,position:`relative`,minHeight:F?0:{xs:120,sm:150,md:200},height:F?0:`auto`,borderRadius:1,overflow:`hidden`,display:F?`none`:`block`},children:!F&&(0,d.jsxs)(a.Canvas,{orthographic:!0,camera:{position:[3,2,3],zoom:1},shadows:!0,frameloop:`demand`,style:{borderRadius:y.shape.borderRadius,width:`100%`,height:`100%`,background:`transparent`,position:`absolute`},dpr:[1,2],gl:{alpha:!0,antialias:!0},children:[(0,d.jsx)(h,{}),(0,d.jsx)(i.Bounds,{fit:!0,clip:!0,observe:!0,margin:1,maxDuration:1,children:(0,d.jsx)(g,{connectedMotionGroup:m,postModelRender:j})})]})}),(0,d.jsxs)(o.Box,{children:[!I&&_&&(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(_,{}),(0,d.jsx)(o.Divider,{sx:{mt:1,mb:0,borderColor:y.palette.divider,opacity:.5}})]}),(0,d.jsx)(o.Box,{sx:{display:`flex`,justifyContent:`flex-start`,mt:!I&&_?{xs:1,sm:2,md:5}:{xs:.5,sm:1,md:2},mb:{xs:.5,sm:.75,md:1}},children:(0,d.jsx)(o.Button,{ref:C,variant:`contained`,color:`secondary`,size:`small`,disabled:!u,onMouseDown:M,onMouseUp:N,onMouseLeave:P,onTouchStart:M,onTouchEnd:N,sx:{textTransform:`none`,px:1.5,py:.5},children:b(`RobotCard.DriveToHome.bt`)})})]})]})})})})),z=[,,,,,,].fill(2*Math.PI);function B({rapidlyChangingMotionState:t,dhParameters:n,onTranslationChanged:i,children:o}){let s=(0,r.useRef)([]),c=(0,r.useRef)([]),l=(0,r.useRef)(null),{invalidate:u}=(0,a.useThree)();(0,r.useEffect)(()=>(l.current=new e.t(t.joint_position.filter(e=>e!==void 0),{tension:120,friction:20,threshold:.001}),()=>{l.current?.destroy()}),[]),(0,a.useFrame)((e,t)=>{if(l.current){let e=l.current.update(t);p(),e||u()}});function f(e){e&&(c.current=x(e),p(),u())}function p(){let e=l.current?.getCurrentValues()||[];if(i)i(c.current,e);else for(let[t,r]of c.current.entries()){let i=n[t].reverse_rotation_direction?-1:1;r.position.y=i*(e[t]||0)/1e3}}let m=(0,r.useCallback)(()=>{let e=t.joint_position.filter(e=>e!==void 0);requestAnimationFrame(()=>{s.current=e,l.current?.setTarget(e)})},[t]);return(0,r.useEffect)(()=>{m()},[t,m]),e.i(()=>{m()}),(0,d.jsx)(`group`,{ref:f,children:o})}function V({rapidlyChangingMotionState:e,dhParameters:n,...a}){let o=new t.Matrix4,s=(0,r.useRef)(null),c=(0,r.useRef)(null);function l(e){let r=new t.Matrix4;for(let i=0;i<n.length;i++){let a=n[i],o=e[i]??0,s=new t.Matrix4().makeRotationY(a.theta).multiply(new t.Matrix4().makeTranslation(a.a/1e3,(a.d+o*(a.reverse_rotation_direction?-1:1))/1e3,0)).multiply(new t.Matrix4().makeRotationX(a.alpha));r.multiply(s)}let i=new t.Vector3,a=new t.Quaternion,o=new t.Vector3;return r.decompose(i,a,o),i}let u=l(e.joint_position);function f(e,r){o.identity();let i=new t.Vector3;for(let e=0;e<n.length;e++){let i=r[e]??0,a=n[e],s=new t.Matrix4().makeRotationY(a.theta).multiply(new t.Matrix4().makeTranslation(a.a/1e3,(a.d+i*(a.reverse_rotation_direction?-1:1))/1e3,0)).multiply(new t.Matrix4().makeRotationX(a.alpha));o.multiply(s)}let a=new t.Vector3,l=new t.Quaternion,u=new t.Vector3;if(o.decompose(a,l,u),i=a,s.current&&s.current.position.set(i.x,i.y,i.z),c.current){let e=c.current.geometry;e&&e.setPositions&&e.setPositions([0,0,0,i.x,i.y,i.z])}}return(0,d.jsx)(d.Fragment,{children:(0,d.jsx)(B,{rapidlyChangingMotionState:e,dhParameters:n,onTranslationChanged:f,children:(0,d.jsxs)(`group`,{...a,name:`Scene`,children:[(0,d.jsxs)(`mesh`,{name:`Base`,position:[0,0,0],children:[(0,d.jsx)(`sphereGeometry`,{args:[.02,32,32]}),(0,d.jsx)(`meshStandardMaterial`,{color:`green`,depthTest:!0})]}),(0,d.jsx)(i.Line,{ref:c,points:[new t.Vector3(0,0,0),u],color:`White`,lineWidth:5}),(0,d.jsxs)(`mesh`,{ref:s,name:`TCP`,position:u,children:[(0,d.jsx)(`sphereGeometry`,{args:[.025,32,32]}),(0,d.jsx)(`meshStandardMaterial`,{color:`red`,depthTest:!0})]})]})})})}var H=e.m(({rapidlyChangingMotionState:e,modelFromController:t,dhParameters:n,getModel:i=b,flangeRef:a,postModelRender:o,transparentColor:s,instanceUrl:c,...u})=>{let[f,p]=(0,r.useState)(null),m=(0,r.useCallback)(e=>{p(e)},[]);(0,r.useEffect)(()=>{f&&(s?P(f,s):F(f))},[f,s]);let h=(0,d.jsx)(V,{rapidlyChangingMotionState:e,dhParameters:n,...u});return(0,d.jsxs)(l.ErrorBoundary,{fallback:h,onError:e=>{console.warn(e)},children:[(0,d.jsx)(r.Suspense,{fallback:h,children:(0,d.jsx)(`group`,{ref:m,children:(0,d.jsx)(B,{rapidlyChangingMotionState:e,dhParameters:n,children:(0,d.jsx)(N,{modelURL:(()=>{let e=i(t,c);if(!e){let e=new Blob([],{type:`model/gltf-binary`}),n=new File([e],`${t}.glb`,{type:`model/gltf-binary`});return Promise.resolve(URL.createObjectURL(n))}return e})(),postModelRender:o,flangeRef:a,...u})})})}),(0,d.jsx)(A,{})]})});function U({connectedMotionGroup:e,getModel:t=b,flangeRef:n,transparentColor:r,postModelRender:i,...a}){if(!e.dhParameters)return null;let o=e.modelFromController||``;return o&&t(o)?(0,d.jsx)(H,{rapidlyChangingMotionState:e.rapidlyChangingMotionState,modelFromController:o,dhParameters:e.dhParameters,getModel:t,flangeRef:n,transparentColor:r,postModelRender:i,...a}):(0,d.jsx)(V,{rapidlyChangingMotionState:e.rapidlyChangingMotionState,dhParameters:e.dhParameters,...a})}var W={[e.u.Abb]:[0,0,0,0,Math.PI/2,0,0],[e.u.Fanuc]:[0,0,0,0,-Math.PI/2,0,0],[e.u.Yaskawa]:[0,0,0,0,-Math.PI/2,0,0],[e.u.Kuka]:[0,-Math.PI/2,Math.PI/2,0,Math.PI/2,0,0],[e.u.Universalrobots]:[0,-Math.PI/2,-Math.PI/2,-Math.PI/2,Math.PI/2,-Math.PI/2,0]};function G(t){let[n]=t.split(`_`);switch(n){case`ABB`:return e.u.Abb;case`FANUC`:return e.u.Fanuc;case`YASKAWA`:return e.u.Yaskawa;case`KUKA`:return e.u.Kuka;case`UniversalRobots`:return e.u.Universalrobots;default:return null}}function K(e,t){let n=G(e);return n&&n in W?W[n]:t||null}var q=e.m(t=>{let{inverseSolver:n,dhParameters:i,...a}=t,[o,s]=(0,r.useState)(e.l.RevoluteJoint);(0,r.useEffect)(()=>{i.length&&s(i[0].type??e.l.RevoluteJoint)},[i]);let c=(0,r.useMemo)(()=>n===null&&o===e.l.RevoluteJoint,[n,o]),l=(0,r.useMemo)(()=>n===null&&o===e.l.PrismaticJoint,[n,o]);return(0,r.useMemo)(()=>!!n,[n])||c?(0,d.jsx)(I,{dhParameters:i,...a}):l?(0,d.jsx)(H,{dhParameters:i,...a}):(0,d.jsx)(d.Fragment,{})});Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return I}});
2
+ //# sourceMappingURL=3d-BOCs0RwR.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"3d-BOCs0RwR.cjs","names":[],"sources":["../src/components/3d-viewport/collider/colliderShapeToBufferGeometry.ts","../src/components/3d-viewport/collider/ColliderElement.tsx","../src/components/3d-viewport/collider/ColliderCollection.tsx","../src/components/3d-viewport/collider/CollisionSceneRenderer.tsx","../src/components/3d-viewport/PresetEnvironment.tsx","../src/components/3d-viewport/SafetyZonesRenderer.tsx","../src/components/3d-viewport/TrajectoryRenderer.tsx","../src/components/robots/robotModelLogic.ts","../src/components/robots/RobotAnimator.tsx","../src/components/robots/DHRobot.tsx","../src/components/ConsoleFilter.tsx","../src/components/robots/GenericRobot.tsx","../src/components/robots/ghostStyle.ts","../src/components/robots/SupportedRobot.tsx","../src/components/robots/Robot.tsx","../src/components/RobotCard.tsx","../src/components/robots/AxisConfig.ts","../src/components/robots/LinearAxisAnimator.tsx","../src/components/robots/DHLinearAxis.tsx","../src/components/robots/SupportedLinearAxis.tsx","../src/components/robots/LinearAxis.tsx","../src/components/robots/manufacturerHomePositions.ts","../src/components/robots/MotionGroupVisualizer.tsx"],"sourcesContent":["import type { ColliderShape } from \"@wandelbots/nova-js/v2\"\nimport * as THREE from \"three\"\nimport { ConvexGeometry } from \"three-stdlib\"\n\nexport function colliderShapeToBufferGeometry(\n shape: ColliderShape,\n): THREE.BufferGeometry {\n const shapeType = shape.shape_type\n switch (shapeType) {\n case \"convex_hull\":\n return new ConvexGeometry(\n shape.vertices.map(\n (vertex) =>\n new THREE.Vector3(\n vertex[0] / 1000,\n vertex[1] / 1000,\n vertex[2] / 1000,\n ),\n ),\n )\n case \"box\":\n return new THREE.BoxGeometry(\n shape.size_x / 1000,\n shape.size_y / 1000,\n shape.size_z / 1000,\n )\n case \"sphere\":\n return new THREE.SphereGeometry(shape.radius / 1000)\n case \"capsule\":\n return new THREE.CapsuleGeometry(\n shape.radius / 1000,\n shape.cylinder_height / 1000,\n )\n case \"cylinder\":\n return new THREE.CylinderGeometry(\n shape.radius / 1000,\n shape.radius / 1000,\n shape.height / 1000,\n )\n case \"rectangle\": {\n return new THREE.BoxGeometry(shape.size_x / 1000, shape.size_y / 1000, 0)\n }\n default: {\n console.warn(`${shape.shape_type} is not supported`)\n return new THREE.BufferGeometry()\n }\n }\n}\n","import type { Collider } from \"@wandelbots/nova-js/v2\"\nimport type React from \"react\"\nimport * as THREE from \"three\"\nimport { colliderShapeToBufferGeometry } from \"./colliderShapeToBufferGeometry\"\n\ntype ColliderElementProps = {\n name?: string\n collider: Collider\n children?: React.ReactNode\n}\n\nexport default function ColliderElement({\n name,\n collider,\n children,\n}: ColliderElementProps) {\n const position = collider.pose?.position ?? [0, 0, 0]\n const rotation = collider.pose?.orientation ?? [0, 0, 0]\n if (collider.margin) {\n console.warn(`${name} margin is not supported`)\n }\n return (\n <mesh\n name={name}\n position={new THREE.Vector3(\n position[0],\n position[1],\n position[2],\n ).divideScalar(1000)}\n rotation={new THREE.Euler(rotation[0], rotation[1], rotation[2], \"XYZ\")}\n geometry={colliderShapeToBufferGeometry(collider.shape)}\n >\n {children}\n </mesh>\n )\n}\n","import type { ThreeElements } from \"@react-three/fiber\"\nimport type { Collider } from \"@wandelbots/nova-js/v2\"\nimport ColliderElement from \"./ColliderElement\"\n\nexport type MeshChildrenProvider = (\n key: string,\n collider: Collider,\n) => React.ReactNode\n\ntype ColliderCollectionProps = {\n name?: string\n colliders: Record<string, Collider>\n meshChildrenProvider: MeshChildrenProvider\n} & ThreeElements[\"group\"]\n\nexport default function ColliderCollection({\n name,\n colliders,\n meshChildrenProvider,\n ...props\n}: ColliderCollectionProps) {\n return (\n <group name={name} {...props}>\n {Object.entries(colliders).map(([colliderKey, collider]) => (\n <ColliderElement\n key={colliderKey}\n name={colliderKey}\n collider={collider}\n children={meshChildrenProvider(colliderKey, collider)}\n />\n ))}\n </group>\n )\n}\n","import type { CollisionSetup } from \"@wandelbots/nova-js/v2\"\nimport ColliderCollection, {\n type MeshChildrenProvider,\n} from \"./ColliderCollection\"\n\ntype CollisionSceneRendererProps = {\n scene: CollisionSetup\n meshChildrenProvider: MeshChildrenProvider\n}\n\nexport default function CollisionSceneRenderer({\n scene,\n meshChildrenProvider,\n}: CollisionSceneRendererProps) {\n const colliders = scene.colliders\n return (\n <group>\n {colliders && (\n <ColliderCollection\n meshChildrenProvider={meshChildrenProvider}\n colliders={colliders}\n />\n )}\n </group>\n )\n}\n","import { Environment, Lightformer } from \"@react-three/drei\"\n\n/**\n * Renders a preset environment for the 3D scene.\n * This component wraps the scene with an `Environment` component\n * and builds a lightmap build with `Lightformers`.\n */\nexport function PresetEnvironment() {\n return (\n <Environment>\n <Lightformers />\n </Environment>\n )\n}\n\nfunction Lightformers({ positions = [2, 0, 2, 0, 2, 0, 2, 0] }) {\n return (\n <>\n {/* Ceiling */}\n <Lightformer\n intensity={5}\n rotation-x={Math.PI / 2}\n position={[0, 5, -9]}\n scale={[10, 10, 1]}\n />\n <group rotation={[0, 0.5, 0]}>\n <group>\n {positions.map((x, i) => (\n <Lightformer\n key={i}\n form=\"circle\"\n intensity={5}\n rotation={[Math.PI / 2, 0, 0]}\n position={[x, 4, i * 4]}\n scale={[3, 1, 1]}\n />\n ))}\n </group>\n </group>\n {/* Sides */}\n <Lightformer\n intensity={40}\n rotation-y={Math.PI / 2}\n position={[-5, 1, -1]}\n scale={[20, 0.1, 1]}\n />\n <Lightformer\n intensity={20}\n rotation-y={-Math.PI}\n position={[-5, -2, -1]}\n scale={[20, 0.1, 1]}\n />\n\n <Lightformer\n rotation-y={Math.PI / 2}\n position={[-5, -1, -1]}\n scale={[20, 0.5, 1]}\n intensity={5}\n />\n <Lightformer\n rotation-y={-Math.PI / 2}\n position={[10, 1, 0]}\n scale={[20, 1, 1]}\n intensity={10}\n />\n\n {/* Key */}\n <Lightformer\n form=\"ring\"\n color=\"white\"\n intensity={5}\n scale={10}\n position={[-15, 4, -18]}\n target={[0, 0, 0]}\n />\n </>\n )\n}\n","import { useMemo } from \"react\"\nimport { type ThreeElements } from \"@react-three/fiber\"\nimport * as THREE from \"three\"\nimport { ConvexGeometry, RoundedBoxGeometry } from \"three-stdlib\"\n\nimport type {\n Collider,\n ConvexHull,\n DHParameter,\n MotionGroupDescription,\n Sphere,\n Capsule,\n RectangularCapsule,\n} from \"@wandelbots/nova-js/v2\"\n\nimport { dhParametersToPlaneSize, orientationToQuaternion, verticesToCoplanarity } from \"../utils/converters\"\n\nexport type SafetyZonesRendererProps = {\n safetyZones: MotionGroupDescription[\"safety_zones\"]\n dhParameters?: DHParameter[]\n} & ThreeElements[\"group\"]\n\nexport function SafetyZonesRenderer({\n safetyZones,\n dhParameters,\n ...props\n }: SafetyZonesRendererProps) {\n /**\n * Common material properties for safety zone meshes\n */\n const safetyZoneMaterialProps = {\n attach: \"material\" as const,\n color: \"#009f4d\",\n opacity: 0.2,\n depthTest: false,\n depthWrite: false,\n transparent: true,\n polygonOffset: true,\n }\n\n /**\n * Plane size for the plane safety zones, returns the reach distance\n * of the robot\n */\n const planeSize = dhParametersToPlaneSize(dhParameters ?? [])\n\n /**\n * Helper function to render plane, sphere, and capsule meshes\n * @param id number\n * @param zone Collider\n */\n const renderMesh = (id: number, zone: Collider) => {\n if (!zone?.pose?.position || !zone?.pose?.orientation) {\n return null\n }\n\n const position = new THREE.Vector3(zone.pose.position[0] / 1000, zone.pose.position[1] / 1000, zone.pose.position[2] / 1000)\n const orientation = new THREE.Vector3(zone.pose.orientation[0], zone.pose.orientation[1], zone.pose.orientation[2])\n\n let geometry: React.ReactElement | null\n\n const materialProps = zone.shape.shape_type === \"plane\"\n ? { ...safetyZoneMaterialProps, side: THREE.DoubleSide }\n : { ...safetyZoneMaterialProps, side: THREE.FrontSide }\n\n switch (zone.shape.shape_type) {\n /**\n * Plane shape, uses DH parameters to calculate the size of the plane (reach distance of a robot)\n */\n case \"plane\":\n geometry = <planeGeometry args={[planeSize, planeSize]} />\n break\n\n /**\n * Sphere shape\n */\n case \"sphere\": {\n const radius = (zone?.shape as Sphere).radius / 1000\n geometry = <sphereGeometry args={[radius]} />\n break\n }\n\n /**\n * Capsule shape\n */\n case \"capsule\": {\n const capsuleRadius = (zone?.shape as Capsule).radius / 1000\n const height = (zone?.shape as Capsule).cylinder_height / 1000\n geometry = <capsuleGeometry args={[capsuleRadius, height]} />\n break\n }\n\n /**\n * Convex hull, checks at first if the vertices are coplanar - if yes, adds a small offset for\n * renderer to be able to visualize the convex hull.\n */\n case \"convex_hull\": {\n const vertices = (zone?.shape as ConvexHull).vertices.map(\n (v) => new THREE.Vector3(v[0] / 1000, v[1] / 1000, v[2] / 1000),\n )\n // Check if the vertices are on the same plane\n const coplanarityResult = verticesToCoplanarity(vertices)\n if (coplanarityResult.isCoplanar && coplanarityResult.normal) {\n const offset = 0.0001\n const newVertex = new THREE.Vector3().addVectors(\n vertices[0],\n coplanarityResult.normal.multiplyScalar(offset),\n )\n vertices.push(newVertex)\n }\n try {\n geometry = <primitive object={new ConvexGeometry(vertices)} attach=\"geometry\" />\n } catch (error) {\n console.log(\"Error creating ConvexGeometry:\", error)\n return null\n }\n break\n }\n\n /**\n * Convex hull around four spheres. Sphere center points in x/y-plane,\n * offset by either combination \"+/- sizeX\" or \"+/- sizeY\".\n * Alternative description: Rectangle in x/y-plane with a 3D padding (source: nova-api docs)\n *\n * Basically a rounded box with a rectangular cross-section.\n */\n case \"rectangular_capsule\": {\n const shape = zone.shape as RectangularCapsule\n const rcRadius = shape.radius / 1000\n const width = shape.sphere_center_distance_x / 1000\n const height = shape.sphere_center_distance_y / 1000\n const depth = rcRadius * 2\n\n geometry = (\n <primitive\n object={new RoundedBoxGeometry(width, height, depth, 2, rcRadius)}\n attach=\"geometry\"\n />\n )\n break\n }\n\n default: {\n console.warn(\"Unsupported safety zone shape type:\", zone.shape.shape_type)\n geometry = null\n }\n }\n\n return (\n <mesh\n key={`safety-zone-${zone.shape.shape_type}-${id}`}\n renderOrder={id}\n position={position}\n quaternion={orientationToQuaternion(orientation)}\n >\n {geometry}\n <meshStandardMaterial {...materialProps} polygonOffsetFactor={-id} />\n </mesh>\n )\n }\n\n /**\n * Helper variable render safety zones\n */\n const renderedSafetyZones = useMemo(() => {\n return Object.values(safetyZones ?? {}).map((zone: Collider, index: number) => {\n return renderMesh(index, zone)\n })\n }, [safetyZones, planeSize])\n\n return (\n <group {...props}>\n {renderedSafetyZones}\n </group>\n )\n}\n","import { Line } from \"@react-three/drei\"\nimport type { Pose } from \"@wandelbots/nova-js/v2\"\nimport * as THREE from \"three\"\n\nexport type TrajectoryRendererProps = {\n trajectory: Pose[]\n} & React.JSX.IntrinsicElements[\"group\"]\n\nexport function TrajectoryRenderer({\n trajectory,\n ...props\n}: TrajectoryRendererProps) {\n const points =\n trajectory\n ?.map((pose: Pose) => {\n if (pose.position?.length) {\n return new THREE.Vector3(\n pose.position[0] / 1000,\n pose.position[2] / 1000,\n -pose.position[1] / 1000,\n )\n }\n return null\n })\n .filter((point): point is THREE.Vector3 => point !== null) || []\n\n return (\n <group {...props}>\n {points.length > 0 && (\n <Line\n points={points}\n lineWidth={3}\n polygonOffset={true}\n polygonOffsetFactor={10}\n polygonOffsetUnits={10}\n />\n )}\n </group>\n )\n}\n","import { NovaClient } from \"@wandelbots/nova-js/v2\"\nimport type { Object3D } from \"three\"\nimport type { GLTF } from \"three-stdlib\"\n\nconst modelCache = new Map<string, Promise<string>>()\n\n/**\n * Revoke a cached model's object URL to prevent memory leaks.\n * Call this when a component unmounts or no longer needs the model.\n */\nexport async function revokeModelUrl(modelFromController: string): Promise<void> {\n const urlPromise = modelCache.get(modelFromController)\n if (!urlPromise) return\n\n try {\n const url = await urlPromise\n URL.revokeObjectURL(url)\n } catch (e) {\n // Ignore errors - URL may already be revoked\n }\n modelCache.delete(modelFromController)\n}\n\n/**\n * Revoke all cached model object URLs and clear the cache.\n * Useful for cleanup on app teardown.\n */\nexport async function revokeAllModelUrls(): Promise<void> {\n const entries = Array.from(modelCache.entries())\n await Promise.allSettled(\n entries.map(async ([key, urlPromise]) => {\n try {\n const url = await urlPromise\n URL.revokeObjectURL(url)\n } catch (e) {\n // Ignore errors\n }\n })\n )\n modelCache.clear()\n}\n\nexport async function defaultGetModel(modelFromController: string, instanceUrlProp?: string): Promise<string> {\n // Check cache first\n if (modelCache.has(modelFromController)) {\n return modelCache.get(modelFromController)!\n }\n \n // Create the promise and cache it immediately to prevent duplicate calls\n const modelPromise = (async () => {\n const instanceUrl = instanceUrlProp || import.meta.env.WANDELAPI_BASE_URL\n const nova = new NovaClient({ instanceUrl })\n \n // Configure axios to handle binary responses for GLB files\n const apiInstance = nova.api.motionGroupModels as any\n if (apiInstance.axios?.interceptors) {\n apiInstance.axios.interceptors.request.use((config: any) => {\n if (config.url?.includes('/glb')) {\n config.responseType = 'blob'\n }\n return config\n })\n }\n \n try {\n const file = await nova.api.motionGroupModels.getMotionGroupGlbModel(modelFromController)\n \n // Create object URL from the file and return it\n const url = URL.createObjectURL(file)\n return url\n } catch (error) {\n console.error(\"Failed to fetch model:\", error)\n throw error\n }\n })()\n \n // Cache the promise\n modelCache.set(modelFromController, modelPromise)\n return modelPromise\n}\n\n/**\n * Finds all the joint groups in a GLTF tree, as identified\n * by the _Jxx name ending convention.\n */\nexport function collectJoints(rootObject: Object3D): Object3D[] {\n function getAllObjects(root: Object3D): Object3D[] {\n if (root.children.length === 0) {\n return [root]\n }\n return [root, ...root.children.flatMap((child) => getAllObjects(child))]\n }\n\n return getAllObjects(rootObject).filter((o) => isJoint(o))\n}\n\n/**\n * Checks if a specified threejs object represents the flange of a\n * robot, based on the _FLG name ending convention.\n */\nexport function isFlange(node: Object3D) {\n return node.name.endsWith(\"_FLG\")\n}\n\n/**\n * Checks if a specified threejs object represents a joint of a\n * robot, based on the _Jxx name ending convention.\n */\nexport function isJoint(node: Object3D) {\n return /_J[0-9]+$/.test(node.name)\n}\n\n/**\n * Validates that the loaded GLTF file has six joints and a flange group.\n */\nexport function parseRobotModel(gltf: GLTF, filename: string): { gltf: GLTF } {\n let flange: Object3D | undefined\n const joints: Object3D[] = []\n\n function parseNode(node: Object3D) {\n if (isFlange(node)) {\n if (flange) {\n throw Error(\n `Found multiple flange groups in robot model ${filename}; first ${flange.name} then ${node.name}. Only one _FLG group is allowed.`,\n )\n }\n\n flange = node\n }\n\n if (isJoint(node)) {\n joints.push(node)\n }\n\n node.children.map(parseNode)\n }\n\n parseNode(gltf.scene)\n\n if (!flange) {\n throw Error(\n `No flange group found in robot model ${filename}. Flange must be identified with a name ending in _FLG.`,\n )\n }\n\n return { gltf }\n}\n","import { useFrame, useThree } from \"@react-three/fiber\"\nimport type { DHParameter, MotionGroupState } from \"@wandelbots/nova-js/v2\"\nimport React, { useEffect, useRef, useCallback } from \"react\"\nimport type { Group, Object3D } from \"three\"\nimport { useAutorun } from \"../utils/hooks\"\nimport { ValueInterpolator } from \"../utils/interpolation\"\nimport { collectJoints } from \"./robotModelLogic\"\n\ntype RobotAnimatorProps = {\n rapidlyChangingMotionState: MotionGroupState\n dhParameters: DHParameter[]\n onRotationChanged?: (joints: Object3D[], jointValues: number[]) => void\n children: React.ReactNode\n}\n\nexport default function RobotAnimator({\n rapidlyChangingMotionState,\n dhParameters,\n onRotationChanged,\n children,\n}: RobotAnimatorProps) {\n const jointValues = useRef<number[]>([])\n const jointObjects = useRef<Object3D[]>([])\n const interpolatorRef = useRef<ValueInterpolator | null>(null)\n const { invalidate } = useThree()\n\n // Initialize interpolator\n useEffect(() => {\n const initialJointValues = rapidlyChangingMotionState.joint_position.filter(\n (item) => item !== undefined,\n )\n\n interpolatorRef.current = new ValueInterpolator(initialJointValues, {\n tension: 120, // Controls spring stiffness - higher values create faster, more responsive motion\n friction: 20, // Controls damping - higher values reduce oscillation and create smoother settling\n threshold: 0.001,\n })\n\n return () => {\n interpolatorRef.current?.destroy()\n }\n }, [])\n\n // Animation loop that runs at the display's refresh rate\n useFrame((state, delta) => {\n if (interpolatorRef.current) {\n const isComplete = interpolatorRef.current.update(delta)\n setRotation()\n\n // Trigger a re-render only if the animation is still running\n if (!isComplete) {\n invalidate()\n }\n }\n })\n\n function setGroupRef(group: Group | null) {\n if (!group) return\n\n jointObjects.current = collectJoints(group)\n\n // Set initial position\n setRotation()\n invalidate()\n }\n\n function setRotation() {\n const updatedJointValues = interpolatorRef.current?.getCurrentValues() || []\n\n if (onRotationChanged) {\n onRotationChanged(jointObjects.current, updatedJointValues)\n } else {\n for (const [index, object] of jointObjects.current.entries()) {\n const dhParam = dhParameters[index]\n const rotationOffset = dhParam.theta || 0\n const rotationSign = dhParam.reverse_rotation_direction ? -1 : 1\n\n object.rotation.y =\n rotationSign * (updatedJointValues[index] || 0) + rotationOffset\n }\n }\n }\n\n const updateJoints = useCallback(() => {\n const newJointValues = rapidlyChangingMotionState.joint_position.filter(\n (item) => item !== undefined,\n )\n\n requestAnimationFrame(() => {\n jointValues.current = newJointValues\n interpolatorRef.current?.setTarget(newJointValues)\n })\n }, [rapidlyChangingMotionState])\n\n /**\n * Fire an update joints call on every motion state change.\n * requestAnimationFrame used to avoid blocking main thread\n */\n useEffect(() => {\n updateJoints()\n }, [rapidlyChangingMotionState, updateJoints])\n\n /**\n * As some consumer applications (eg. storybook) deliver\n * mobx observable for rapidlyChangingMotionState, we need to\n * register the watcher to get the newest value updates\n */\n useAutorun(() => {\n updateJoints()\n })\n\n return <group ref={setGroupRef}>{children}</group>\n}\n","import { Line } from \"@react-three/drei\"\nimport type { DHParameter } from \"@wandelbots/nova-js/v2\"\nimport React, { useRef } from \"react\"\nimport type * as THREE from \"three\"\nimport { Matrix4, Quaternion, Vector3 } from \"three\"\nimport type { LineGeometry } from \"three/examples/jsm/lines/LineGeometry.js\"\nimport RobotAnimator from \"./RobotAnimator\"\nimport type { DHRobotProps } from \"./SupportedRobot\"\n\nconst CHILD_LINE = \"line\"\nconst CHILD_MESH = \"mesh\"\n\nexport function DHRobot({\n rapidlyChangingMotionState,\n dhParameters,\n ...props\n}: DHRobotProps) {\n // reused in every update\n const accumulatedMatrix = new Matrix4()\n\n // Store direct references to avoid searching by name\n const lineRefs = useRef<any[]>([])\n const meshRefs = useRef<(THREE.Mesh | null)[]>([])\n\n // Initialize refs array when dhParameters change\n React.useEffect(() => {\n lineRefs.current = new Array(dhParameters.length).fill(null)\n meshRefs.current = new Array(dhParameters.length).fill(null)\n }, [dhParameters.length])\n\n // Updates accumulatedMatrix with every execution\n // Reset the matrix to identity if you start a new position update\n function getLinePoints(\n dhParameter: DHParameter,\n jointRotation: number,\n ): {\n a: THREE.Vector3\n b: THREE.Vector3\n } {\n const position = new Vector3()\n const quaternion = new Quaternion()\n const scale = new Vector3()\n accumulatedMatrix.decompose(position, quaternion, scale)\n const prevPosition = position.clone() // Update the previous position\n\n const matrix = new Matrix4()\n .makeRotationY(\n dhParameter.theta! +\n jointRotation * (dhParameter.reverse_rotation_direction ? -1 : 1),\n ) // Rotate around Z\n .multiply(new Matrix4().makeTranslation(0, dhParameter.d! / 1000, 0)) // Translate along Z\n .multiply(new Matrix4().makeTranslation(dhParameter.a! / 1000, 0, 0)) // Translate along X\n .multiply(new Matrix4().makeRotationX(dhParameter.alpha!)) // Rotate around X\n\n // Accumulate transformations\n accumulatedMatrix.multiply(matrix)\n accumulatedMatrix.decompose(position, quaternion, scale)\n return { a: prevPosition, b: position }\n }\n\n function setJointLineRotation(\n jointIndex: number,\n line: any, // Use any for drei Line component\n mesh: THREE.Mesh,\n jointValue: number,\n ) {\n if (!dhParameters) {\n return\n }\n\n const dh_parameter = dhParameters[jointIndex]\n if (!dh_parameter) {\n return\n }\n\n const { a, b } = getLinePoints(dh_parameter, jointValue)\n const lineGeometry = line.geometry as LineGeometry\n lineGeometry.setPositions([a.toArray(), b.toArray()].flat())\n\n mesh.position.set(b.x, b.y, b.z)\n }\n\n function setRotation(joints: THREE.Object3D[], jointValues: number[]) {\n accumulatedMatrix.identity()\n\n // Use direct refs instead of searching by name\n for (\n let jointIndex = 0;\n jointIndex < Math.min(joints.length, jointValues.length);\n jointIndex++\n ) {\n const line = lineRefs.current[jointIndex]\n const mesh = meshRefs.current[jointIndex]\n\n if (line && mesh) {\n setJointLineRotation(jointIndex, line, mesh, jointValues[jointIndex]!)\n }\n }\n }\n\n return (\n <>\n <RobotAnimator\n rapidlyChangingMotionState={rapidlyChangingMotionState}\n dhParameters={dhParameters}\n onRotationChanged={setRotation}\n >\n <group {...props} name=\"Scene\">\n <mesh>\n <sphereGeometry args={[0.01, 32, 32]} />\n <meshStandardMaterial color={\"black\"} depthTest={true} />\n </mesh>\n {dhParameters!.map((param, index) => {\n const { a, b } = getLinePoints(\n param,\n rapidlyChangingMotionState.joint_position[index] ?? 0,\n )\n const jointName = `dhrobot_J0${index}`\n return (\n <group name={jointName} key={jointName}>\n <Line\n ref={(ref) => {\n lineRefs.current[index] = ref\n }}\n name={CHILD_LINE}\n points={[a, b]}\n color={\"white\"}\n lineWidth={5}\n />\n <mesh\n ref={(ref) => {\n meshRefs.current[index] = ref\n }}\n name={CHILD_MESH}\n key={\"mesh_\" + index}\n position={b}\n >\n <sphereGeometry args={[0.01, 32, 32]} />\n <meshStandardMaterial color={\"black\"} depthTest={true} />\n </mesh>\n </group>\n )\n })}\n </group>\n </RobotAnimator>\n </>\n )\n}\n","\"use client\"\nimport { useEffect } from \"react\"\n\nconst defaultWarn = console.warn\n\nexport default function ConsoleFilter() {\n useEffect(() => {\n console.warn = (data) => {\n // This message is caused by a bug from useSpring in combination with Canvas \"demand\" frameloop.\n // For now we can only suppress this warning there are no sideeffects yet\n // See https://github.com/pmndrs/react-spring/issues/1586#issuecomment-915051856\n if (\n data ===\n \"Cannot call the manual advancement of rafz whilst frameLoop is not set as demand\"\n ) {\n return\n }\n\n defaultWarn(data)\n }\n }, [])\n\n return <></>\n}\n","import { useGLTF } from \"@react-three/drei\"\nimport type { ThreeElements } from \"@react-three/fiber\"\nimport React, { useCallback, useEffect, useState } from \"react\"\nimport type { Group, Mesh } from \"three\"\nimport { type Object3D } from \"three\"\nimport { isFlange, parseRobotModel } from \"./robotModelLogic\"\n\nexport type RobotModelProps = {\n modelURL: string | Promise<string>\n /**\n * Called after a robot model has been loaded and\n * rendered into the threejs scene\n */\n postModelRender?: () => void\n flangeRef?: React.Ref<Group>\n} & ThreeElements[\"group\"]\n\nfunction isMesh(node: Object3D): node is Mesh {\n return node.type === \"Mesh\"\n}\n\n// Separate component that only renders when we have a valid URL\nfunction LoadedRobotModel({ \n url, \n flangeRef, \n postModelRender, \n ...props \n}: { \n url: string\n flangeRef?: React.Ref<Group>\n postModelRender?: () => void\n} & ThreeElements[\"group\"]) {\n const gltfResult = useGLTF(url)\n let gltf\n try {\n const parsed = parseRobotModel(gltfResult, 'robot.glb')\n gltf = parsed.gltf\n } catch (err) {\n throw err;\n }\n\n const groupRef: React.RefCallback<Group> = useCallback(\n (group) => {\n if (group && postModelRender) {\n postModelRender()\n }\n },\n [postModelRender],\n )\n\n function renderNode(node: Object3D): React.ReactNode {\n try {\n if (isMesh(node)) {\n // Defensive: only render mesh if geometry exists\n if ((node as Mesh).geometry) {\n return (\n <mesh\n name={node.name}\n key={node.uuid}\n geometry={(node as Mesh).geometry}\n material={(node as Mesh).material}\n position={node.position}\n rotation={node.rotation}\n />\n )\n }\n // Fallback to empty group if geometry is missing\n return (\n <group name={node.name} key={node.uuid} position={node.position} rotation={node.rotation} />\n )\n } else {\n return (\n <group\n name={node.name}\n key={node.uuid}\n position={node.position}\n rotation={node.rotation}\n ref={isFlange(node) ? flangeRef : undefined}\n >\n {node.children.map(renderNode)}\n </group>\n )\n }\n } catch (e) {\n console.warn('Error rendering node', node.name, e)\n return null\n }\n }\n\n return (\n <group {...props} dispose={null} ref={groupRef}>\n {renderNode(gltf.scene)}\n </group>\n )\n}\n\nexport function GenericRobot({\n modelURL,\n flangeRef,\n postModelRender,\n ...props\n}: RobotModelProps) {\n const [resolvedURL, setResolvedURL] = useState<string | null>(null)\n \n useEffect(() => {\n const resolveURL = async () => {\n try {\n if (typeof modelURL === 'string') {\n setResolvedURL(modelURL)\n } else {\n const url = await modelURL\n setResolvedURL(url)\n }\n } catch (error) {\n console.error('Failed to resolve model URL:', error)\n }\n }\n \n resolveURL()\n }, [modelURL])\n\n // Don't render until we have a resolved URL\n if (!resolvedURL) {\n return null // Loading state\n }\n \n return (\n <LoadedRobotModel \n url={resolvedURL}\n flangeRef={flangeRef}\n postModelRender={postModelRender}\n {...props}\n />\n )\n}\n","import * as THREE from \"three\"\n\nexport const applyGhostStyle = (robot: THREE.Group, color: string) => {\n if (robot.userData.isGhost) return\n\n robot.traverse((obj) => {\n if (obj instanceof THREE.Mesh) {\n if (obj.material instanceof THREE.Material) {\n obj.material.colorWrite = false\n }\n\n // Create a clone of the mesh\n const depth = obj.clone()\n const ghost = obj.clone()\n\n depth.material = new THREE.MeshStandardMaterial({\n depthTest: true,\n depthWrite: true,\n colorWrite: false,\n polygonOffset: true,\n polygonOffsetFactor: -1,\n side: THREE.DoubleSide,\n })\n depth.userData.isGhost = true\n\n // Set the material for the ghost mesh\n ghost.material = new THREE.MeshStandardMaterial({\n color: color,\n opacity: 0.3,\n depthTest: true,\n depthWrite: false,\n transparent: true,\n polygonOffset: true,\n polygonOffsetFactor: -2,\n side: THREE.DoubleSide,\n })\n ghost.userData.isGhost = true\n\n if (obj.parent) {\n obj.parent.add(depth)\n obj.parent.add(ghost)\n }\n }\n })\n\n robot.userData.isGhost = true\n}\n\nexport const removeGhostStyle = (robot: THREE.Group) => {\n if (!robot.userData.isGhost) return\n\n const objectsToRemove: THREE.Object3D[] = []\n\n robot.traverse((obj) => {\n if (obj instanceof THREE.Mesh) {\n if (obj.userData?.isGhost) {\n objectsToRemove.push(obj)\n } else if (obj.material instanceof THREE.Material) {\n obj.material.colorWrite = true\n }\n }\n })\n\n objectsToRemove.forEach((obj) => {\n if (obj.parent) {\n obj.parent.remove(obj)\n }\n })\n\n robot.userData.isGhost = false\n}\n","import type { ThreeElements } from \"@react-three/fiber\"\nimport type { DHParameter, MotionGroupState } from \"@wandelbots/nova-js/v2\"\nimport { Suspense, useCallback, useEffect, useState } from \"react\"\nimport { DHRobot } from \"./DHRobot\"\n\nimport { ErrorBoundary } from \"react-error-boundary\"\nimport type * as THREE from \"three\"\nimport { externalizeComponent } from \"../../externalizeComponent\"\nimport ConsoleFilter from \"../ConsoleFilter\"\nimport { GenericRobot } from \"./GenericRobot\"\nimport RobotAnimator from \"./RobotAnimator\"\nimport { applyGhostStyle, removeGhostStyle } from \"./ghostStyle\"\nimport { defaultGetModel } from \"./robotModelLogic\"\n\nexport type DHRobotProps = {\n rapidlyChangingMotionState: MotionGroupState\n dhParameters: Array<DHParameter>\n} & ThreeElements[\"group\"]\n\nexport type SupportedRobotProps = {\n rapidlyChangingMotionState: MotionGroupState\n modelFromController: string\n dhParameters: DHParameter[]\n flangeRef?: React.Ref<THREE.Group>\n instanceUrl?: string\n getModel?: (modelFromController: string, instanceUrl?: string) => Promise<string> | undefined\n postModelRender?: () => void\n transparentColor?: string\n} & ThreeElements[\"group\"]\n\nexport const SupportedRobot = externalizeComponent(\n ({\n rapidlyChangingMotionState,\n modelFromController,\n dhParameters,\n getModel = defaultGetModel,\n flangeRef,\n postModelRender,\n transparentColor,\n instanceUrl,\n ...props\n }: SupportedRobotProps) => {\n const [robotGroup, setRobotGroup] = useState<THREE.Group | null>(null)\n\n const setRobotRef = useCallback((instance: THREE.Group | null) => {\n setRobotGroup(instance)\n }, [])\n\n useEffect(() => {\n if (!robotGroup) return\n\n if (transparentColor) {\n applyGhostStyle(robotGroup, transparentColor)\n } else {\n removeGhostStyle(robotGroup)\n }\n }, [robotGroup, transparentColor])\n\n const dhrobot = (\n <DHRobot\n rapidlyChangingMotionState={rapidlyChangingMotionState}\n dhParameters={dhParameters}\n {...props}\n />\n )\n\n return (\n <ErrorBoundary\n fallback={dhrobot}\n onError={(err) => {\n // Missing model; show the fallback for now\n console.warn(err)\n }}\n >\n <Suspense fallback={dhrobot}>\n <group ref={setRobotRef}>\n <RobotAnimator\n rapidlyChangingMotionState={rapidlyChangingMotionState}\n dhParameters={dhParameters}\n >\n <GenericRobot\n modelURL={(() => {\n const result = getModel(modelFromController, instanceUrl)\n if (!result) {\n const mockBlob = new Blob([], { type: 'model/gltf-binary' })\n const mockFile = new File([mockBlob], `${modelFromController}.glb`, { type: 'model/gltf-binary' })\n return Promise.resolve(URL.createObjectURL(mockFile))\n }\n return result\n })()}\n postModelRender={postModelRender}\n flangeRef={flangeRef}\n {...props}\n />\n </RobotAnimator>\n </group>\n </Suspense>\n <ConsoleFilter />\n </ErrorBoundary>\n )\n },\n)\n","import type { ThreeElements } from \"@react-three/fiber\"\n\nimport type { Group } from \"three\"\nimport type { ConnectedMotionGroup } from \"../../lib/ConnectedMotionGroup\"\nimport { defaultGetModel } from \"./robotModelLogic\"\nimport { SupportedRobot } from \"./SupportedRobot\"\n\nexport type RobotProps = {\n connectedMotionGroup: ConnectedMotionGroup\n getModel?: (modelFromController: string) => Promise<string>\n flangeRef?: React.Ref<Group>\n transparentColor?: string\n postModelRender?: () => void\n} & ThreeElements[\"group\"]\n\n/**\n * The Robot component is a wrapper around the SupportedRobot component\n * for usage with @wandelbots/nova-js ConnectedMotionGroup object.\n *\n * @param {RobotProps} props - The properties for the Robot component.\n * @param {ConnectedMotionGroup} props.connectedMotionGroup - The connected motion group containing motion state and parameters.\n * @param {Function} [props.getModel=defaultGetModel] - Optional function to get the model URL. Defaults to defaultGetModel.\n * @param {Object} props - Additional properties passed to the SupportedRobot component.\n *\n * @returns {JSX.Element} The rendered SupportedRobot component.\n */\nexport function Robot({\n connectedMotionGroup,\n getModel = defaultGetModel,\n flangeRef,\n transparentColor,\n postModelRender,\n ...props\n}: RobotProps) {\n if (!connectedMotionGroup.dhParameters) {\n return null\n }\n\n return (\n <SupportedRobot\n rapidlyChangingMotionState={\n connectedMotionGroup.rapidlyChangingMotionState\n }\n modelFromController={connectedMotionGroup.modelFromController || \"\"}\n dhParameters={connectedMotionGroup.dhParameters}\n getModel={getModel}\n flangeRef={flangeRef}\n transparentColor={transparentColor}\n postModelRender={postModelRender}\n {...props}\n />\n )\n}\n\nexport { defaultGetModel }\n","import { Box, Button, Card, Divider, Typography, useTheme } from \"@mui/material\"\nimport { Bounds } from \"@react-three/drei\"\nimport { Canvas } from \"@react-three/fiber\"\nimport type { OperationMode, SafetyStateType } from \"@wandelbots/nova-js/v2\"\nimport { observer } from \"mobx-react-lite\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useTranslation } from \"react-i18next\"\nimport type { Group } from \"three\"\nimport { externalizeComponent } from \"../externalizeComponent\"\nimport type { ConnectedMotionGroup } from \"../lib/ConnectedMotionGroup\"\nimport { PresetEnvironment } from \"./3d-viewport/PresetEnvironment\"\nimport type { ProgramState } from \"./ProgramControl\"\nimport { ProgramStateIndicator } from \"./ProgramStateIndicator\"\nimport { Robot } from \"./robots/Robot\"\n\nexport interface RobotCardProps {\n /** Name of the robot displayed at the top */\n robotName: string\n /** Current program state */\n programState: ProgramState\n /** Current safety state of the robot controller */\n safetyState: SafetyStateType\n /** Current operation mode of the robot controller */\n operationMode: OperationMode\n /** Whether the \"Drive to Home\" button should be enabled */\n driveToHomeEnabled?: boolean\n /** Callback fired when \"Drive to Home\" button is pressed */\n onDriveToHomePress?: () => void\n /** Callback fired when \"Drive to Home\" button is released */\n onDriveToHomeRelease?: () => void\n /**\n * Callback fired when \"Drive to Home\" button is pressed, with the default home position.\n * If provided, this will be called instead of onDriveToHomePress, providing the recommended\n * home position joint configuration based on the robot manufacturer.\n */\n onDriveToHomePressWithConfig?: (homePosition: number[]) => void\n /**\n * Callback fired when \"Drive to Home\" button is released after using onDriveToHomePressWithConfig.\n * If provided, this will be called instead of onDriveToHomeRelease.\n */\n onDriveToHomeReleaseWithConfig?: () => void\n /**\n * Custom default joint configuration to use if manufacturer-based defaults are not available.\n * Joint values should be in radians.\n */\n defaultJointConfig?: number[]\n /** Connected motion group for the robot */\n connectedMotionGroup: ConnectedMotionGroup\n /** Custom robot component to render (optional, defaults to Robot) */\n robotComponent?: React.ComponentType<{\n connectedMotionGroup: ConnectedMotionGroup\n flangeRef?: React.Ref<Group>\n postModelRender?: () => void\n transparentColor?: string\n getModel?: (modelFromController: string) => Promise<string>\n }>\n /** Custom component to render in the content area (optional) */\n customContentComponent?: React.ComponentType<Record<string, unknown>>\n /** Additional CSS class name */\n className?: string\n}\n\n/**\n * A responsive card component that displays a 3D robot with states and controls.\n * The card automatically adapts to its container's size and aspect ratio.\n *\n * Features:\n * - Fully responsive Material-UI Card that adapts to container dimensions\n * - Automatic layout switching based on aspect ratio:\n * - Portrait mode: Vertical layout with robot in center\n * - Landscape mode: Horizontal layout with robot on left, content on right (left-aligned)\n * - Responsive 3D robot rendering:\n * - Scales dynamically with container size\n * - Hides at very small sizes to preserve usability\n * - Adaptive margin based on available space\n * - Smart spacing and padding that reduces at smaller sizes\n * - Minimum size constraints for usability while maximizing content density\n * - Robot name displayed in Typography h6 at top-left\n * - Program state indicator below the name\n * - Auto-fitting 3D robot model that scales with container size\n * - Customizable content area for displaying custom React components\n * - Transparent gray divider line\n * - \"Drive to Home\" button with press-and-hold functionality\n * - Localization support via react-i18next\n * - Material-UI theming integration\n *\n * Usage with custom content:\n * ```tsx\n * // Example custom timer component\n * const CustomTimer = () => (\n * <Box>\n * <Typography variant=\"body1\" sx={{ color: \"text.secondary\" }}>\n * Runtime\n * </Typography>\n * <Typography variant=\"h6\">05:23</Typography>\n * </Box>\n * )\n *\n * <RobotCard\n * robotName=\"UR5e Robot\"\n * programState={ProgramState.RUNNING}\n * customContentComponent={CustomTimer}\n * // ... other props\n * />\n * ```\n */\nexport const RobotCard = externalizeComponent(\n observer(\n ({\n robotName,\n programState,\n safetyState,\n operationMode,\n driveToHomeEnabled = false,\n onDriveToHomePress,\n onDriveToHomeRelease,\n connectedMotionGroup,\n robotComponent: RobotComponent = Robot,\n customContentComponent: CustomContentComponent,\n className,\n }: RobotCardProps) => {\n const theme = useTheme()\n const { t } = useTranslation()\n const [isDriveToHomePressed, setIsDriveToHomePressed] = useState(false)\n const driveButtonRef = useRef<HTMLButtonElement>(null)\n const cardRef = useRef<HTMLDivElement>(null)\n const [isLandscape, setIsLandscape] = useState(false)\n const [cardSize, setCardSize] = useState<{\n width: number\n height: number\n }>({ width: 400, height: 600 })\n const [modelRenderTrigger, setModelRenderTrigger] = useState(0)\n\n // Hook to detect aspect ratio and size changes\n useEffect(() => {\n const checkDimensions = () => {\n if (cardRef.current) {\n const { offsetWidth, offsetHeight } = cardRef.current\n setIsLandscape(offsetWidth > offsetHeight)\n setCardSize({ width: offsetWidth, height: offsetHeight })\n }\n }\n\n // Initial check\n checkDimensions()\n\n // Set up ResizeObserver to watch for size changes\n const resizeObserver = new ResizeObserver(checkDimensions)\n if (cardRef.current) {\n resizeObserver.observe(cardRef.current)\n }\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [])\n\n const handleModelRender = useCallback(() => {\n // Trigger bounds refresh when model renders\n setModelRenderTrigger((prev) => prev + 1)\n }, [])\n\n const handleDriveToHomeMouseDown = useCallback(() => {\n if (!driveToHomeEnabled || !onDriveToHomePress) return\n setIsDriveToHomePressed(true)\n onDriveToHomePress()\n }, [driveToHomeEnabled, onDriveToHomePress])\n\n const handleDriveToHomeMouseUp = useCallback(() => {\n if (!driveToHomeEnabled || !onDriveToHomeRelease) return\n setIsDriveToHomePressed(false)\n onDriveToHomeRelease()\n }, [driveToHomeEnabled, onDriveToHomeRelease])\n\n const handleDriveToHomeMouseLeave = useCallback(() => {\n if (isDriveToHomePressed && onDriveToHomeRelease) {\n setIsDriveToHomePressed(false)\n onDriveToHomeRelease()\n }\n }, [isDriveToHomePressed, onDriveToHomeRelease])\n\n // Determine if robot should be hidden at small sizes to save space\n const shouldHideRobot = isLandscape\n ? cardSize.width < 350\n : cardSize.height < 200 // Hide robot at height < 200px in portrait\n\n // Determine if custom content should be hidden when height is too low\n // Custom content should be hidden BEFORE the robot (at higher threshold)\n const shouldHideCustomContent = isLandscape\n ? cardSize.height < 310 // Landscape: hide custom content at height < 310px\n : cardSize.height < 450 // Portrait: hide custom content at height < 450px\n\n return (\n <Card\n ref={cardRef}\n className={className}\n sx={{\n width: \"100%\",\n height: \"100%\",\n display: \"flex\",\n flexDirection: isLandscape ? \"row\" : \"column\",\n position: \"relative\",\n overflow: \"hidden\",\n minWidth: { xs: 180, sm: 220, md: 250 },\n minHeight: isLandscape\n ? { xs: 200, sm: 240, md: 260 } // Allow runtime hiding at < 283px\n : { xs: 150, sm: 180, md: 220 }, // Allow progressive hiding in portrait mode\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: \"18px\",\n boxShadow: \"none\",\n backgroundColor:\n theme.palette.backgroundPaperElevation?.[8] || \"#2A2A3F\",\n backgroundImage: \"none\", // Override any gradient from elevation\n }}\n >\n {isLandscape ? (\n <>\n {/* Landscape Layout: Robot on left, content on right */}\n <Box\n sx={{\n flex: \"0 0 50%\",\n position: \"relative\",\n height: \"100%\",\n minHeight: \"100%\",\n maxHeight: \"100%\",\n borderRadius: 1,\n m: { xs: 1.5, sm: 2, md: 3 },\n mr: { xs: 0.75, sm: 1, md: 1.5 },\n overflow: \"hidden\", // Prevent content from affecting container size\n display: shouldHideRobot ? \"none\" : \"block\",\n }}\n >\n {!shouldHideRobot && (\n <Canvas\n orthographic\n camera={{\n position: [3, 2, 3],\n zoom: 1,\n }}\n shadows\n frameloop=\"demand\"\n style={{\n borderRadius: theme.shape.borderRadius,\n width: \"100%\",\n height: \"100%\",\n background: \"transparent\",\n position: \"absolute\",\n top: 0,\n left: 0,\n }}\n dpr={[1, 2]}\n gl={{ alpha: true, antialias: true }}\n >\n <PresetEnvironment />\n <Bounds fit observe margin={1} maxDuration={1}>\n <RobotComponent\n connectedMotionGroup={connectedMotionGroup}\n postModelRender={handleModelRender}\n />\n </Bounds>\n </Canvas>\n )}\n </Box>\n\n {/* Content container on right */}\n <Box\n sx={{\n flex: shouldHideRobot ? \"1\" : \"1\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-start\",\n width: shouldHideRobot ? \"100%\" : \"50%\",\n }}\n >\n {/* Header section with robot name and program state */}\n <Box\n sx={{\n p: { xs: 1.5, sm: 2, md: 3 },\n pb: { xs: 1, sm: 1.5, md: 2 },\n textAlign: \"left\",\n }}\n >\n <Typography variant=\"h6\" component=\"h2\" sx={{ mb: 1 }}>\n {robotName}\n </Typography>\n <ProgramStateIndicator\n programState={programState}\n safetyState={safetyState}\n operationMode={operationMode}\n />\n </Box>\n\n {/* Bottom section with custom content and button */}\n <Box\n sx={{\n p: { xs: 1.5, sm: 2, md: 3 },\n pt: 0,\n flex: \"1\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"space-between\",\n }}\n >\n {/* Custom content section - hidden if height is too low in landscape mode */}\n {!shouldHideCustomContent && CustomContentComponent && (\n <Box>\n <CustomContentComponent />\n\n {/* Divider */}\n <Divider\n sx={{\n mt: 1,\n mb: 0,\n borderColor: theme.palette.divider,\n opacity: 0.5,\n }}\n />\n </Box>\n )}\n\n <Box\n sx={{\n mt:\n !shouldHideCustomContent && CustomContentComponent\n ? \"auto\"\n : 0,\n }}\n >\n {/* Drive to Home button with some space */}\n <Box\n sx={{\n display: \"flex\",\n justifyContent: \"flex-start\",\n mt: { xs: 1, sm: 1.5, md: 2 },\n mb: { xs: 0.5, sm: 0.75, md: 1 },\n }}\n >\n <Button\n ref={driveButtonRef}\n variant=\"contained\"\n color=\"secondary\"\n size=\"small\"\n disabled={!driveToHomeEnabled}\n onMouseDown={handleDriveToHomeMouseDown}\n onMouseUp={handleDriveToHomeMouseUp}\n onMouseLeave={handleDriveToHomeMouseLeave}\n onTouchStart={handleDriveToHomeMouseDown}\n onTouchEnd={handleDriveToHomeMouseUp}\n sx={{\n textTransform: \"none\",\n px: 1.5,\n py: 0.5,\n }}\n >\n {t(\"RobotCard.DriveToHome.bt\")}\n </Button>\n </Box>\n </Box>\n </Box>\n </Box>\n </>\n ) : (\n <>\n {/* Portrait Layout: Header, Robot, Footer */}\n <Box\n sx={{\n p: 3,\n height: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n {/* Header section with robot name and program state */}\n <Box>\n <Typography variant=\"h6\" component=\"h2\" sx={{ mb: 1 }}>\n {robotName}\n </Typography>\n <ProgramStateIndicator\n programState={programState}\n safetyState={safetyState}\n operationMode={operationMode}\n />\n </Box>\n\n {/* 3D Robot viewport in center */}\n <Box\n sx={{\n flex: shouldHideRobot ? 0 : 1,\n position: \"relative\",\n minHeight: shouldHideRobot\n ? 0\n : { xs: 120, sm: 150, md: 200 },\n height: shouldHideRobot ? 0 : \"auto\",\n borderRadius: 1,\n overflow: \"hidden\",\n display: shouldHideRobot ? \"none\" : \"block\",\n }}\n >\n {!shouldHideRobot && (\n <Canvas\n orthographic\n camera={{\n position: [3, 2, 3],\n zoom: 1,\n }}\n shadows\n frameloop=\"demand\"\n style={{\n borderRadius: theme.shape.borderRadius,\n width: \"100%\",\n height: \"100%\",\n background: \"transparent\",\n position: \"absolute\",\n }}\n dpr={[1, 2]}\n gl={{ alpha: true, antialias: true }}\n >\n <PresetEnvironment />\n <Bounds fit clip observe margin={1} maxDuration={1}>\n <RobotComponent\n connectedMotionGroup={connectedMotionGroup}\n postModelRender={handleModelRender}\n />\n </Bounds>\n </Canvas>\n )}\n </Box>\n\n {/* Bottom section with custom content and button */}\n <Box>\n {/* Custom content section - hidden if height is too low */}\n {!shouldHideCustomContent && CustomContentComponent && (\n <>\n <CustomContentComponent />\n\n {/* Divider */}\n <Divider\n sx={{\n mt: 1,\n mb: 0,\n borderColor: theme.palette.divider,\n opacity: 0.5,\n }}\n />\n </>\n )}\n\n {/* Drive to Home button with some space */}\n <Box\n sx={{\n display: \"flex\",\n justifyContent: \"flex-start\",\n mt:\n !shouldHideCustomContent && CustomContentComponent\n ? { xs: 1, sm: 2, md: 5 }\n : { xs: 0.5, sm: 1, md: 2 },\n mb: { xs: 0.5, sm: 0.75, md: 1 },\n }}\n >\n <Button\n ref={driveButtonRef}\n variant=\"contained\"\n color=\"secondary\"\n size=\"small\"\n disabled={!driveToHomeEnabled}\n onMouseDown={handleDriveToHomeMouseDown}\n onMouseUp={handleDriveToHomeMouseUp}\n onMouseLeave={handleDriveToHomeMouseLeave}\n onTouchStart={handleDriveToHomeMouseDown}\n onTouchEnd={handleDriveToHomeMouseUp}\n sx={{\n textTransform: \"none\",\n px: 1.5,\n py: 0.5,\n }}\n >\n {t(\"RobotCard.DriveToHome.bt\")}\n </Button>\n </Box>\n </Box>\n </Box>\n </>\n )}\n </Card>\n )\n },\n ),\n)\n","export type AxisConfig = number[]\n\nexport const defaultAxisConfig: AxisConfig = Array(6).fill(2 * Math.PI)\n","import { useFrame, useThree } from \"@react-three/fiber\"\nimport type { DHParameter, MotionGroupState } from \"@wandelbots/nova-js/v2\"\nimport React, { useCallback, useEffect, useRef } from \"react\"\nimport type { Group, Object3D } from \"three\"\nimport { useAutorun } from \"../utils/hooks\"\nimport { ValueInterpolator } from \"../utils/interpolation\"\nimport { collectJoints } from \"./robotModelLogic\"\n\ntype LinearAxisAnimatorProps = {\n rapidlyChangingMotionState: MotionGroupState\n dhParameters: DHParameter[]\n onTranslationChanged?: (joints: Object3D[], jointValues: number[]) => void\n children: React.ReactNode\n}\n\nexport default function LinearAxisAnimator({\n rapidlyChangingMotionState,\n dhParameters,\n onTranslationChanged,\n children,\n}: LinearAxisAnimatorProps) {\n const jointValues = useRef<number[]>([])\n const jointObjects = useRef<Object3D[]>([])\n const interpolatorRef = useRef<ValueInterpolator | null>(null)\n const { invalidate } = useThree()\n\n // Initialize interpolator\n useEffect(() => {\n const initialJointValues = rapidlyChangingMotionState.joint_position.filter(\n (item) => item !== undefined,\n )\n\n interpolatorRef.current = new ValueInterpolator(initialJointValues, {\n tension: 120, // Controls spring stiffness - higher values create faster, more responsive motion\n friction: 20, // Controls damping - higher values reduce oscillation and create smoother settling\n threshold: 0.001,\n })\n\n return () => {\n interpolatorRef.current?.destroy()\n }\n }, [])\n\n // Animation loop that runs at the display's refresh rate\n useFrame((state, delta) => {\n if (interpolatorRef.current) {\n const isComplete = interpolatorRef.current.update(delta)\n setTranslation()\n\n // Trigger a re-render only if the animation is still running\n if (!isComplete) {\n invalidate()\n }\n }\n })\n\n function setGroupRef(group: Group | null) {\n if (!group) return\n\n jointObjects.current = collectJoints(group)\n\n // Set initial position\n setTranslation()\n invalidate()\n }\n\n function setTranslation() {\n const updatedJointValues = interpolatorRef.current?.getCurrentValues() || []\n\n if (onTranslationChanged) {\n onTranslationChanged(jointObjects.current, updatedJointValues)\n } else {\n // For linear axes, we apply translation instead of rotation\n for (const [index, object] of jointObjects.current.entries()) {\n const dhParam = dhParameters[index]\n const translationSign = dhParam.reverse_rotation_direction ? -1 : 1\n\n // Apply linear translation along Y axis\n // Convert from millimeters to meters\n object.position.y =\n (translationSign * (updatedJointValues[index] || 0)) / 1000\n }\n }\n }\n\n const updateJoints = useCallback(() => {\n const newJointValues = rapidlyChangingMotionState.joint_position.filter(\n (item) => item !== undefined,\n )\n\n requestAnimationFrame(() => {\n jointValues.current = newJointValues\n interpolatorRef.current?.setTarget(newJointValues)\n })\n }, [rapidlyChangingMotionState])\n\n /**\n * Fire an update joints call on every motion state change.\n * requestAnimationFrame used to avoid blocking main thread\n */\n useEffect(() => {\n updateJoints()\n }, [rapidlyChangingMotionState, updateJoints])\n\n /**\n * As some consumer applications (eg. storybook) deliver\n * mobx observable for rapidlyChangingMotionState, we need to\n * register the watcher to get the newest value updates\n */\n useAutorun(() => {\n updateJoints()\n })\n\n return <group ref={setGroupRef}>{children}</group>\n}\n","import { Line } from \"@react-three/drei\"\nimport type { DHParameter } from \"@wandelbots/nova-js/v2\"\nimport React, { useRef } from \"react\"\nimport type * as THREE from \"three\"\nimport { Matrix4, Quaternion, Vector3 } from \"three\"\nimport LinearAxisAnimator from \"./LinearAxisAnimator\"\nimport type { DHLinearAxisProps } from \"./SupportedLinearAxis\"\n\nexport function DHLinearAxis({\n rapidlyChangingMotionState,\n dhParameters,\n ...props\n}: DHLinearAxisProps) {\n // reused in every update\n const accumulatedMatrix = new Matrix4()\n\n const tcpMeshRef = useRef<THREE.Mesh | null>(null)\n const tcpLineRef = useRef<any>(null)\n\n // Calculate initial TCP position\n function calculateTcpPosition(jointValues: number[]): Vector3 {\n const tempMatrix = new Matrix4()\n \n for (let i = 0; i < dhParameters.length; i++) {\n const param = dhParameters[i]\n const jointValue = jointValues[i] ?? 0\n \n const matrix = new Matrix4()\n .makeRotationY(param.theta!) // Base rotation (if any)\n .multiply(\n new Matrix4().makeTranslation(\n param.a! / 1000,\n (param.d! + jointValue * (param.reverse_rotation_direction ? -1 : 1)) / 1000,\n 0\n )\n ) // Translate along X by a, and Y by d + joint_position\n .multiply(new Matrix4().makeRotationX(param.alpha!)) // Rotate around X\n \n tempMatrix.multiply(matrix)\n }\n \n const position = new Vector3()\n const quaternion = new Quaternion()\n const scale = new Vector3()\n tempMatrix.decompose(position, quaternion, scale)\n return position\n }\n\n // Calculate initial TCP position for rendering\n const initialTcpPosition = calculateTcpPosition(rapidlyChangingMotionState.joint_position)\n\n function setTranslation(joints: THREE.Object3D[], jointValues: number[]) {\n accumulatedMatrix.identity()\n\n let tcpPosition = new Vector3()\n\n // Process all joints based on dhParameters length, not joints array\n // Since we're using DHLinearAxis directly without a model, we don't have joint objects\n for (let jointIndex = 0; jointIndex < dhParameters.length; jointIndex++) {\n const jointValue = jointValues[jointIndex] ?? 0\n const param = dhParameters[jointIndex]\n \n // Calculate and accumulate transformation\n const matrix = new Matrix4()\n .makeRotationY(param.theta!) // Base rotation (if any)\n .multiply(\n new Matrix4().makeTranslation(\n param.a! / 1000,\n (param.d! + jointValue * (param.reverse_rotation_direction ? -1 : 1)) / 1000,\n 0\n )\n )\n .multiply(new Matrix4().makeRotationX(param.alpha!))\n \n accumulatedMatrix.multiply(matrix)\n }\n\n // Get final TCP position from accumulated matrix\n const position = new Vector3()\n const quaternion = new Quaternion()\n const scale = new Vector3()\n accumulatedMatrix.decompose(position, quaternion, scale)\n tcpPosition = position\n\n // Update TCP marker\n if (tcpMeshRef.current) {\n tcpMeshRef.current.position.set(tcpPosition.x, tcpPosition.y, tcpPosition.z)\n }\n\n // Update TCP line\n if (tcpLineRef.current) {\n const lineGeometry = tcpLineRef.current.geometry\n if (lineGeometry && lineGeometry.setPositions) {\n lineGeometry.setPositions([0, 0, 0, tcpPosition.x, tcpPosition.y, tcpPosition.z])\n }\n }\n }\n\n return (\n <>\n <LinearAxisAnimator\n rapidlyChangingMotionState={rapidlyChangingMotionState}\n dhParameters={dhParameters}\n onTranslationChanged={setTranslation}\n >\n <group {...props} name=\"Scene\">\n {/* Base (origin) - Green sphere representing initial previous position */}\n <mesh name=\"Base\" position={[0, 0, 0]}>\n <sphereGeometry args={[0.02, 32, 32]} />\n <meshStandardMaterial color={\"green\"} depthTest={true} />\n </mesh>\n {/* Line from Base to TCP */}\n <Line\n ref={tcpLineRef}\n points={[new Vector3(0, 0, 0), initialTcpPosition]}\n color={\"White\"}\n lineWidth={5}\n />\n {/* TCP (Tool Center Point) - Red sphere that shows final position */}\n <mesh ref={tcpMeshRef} name=\"TCP\" position={initialTcpPosition}>\n <sphereGeometry args={[0.025, 32, 32]} />\n <meshStandardMaterial color={\"red\"} depthTest={true} />\n </mesh>\n </group>\n </LinearAxisAnimator>\n </>\n )\n}\n","import type { ThreeElements } from \"@react-three/fiber\"\nimport type { DHParameter, MotionGroupState } from \"@wandelbots/nova-js/v2\"\nimport { Suspense, useCallback, useEffect, useState } from \"react\"\nimport { ErrorBoundary } from \"react-error-boundary\"\nimport type * as THREE from \"three\"\nimport { externalizeComponent } from \"../../externalizeComponent\"\nimport ConsoleFilter from \"../ConsoleFilter\"\nimport { DHLinearAxis } from \"./DHLinearAxis\"\nimport { GenericRobot } from \"./GenericRobot\"\nimport LinearAxisAnimator from \"./LinearAxisAnimator\"\nimport { applyGhostStyle, removeGhostStyle } from \"./ghostStyle\"\nimport { defaultGetModel } from \"./robotModelLogic\"\n\nexport type DHLinearAxisProps = {\n rapidlyChangingMotionState: MotionGroupState\n dhParameters: Array<DHParameter>\n} & ThreeElements[\"group\"]\n\nexport type SupportedLinearAxisProps = {\n rapidlyChangingMotionState: MotionGroupState\n modelFromController: string\n dhParameters: DHParameter[]\n flangeRef?: React.Ref<THREE.Group>\n instanceUrl?: string\n getModel?: (modelFromController: string, instanceUrl?: string) => Promise<string> | undefined\n postModelRender?: () => void\n transparentColor?: string\n} & ThreeElements[\"group\"]\n\nexport const SupportedLinearAxis = externalizeComponent(\n ({\n rapidlyChangingMotionState,\n modelFromController,\n dhParameters,\n getModel = defaultGetModel,\n flangeRef,\n postModelRender,\n transparentColor,\n instanceUrl,\n ...props\n }: SupportedLinearAxisProps) => {\n const [robotGroup, setRobotGroup] = useState<THREE.Group | null>(null)\n\n const setRobotRef = useCallback((instance: THREE.Group | null) => {\n setRobotGroup(instance)\n }, [])\n\n useEffect(() => {\n if (!robotGroup) return\n\n if (transparentColor) {\n applyGhostStyle(robotGroup, transparentColor)\n } else {\n removeGhostStyle(robotGroup)\n }\n }, [robotGroup, transparentColor])\n\n const dhLinearAxis = (\n <DHLinearAxis\n rapidlyChangingMotionState={rapidlyChangingMotionState}\n dhParameters={dhParameters}\n {...props}\n />\n )\n\n return (\n <ErrorBoundary\n fallback={dhLinearAxis}\n onError={(err) => {\n // Missing model; show the fallback for now\n console.warn(err)\n }}\n >\n <Suspense fallback={dhLinearAxis}>\n <group ref={setRobotRef}>\n <LinearAxisAnimator\n rapidlyChangingMotionState={rapidlyChangingMotionState}\n dhParameters={dhParameters}\n >\n <GenericRobot\n modelURL={(() => {\n const result = getModel(modelFromController, instanceUrl)\n if (!result) {\n const mockBlob = new Blob([], { type: 'model/gltf-binary' })\n const mockFile = new File([mockBlob], `${modelFromController}.glb`, { type: 'model/gltf-binary' })\n return Promise.resolve(URL.createObjectURL(mockFile))\n }\n return result\n })()}\n postModelRender={postModelRender}\n flangeRef={flangeRef}\n {...props}\n />\n </LinearAxisAnimator>\n </group>\n </Suspense>\n <ConsoleFilter />\n </ErrorBoundary>\n )\n },\n)\n","import type { ThreeElements } from \"@react-three/fiber\"\n\nimport type { Group } from \"three\"\nimport type { ConnectedMotionGroup } from \"../../lib/ConnectedMotionGroup\"\nimport { DHLinearAxis } from \"./DHLinearAxis\"\nimport { defaultGetModel } from \"./robotModelLogic\"\nimport { SupportedLinearAxis } from \"./SupportedLinearAxis\"\n\nexport type LinearAxisProps = {\n connectedMotionGroup: ConnectedMotionGroup\n getModel?: (modelFromController: string) => Promise<string>\n flangeRef?: React.Ref<Group>\n transparentColor?: string\n postModelRender?: () => void\n} & ThreeElements[\"group\"]\n\n/**\n * The LinearAxis component is a wrapper that renders SupportedLinearAxis if a model is available,\n * otherwise falls back to DHLinearAxis for usage with @wandelbots/nova-js ConnectedMotionGroup object.\n *\n * @param {LinearAxisProps} props - The properties for the LinearAxis component.\n * @param {ConnectedMotionGroup} props.connectedMotionGroup - The connected motion group containing motion state and parameters.\n * @param {Function} [props.getModel=defaultGetModel] - Optional function to get the model URL. Defaults to defaultGetModel.\n * @param {Object} props - Additional properties passed to the underlying component.\n *\n * @returns {JSX.Element} The rendered SupportedLinearAxis or DHLinearAxis component.\n */\nexport function LinearAxis({\n connectedMotionGroup,\n getModel = defaultGetModel,\n flangeRef,\n transparentColor,\n postModelRender,\n ...props\n}: LinearAxisProps) {\n if (!connectedMotionGroup.dhParameters) {\n return null\n }\n\n const modelFromController = connectedMotionGroup.modelFromController || \"\"\n const hasModel = modelFromController && getModel(modelFromController)\n\n // Use SupportedLinearAxis if model is available, otherwise fall back to DHLinearAxis\n if (hasModel) {\n return (\n <SupportedLinearAxis\n rapidlyChangingMotionState={\n connectedMotionGroup.rapidlyChangingMotionState\n }\n modelFromController={modelFromController}\n dhParameters={connectedMotionGroup.dhParameters}\n getModel={getModel}\n flangeRef={flangeRef}\n transparentColor={transparentColor}\n postModelRender={postModelRender}\n {...props}\n />\n )\n }\n\n return (\n <DHLinearAxis\n rapidlyChangingMotionState={\n connectedMotionGroup.rapidlyChangingMotionState\n }\n dhParameters={connectedMotionGroup.dhParameters}\n {...props}\n />\n )\n}\n\nexport { defaultGetModel }\n\n","import { Manufacturer } from \"@wandelbots/nova-js/v2\"\n\n/**\n * Default home configs for different robot manufacturers.\n * These joint configurations represent safe home configs for each manufacturer's robots.\n * All angles are in radians.\n */\nexport const MANUFACTURER_HOME_CONFIGS: Record<Manufacturer, number[]> = {\n [Manufacturer.Abb]: [0.0, 0.0, 0.0, 0.0, Math.PI / 2, 0.0, 0.0],\n [Manufacturer.Fanuc]: [0.0, 0.0, 0.0, 0.0, -Math.PI / 2, 0.0, 0.0],\n [Manufacturer.Yaskawa]: [0.0, 0.0, 0.0, 0.0, -Math.PI / 2, 0.0, 0.0],\n [Manufacturer.Kuka]: [\n 0.0,\n -Math.PI / 2,\n Math.PI / 2,\n 0.0,\n Math.PI / 2,\n 0.0,\n 0.0,\n ],\n [Manufacturer.Universalrobots]: [\n 0.0,\n -Math.PI / 2,\n -Math.PI / 2,\n -Math.PI / 2,\n Math.PI / 2,\n -Math.PI / 2,\n 0.0,\n ],\n}\n\n/**\n * Extracts manufacturer from modelFromController string.\n * @param modelFromController - String in format \"Manufacturer_ModelName\"\n * @returns Manufacturer enum value or null if not recognized\n */\nexport function extractManufacturer(\n modelFromController: string,\n): Manufacturer | null {\n const [manufacturerString] = modelFromController.split(\"_\")\n\n // Handle the mapping from string to enum\n switch (manufacturerString) {\n case \"ABB\":\n return Manufacturer.Abb\n case \"FANUC\":\n return Manufacturer.Fanuc\n case \"YASKAWA\":\n return Manufacturer.Yaskawa\n case \"KUKA\":\n return Manufacturer.Kuka\n case \"UniversalRobots\":\n return Manufacturer.Universalrobots\n default:\n return null\n }\n}\n\n/**\n * Gets the default home config for a robot based on its model identifier.\n * @param modelFromController - String in format \"Manufacturer_ModelName\"\n * @param defaultJointConfig - Optional custom default configuration to use if manufacturer not found\n * @returns Array of joint positions in radians, or null if no configuration available\n */\nexport function getDefaultHomeConfig(\n modelFromController: string,\n defaultJointConfig?: number[],\n): number[] | null {\n const manufacturer = extractManufacturer(modelFromController)\n\n if (manufacturer && manufacturer in MANUFACTURER_HOME_CONFIGS) {\n return MANUFACTURER_HOME_CONFIGS[manufacturer]\n }\n\n return defaultJointConfig || null\n}\n","import React, { useEffect, useMemo, useState } from \"react\"\nimport { JointTypeEnum } from \"@wandelbots/nova-js/v2\"\n\nimport { externalizeComponent } from \"../../externalizeComponent\"\nimport { SupportedRobot, type SupportedRobotProps } from \"./SupportedRobot\"\nimport { SupportedLinearAxis, type SupportedLinearAxisProps } from \"./SupportedLinearAxis\"\n\nexport type MotionGroupVisualizerProps = {\n instanceUrl: string\n inverseSolver?: string | null\n} & (SupportedRobotProps | SupportedLinearAxisProps)\n\nexport const MotionGroupVisualizer: React.FC<MotionGroupVisualizerProps> = externalizeComponent((props: MotionGroupVisualizerProps) => {\n const {\n inverseSolver,\n dhParameters,\n ...rest\n } = props\n\n /**\n * Joint type to find out - in combination with inverseSolver - whether the\n * active robot is a turn table\n */\n const [jointType, setJointType] = useState<JointTypeEnum>(JointTypeEnum.RevoluteJoint)\n\n /**\n * Sets the joint type according to delivered dh parameter type\n *\n * TODO as soon as V2 api migration is done, the setting of the default RevoluteJoint value should be\n * deleted, cause the type property is expected to be always delivered. It is not the case in the V1 at the\n * moment.\n */\n useEffect(() => {\n if (dhParameters.length) {\n setJointType(dhParameters[0].type ?? JointTypeEnum.RevoluteJoint)\n }\n }, [dhParameters])\n\n /**\n * The turntable models return inverseSolver = null - however these models\n * should be rendered with SupportedRobot instead of SupportedLinearAxis\n */\n const isTurnTable = useMemo(() => {\n return inverseSolver === null && jointType === JointTypeEnum.RevoluteJoint\n }, [inverseSolver, jointType])\n\n /**\n * Linear axis check\n */\n const isLinearAxis = useMemo(() => {\n return inverseSolver === null && jointType === JointTypeEnum.PrismaticJoint\n }, [inverseSolver, jointType])\n\n /**\n * Robot differentiation for readability reasons\n */\n const isRobot = useMemo(() => {\n return !!inverseSolver\n }, [inverseSolver])\n\n\n if (isRobot || isTurnTable) {\n return (\n <SupportedRobot dhParameters={dhParameters} {...rest} />\n )\n }\n\n if(isLinearAxis) {\n return (\n <SupportedLinearAxis dhParameters={dhParameters} {...rest} />\n )\n }\n\n return <></>\n})"],"mappings":"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"}