UNPKG

x_ite

Version:

X_ITE X3D Browser, view and manipulate X3D, VRML, glTF and other 3D sources in HTML.

1,574 lines (1,260 loc) 157 kB
/* X_ITE v12.2.3 */ const __X_ITE_X3D__ = window [Symbol .for ("X_ITE.X3D-12.2.3")]; /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* webpack/runtime/compat get default export */ /******/ (() => { /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = (module) => { /******/ var getter = module && module.__esModule ? /******/ () => (module['default']) : /******/ () => (module); /******/ __webpack_require__.d(getter, { a: getter }); /******/ return getter; /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /************************************************************************/ // UNUSED EXPORTS: default ;// external "__X_ITE_X3D__ .Components" const external_X_ITE_X3D_Components_namespaceObject = __X_ITE_X3D__ .Components; var external_X_ITE_X3D_Components_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Components_namespaceObject); ;// external "__X_ITE_X3D__ .Fields" const external_X_ITE_X3D_Fields_namespaceObject = __X_ITE_X3D__ .Fields; var external_X_ITE_X3D_Fields_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Fields_namespaceObject); ;// external "__X_ITE_X3D__ .X3DFieldDefinition" const external_X_ITE_X3D_X3DFieldDefinition_namespaceObject = __X_ITE_X3D__ .X3DFieldDefinition; var external_X_ITE_X3D_X3DFieldDefinition_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DFieldDefinition_namespaceObject); ;// external "__X_ITE_X3D__ .FieldDefinitionArray" const external_X_ITE_X3D_FieldDefinitionArray_namespaceObject = __X_ITE_X3D__ .FieldDefinitionArray; var external_X_ITE_X3D_FieldDefinitionArray_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_FieldDefinitionArray_namespaceObject); ;// external "__X_ITE_X3D__ .X3DNode" const external_X_ITE_X3D_X3DNode_namespaceObject = __X_ITE_X3D__ .X3DNode; var external_X_ITE_X3D_X3DNode_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DNode_namespaceObject); ;// external "__X_ITE_X3D__ .X3DConstants" const external_X_ITE_X3D_X3DConstants_namespaceObject = __X_ITE_X3D__ .X3DConstants; var external_X_ITE_X3D_X3DConstants_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DConstants_namespaceObject); ;// external "__X_ITE_X3D__ .X3DCast" const external_X_ITE_X3D_X3DCast_namespaceObject = __X_ITE_X3D__ .X3DCast; var external_X_ITE_X3D_X3DCast_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DCast_namespaceObject); ;// external "__X_ITE_X3D__ .Namespace" const external_X_ITE_X3D_Namespace_namespaceObject = __X_ITE_X3D__ .Namespace; var external_X_ITE_X3D_Namespace_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Namespace_namespaceObject); ;// ./src/x_ite/Components/NURBS/Contour2D.js function Contour2D (executionContext) { external_X_ITE_X3D_X3DNode_default().call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).Contour2D); this .childNodes = [ ]; } Object .assign (Object .setPrototypeOf (Contour2D .prototype, (external_X_ITE_X3D_X3DNode_default()).prototype), { initialize () { external_X_ITE_X3D_X3DNode_default().prototype .initialize .call (this); this ._addChildren .addInterest ("set_addChildren__", this); this ._removeChildren .addInterest ("set_removeChildren__", this); this ._children .addInterest ("set_children__", this); this .set_children__ (); }, set_addChildren__ () { this ._addChildren .setTainted (true); this ._addChildren .assign (filter (this ._addChildren, this ._children)); for (const child of this ._addChildren) this ._children .push (child); this ._addChildren .length = 0; this ._addChildren .setTainted (false); }, set_removeChildren__ () { this ._removeChildren .setTainted (true); this ._children .assign (filter (this ._children, this ._removeChildren)); this ._removeChildren .length = 0; this ._removeChildren .setTainted (false); }, set_children__ () { const childNodes = this .childNodes; for (const childNode of childNodes) childNode .removeInterest ("addNodeEvent", this); childNodes .length = 0; for (const node of this ._children) { const childNode = external_X_ITE_X3D_X3DCast_default() ((external_X_ITE_X3D_X3DConstants_default()).NurbsCurve2D, node) ?? external_X_ITE_X3D_X3DCast_default() ((external_X_ITE_X3D_X3DConstants_default()).ContourPolyline2D, node); if (childNode) childNodes .push (childNode); } for (const childNode of childNodes) childNode .addInterest ("addNodeEvent", this); }, addTrimmingContour (offset, scale, trimmingContours) { const trimmingContour = [ ]; for (const childNode of this .childNodes) childNode .tessellate (2, trimmingContour); if (!trimmingContour .length) return; for (const point of trimmingContour) point .subtract (offset) .divVec (scale); trimmingContours .push (trimmingContour); } }); function filter (array, remove) { const set = new Set (remove); return array .filter (value => !set .has (value)); } Object .defineProperties (Contour2D, { ... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("Contour2D", "NURBS", 4, "trimmingContour", "3.0"), fieldDefinitions: { value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOnly, "addChildren", new (external_X_ITE_X3D_Fields_default()).MFNode ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOnly, "removeChildren", new (external_X_ITE_X3D_Fields_default()).MFNode ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "children", new (external_X_ITE_X3D_Fields_default()).MFNode ()), ]), enumerable: true, }, }); const __default__ = Contour2D; ; /* harmony default export */ const NURBS_Contour2D = (external_X_ITE_X3D_Namespace_default().add ("Contour2D", __default__)); ;// ./src/x_ite/Components/NURBS/X3DNurbsControlCurveNode.js function X3DNurbsControlCurveNode (executionContext) { external_X_ITE_X3D_X3DNode_default().call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).X3DNurbsControlCurveNode); } Object .setPrototypeOf (X3DNurbsControlCurveNode .prototype, (external_X_ITE_X3D_X3DNode_default()).prototype); Object .defineProperties (X3DNurbsControlCurveNode, external_X_ITE_X3D_X3DNode_default().getStaticProperties ("X3DNurbsControlCurveNode", "NURBS", 1)); const X3DNurbsControlCurveNode_default_ = X3DNurbsControlCurveNode; ; /* harmony default export */ const NURBS_X3DNurbsControlCurveNode = (external_X_ITE_X3D_Namespace_default().add ("X3DNurbsControlCurveNode", X3DNurbsControlCurveNode_default_)); ;// external "__X_ITE_X3D__ .Vector3" const external_X_ITE_X3D_Vector3_namespaceObject = __X_ITE_X3D__ .Vector3; var external_X_ITE_X3D_Vector3_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Vector3_namespaceObject); ;// ./src/x_ite/Components/NURBS/ContourPolyline2D.js function ContourPolyline2D (executionContext) { NURBS_X3DNurbsControlCurveNode .call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).ContourPolyline2D); this .array = [ ]; } Object .assign (Object .setPrototypeOf (ContourPolyline2D .prototype, NURBS_X3DNurbsControlCurveNode .prototype), { tessellate (type, array = this .array) { const controlPoints = this ._controlPoint .getValue (), numControlPoints = this ._controlPoint .length * 2; switch (type) { case 0: { array .length = 0; for (let i = 0; i < numControlPoints; i += 2) array .push (controlPoints [i], controlPoints [i + 1]); break; } case 1: { array .length = 0; for (let i = 0; i < numControlPoints; i += 2) array .push (controlPoints [i], 0, controlPoints [i + 1]); break; } case 2: // Contour2D { for (let i = 0; i < numControlPoints; i += 2) array .push (new (external_X_ITE_X3D_Vector3_default()) (controlPoints [i], controlPoints [i + 1], 0)); break; } } return array; }, }); Object .defineProperties (ContourPolyline2D, { ... external_X_ITE_X3D_X3DNode_default().getStaticProperties ("ContourPolyline2D", "NURBS", 3, "children", "3.0"), fieldDefinitions: { value: new (external_X_ITE_X3D_FieldDefinitionArray_default()) ([ new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "metadata", new (external_X_ITE_X3D_Fields_default()).SFNode ()), new (external_X_ITE_X3D_X3DFieldDefinition_default()) ((external_X_ITE_X3D_X3DConstants_default()).inputOutput, "controlPoint", new (external_X_ITE_X3D_Fields_default()).MFVec2d ()), ]), enumerable: true, }, }); const ContourPolyline2D_default_ = ContourPolyline2D; ; /* harmony default export */ const NURBS_ContourPolyline2D = (external_X_ITE_X3D_Namespace_default().add ("ContourPolyline2D", ContourPolyline2D_default_)); ;// external "__X_ITE_X3D__ .X3DGeometryNode" const external_X_ITE_X3D_X3DGeometryNode_namespaceObject = __X_ITE_X3D__ .X3DGeometryNode; var external_X_ITE_X3D_X3DGeometryNode_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DGeometryNode_namespaceObject); ;// external "__X_ITE_X3D__ .Vector2" const external_X_ITE_X3D_Vector2_namespaceObject = __X_ITE_X3D__ .Vector2; var external_X_ITE_X3D_Vector2_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Vector2_namespaceObject); ;// external "__X_ITE_X3D__ .Vector4" const external_X_ITE_X3D_Vector4_namespaceObject = __X_ITE_X3D__ .Vector4; var external_X_ITE_X3D_Vector4_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_Vector4_namespaceObject); ;// ./src/x_ite/Browser/NURBS/NURBS.js const NURBS = { getTessellation (tessellation, dimension) { // This returns the number of tessellation faces, // the number of tessellation points will be one higher, // as required by the specification. if (tessellation > 0) return tessellation; if (tessellation < 0) return -tessellation * dimension; return 2 * dimension; }, getClosed2D (order, knot, weight, controlPoint) { const dimension = controlPoint .length, haveWeights = weight .length === dimension; // Check if first and last weights are unitary. if (haveWeights) { if (weight [0] !== weight [dimension - 1]) return false; } // Check if first and last point are coincident. if (!controlPoint [0] .equals (controlPoint [dimension - 1])) return false; return true; }, getClosed: (() => { const firstPoint = new (external_X_ITE_X3D_Vector3_default()) (), lastPoint = new (external_X_ITE_X3D_Vector3_default()) (); return function (order, knot, weight, controlPointNode) { const dimension = controlPointNode .getSize (), haveWeights = weight .length === dimension; // Check if first and last weights are unitary. if (haveWeights) { if (weight [0] !== weight [dimension - 1]) return false; } // Check if first and last point are coincident. if (!controlPointNode .get1Point (0, firstPoint) .equals (controlPointNode .get1Point (dimension - 1, lastPoint))) return false; return true; }; })(), getUClosed: (() => { const firstPoint = new (external_X_ITE_X3D_Vector3_default()) (), lastPoint = new (external_X_ITE_X3D_Vector3_default()) (); return function (uOrder, uDimension, vDimension, uKnot, weight, controlPointNode) { const haveWeights = weight .length === controlPointNode .getSize (); for (let v = 0; v < vDimension; ++ v) { const first = v * uDimension, last = v * uDimension + uDimension - 1; // Check if first and last weights are unitary. if (haveWeights) { if (weight [first] !== weight [last]) return false; } // Check if first and last point are coincident. if (!controlPointNode .get1Point (first, firstPoint) .equals (controlPointNode .get1Point (last, lastPoint))) return false; } return true; }; })(), getVClosed: (() => { const firstPoint = new (external_X_ITE_X3D_Vector3_default()) (), lastPoint = new (external_X_ITE_X3D_Vector3_default()) (); return function (vOrder, uDimension, vDimension, vKnot, weight, controlPointNode) { const haveWeights = weight .length === controlPointNode .getSize (); for (let u = 0; u < uDimension; ++ u) { const first = u, last = (vDimension - 1) * uDimension + u; // Check if first and last weights are unitary. if (haveWeights) { if (weight [first] !== weight [last]) return false; } // Check if first and last point are coincident. if (!controlPointNode .get1Point (first, firstPoint) .equals (controlPointNode .get1Point (last, lastPoint))) return false; } return true; }; })(), getKnots (result, closed, order, dimension, knot) { const length = dimension + order, knots = result ?? [ ]; for (let i = 0, l = knot .length; i < l; ++ i) knots [i] = knot [i]; knots .length = knot .length; // check the knot-vectors. If they are not according to standard // default uniform knot vectors will be generated. let generateUniform = true; if (knots .length === length) { generateUniform = false; let consecutiveKnots = 0; for (let i = 1; i < length; ++ i) { if (knots [i] === knots [i - 1]) ++ consecutiveKnots; else consecutiveKnots = 0; if (consecutiveKnots > order - 1) generateUniform = true; if (knots [i - 1] > knots [i]) generateUniform = true; } } if (generateUniform) { if (closed) { // Generate periodic uniform knots. for (let i = 0; i < length; ++ i) knots [i] = i; } else { // Generate pinned uniform knots. let i = 0, k = 1; for (; i < order; ++ i) knots [i] = 0; for (const l = length - order; i < l; ++ i, ++ k) knots [i] = k; for (; i < length; ++ i) knots [i] = k; } knots .length = length; // Scale knots. const max = knots .at (-1); for (let i = 0; i < length; ++ i) knots [i] /= max; } if (closed) { // Make knots periodic. const l = order - 1; for (let i = 1; i < l; ++ i) knots .push (knots .at (-1) + (knots [i] - knots [i - 1])); } return knots; }, getWeights (result, dimension, weight) { if (weight .length !== dimension) return undefined; const weights = result ?? [ ]; for (let i = 0; i < dimension; ++ i) { weights [i] = weight [i]; } weights .length = dimension; return weights; }, getUVWeights (result, uDimension, vDimension, weight) { const dimension = uDimension * vDimension; if (weight .length !== dimension) return undefined; const weights = result ?? [ ]; for (let u = 0, i = 0; u < uDimension; ++ u) { for (let v = 0; v < vDimension; ++ v, ++ i) { weights [i] = weight [i]; } } weights .length = dimension; return weights; }, getControlPoints2D (result, closed, order, weights, controlPoint) { const controlPoints = result ?? [ ], controlPointArray = controlPoint .getValue (), dimension = controlPoint .length, haveWeights = !! weights, Vector = haveWeights ? (external_X_ITE_X3D_Vector3_default()) : (external_X_ITE_X3D_Vector2_default()); if (controlPoints .haveWeights !== haveWeights) { controlPoints .haveWeights = haveWeights; controlPoints .length = 0; } for (let i = 0; i < dimension; ++ i) { const i2 = i * 2, cp = controlPoints [i] ??= new Vector (0, 0, 0); cp .set (controlPointArray [i2 + 0], controlPointArray [i2 + 1], haveWeights ? weights [i] : 0); } controlPoints .length = dimension; if (closed) { const length = order - 1; for (let i = 1; i < length; ++ i) controlPoints .push (controlPoints [i]); } return controlPoints; }, getControlPoints (result, closed, order, weights, controlPointNode) { const controlPoints = result ?? [ ], dimension = controlPointNode .getSize (), haveWeights = !! weights, Vector = haveWeights ? (external_X_ITE_X3D_Vector4_default()) : (external_X_ITE_X3D_Vector3_default()); if (controlPoints .haveWeights !== haveWeights) { controlPoints .haveWeights = haveWeights; controlPoints .length = 0; } for (let i = 0; i < dimension; ++ i) { const cp = controlPointNode .get1Point (i, controlPoints [i] ??= new Vector (0, 0, 0, 0)); if (haveWeights) cp .w = weights [i]; } controlPoints .length = dimension; if (closed) { const length = order - 1; for (let i = 1; i < length; ++ i) controlPoints .push (controlPoints [i]); } return controlPoints; }, getUVControlPoints (result, uClosed, vClosed, uOrder, vOrder, uDimension, vDimension, weights, controlPointNode) { const controlPoints = result ?? [ ], haveWeights = !! weights, Vector = haveWeights ? (external_X_ITE_X3D_Vector4_default()) : (external_X_ITE_X3D_Vector3_default()); if (controlPoints .haveWeights !== haveWeights) { controlPoints .haveWeights = haveWeights; controlPoints .length = 0; } for (let u = 0; u < uDimension; ++ u) { const cp = controlPoints [u] ??= [ ]; for (let v = 0; v < vDimension; ++ v) { const index = v * uDimension + u; controlPointNode .get1Point (index, cp [v] ??= new Vector (0, 0, 0, 0)); if (haveWeights) cp [v] .w = weights [index]; } cp .length = vDimension; if (vClosed) { const length = vOrder - 1; for (let i = 1; i < length; ++ i) cp .push (cp [i]); } } controlPoints .length = uDimension; if (uClosed) { const length = uOrder - 1; for (let i = 1; i < length; ++ i) controlPoints .push (controlPoints [i]); } return controlPoints; }, getTexControlPoints (result, uClosed, vClosed, uOrder, vOrder, uDimension, vDimension, controlPointNode) { const controlPoints = result ?? [ ]; for (let u = 0; u < uDimension; ++ u) { const cp = controlPoints [u] ??= [ ]; for (let v = 0; v < vDimension; ++ v) { const index = v * uDimension + u; controlPointNode .get1Point (index, cp [v] ??= new (external_X_ITE_X3D_Vector4_default()) ()); } cp .length = vDimension; if (vClosed) { const length = vOrder - 1; for (let i = 1; i < length; ++ i) cp .push (cp [i]); } } controlPoints .length = uDimension; if (uClosed) { const length = uOrder - 1; for (let i = 1; i < length; ++ i) controlPoints .push (controlPoints [i]); } return controlPoints; }, }; const NURBS_default_ = NURBS; ; /* harmony default export */ const NURBS_NURBS = (external_X_ITE_X3D_Namespace_default().add ("NURBS", NURBS_default_)); ;// ./src/x_ite/Components/NURBS/X3DParametricGeometryNode.js function X3DParametricGeometryNode (executionContext) { external_X_ITE_X3D_X3DGeometryNode_default().call (this, executionContext); this .addType ((external_X_ITE_X3D_X3DConstants_default()).X3DParametricGeometryNode); } Object .assign (Object .setPrototypeOf (X3DParametricGeometryNode .prototype, (external_X_ITE_X3D_X3DGeometryNode_default()).prototype), { getKnots (result, closed, order, dimension, knot) { return NURBS_NURBS .getKnots (result, closed, order, dimension, knot); }, }); Object .defineProperties (X3DParametricGeometryNode, external_X_ITE_X3D_X3DNode_default().getStaticProperties ("X3DParametricGeometryNode", "NURBS", 1)); const X3DParametricGeometryNode_default_ = X3DParametricGeometryNode; ; /* harmony default export */ const NURBS_X3DParametricGeometryNode = (external_X_ITE_X3D_Namespace_default().add ("X3DParametricGeometryNode", X3DParametricGeometryNode_default_)); ;// external "__X_ITE_X3D__ .X3DLineGeometryNode" const external_X_ITE_X3D_X3DLineGeometryNode_namespaceObject = __X_ITE_X3D__ .X3DLineGeometryNode; var external_X_ITE_X3D_X3DLineGeometryNode_default = /*#__PURE__*/__webpack_require__.n(external_X_ITE_X3D_X3DLineGeometryNode_namespaceObject); ;// ./src/lib/nurbs/src/utils/is-ndarray.js // Source: https://github.com/scijs/isndarray // By Kyle Robinson Young, MIT Licensed. const is_ndarray_default_ = function (arr) { if (!arr) return false; if (!arr .dtype) return false; const re = new RegExp ("function View[0-9]+d(:?" + arr .dtype + ")+"); return re .test (String (arr .constructor)); }; ; /* harmony default export */ const is_ndarray = (external_X_ITE_X3D_Namespace_default().add ("is-ndarray", is_ndarray_default_)); ;// ./src/lib/nurbs/src/utils/is-ndarray-like.js const is_ndarray_like_default_ = function (arr) { if (!arr) return false; return ( arr .data !== undefined && Array .isArray (arr .shape) && arr .offset !== undefined && arr .stride !== undefined ); }; ; /* harmony default export */ const is_ndarray_like = (external_X_ITE_X3D_Namespace_default().add ("is-ndarray-like", is_ndarray_like_default_)); ;// ./src/lib/nurbs/src/utils/is-array-like.js const is_array_like_default_ = function isArrayLike (data) { return Array .isArray (data) || ArrayBuffer .isView (data) || data .length !== undefined; }; ; /* harmony default export */ const is_array_like = (external_X_ITE_X3D_Namespace_default().add ("is-array-like", is_array_like_default_)); ;// ./src/lib/nurbs/src/utils/infer-type.js function inferType (x) { if (!x) return undefined; if (is_ndarray (x) || is_ndarray_like (x)) { if (x.dtype === "generic") return inferType .GENERIC_NDARRAY; return inferType .NDARRAY; } else { if (is_array_like (x)) { let ptr = x; while (is_array_like (ptr [0])) ptr = ptr [0]; if ("x" in ptr) return inferType .ARRAY_OF_OBJECTS; // if (isArrayLike(x[0])) { return inferType .ARRAY_OF_ARRAYS; // } // return inferType.PACKED; } throw new Error("Unhandled data type. Got type: " + (typeof x)); } } inferType .ARRAY_OF_OBJECTS = "Obj"; inferType .ARRAY_OF_ARRAYS = "Arr"; inferType .NDARRAY = "Nd"; inferType .GENERIC_NDARRAY = "GenNd"; inferType .PACKED = "PackArr"; const infer_type_default_ = inferType; ; /* harmony default export */ const infer_type = (external_X_ITE_X3D_Namespace_default().add ("infer-type", infer_type_default_)); ;// ./src/lib/nurbs/src/utils/cache-key.js function capitalize (str) { return str[0].toUpperCase() + str.slice(1); } const cache_key_default_ = function (nurbs, debug, checkBounds, pointType, weightType, knotType) { const degreeParts = []; let hasAnyKnots = false; for (let d = 0; d < nurbs.splineDimension; ++ d) { const hasKnots = is_array_like(nurbs.knots) && is_array_like(nurbs.knots[d]); if (hasKnots) hasAnyKnots = true; degreeParts.push( "Deg" + nurbs.degree[d] + (hasKnots ? "" : "Uniform") + capitalize(nurbs.boundary[d]) ); } const parts = [ [ hasAnyKnots ? "NU" : "", nurbs.weights ? "RBS" : "BS" ].join("") + nurbs.dimension + "D", degreeParts.join("_") ]; if (pointType) { parts.push(pointType + "Pts"); } if (weightType) { parts.push(weightType + "Wts"); } if (knotType) { parts.push(knotType + "Kts"); } if (debug) { parts.push("debug"); } if (checkBounds) { parts.push("chk"); } return parts.join("_"); }; ; /* harmony default export */ const cache_key = (external_X_ITE_X3D_Namespace_default().add ("cache-key", cache_key_default_)); ;// ./src/lib/nurbs/src/utils/variable.js const createVariable = function createVariable (name, nurbs) { return function (i, period) { if (i !== undefined && !Array.isArray(i)) i = [i]; const dimAccessors = []; for (let j = 0; j < i.length; ++ j) { dimAccessors.push(createVariable.sum(i[j])); } if (period) { for (let i = 0; i < dimAccessors.length; ++ i) { if (period[i] === undefined) continue; dimAccessors[i] = "(" + dimAccessors[i] + " + " + period[i] + ") % " + period[i]; } } return name + dimAccessors.join("_"); }; }; createVariable.sum = function (parts) { parts = Array.isArray(parts) ? parts : [parts]; parts = parts.filter(part => part !== undefined && part !== 0); if (parts.length === 0) parts.push(0); return parts.join(" + "); }; const variable_default_ = createVariable; ; /* harmony default export */ const variable = (external_X_ITE_X3D_Namespace_default().add ("variable", variable_default_)); ;// ./src/lib/nurbs/src/utils/create-accessors.js const properties = [".x", ".y", ".z", ".w"]; function wrapAccessor (callback) { return function (i, period) { if (i !== undefined && ! Array .isArray(i)) i = [i]; const dimAccessors = [ ]; for (let j = 0; j < i .length; ++ j) dimAccessors .push (variable .sum (i [j])); if (period) { for (let i = 0; i < dimAccessors .length; ++ i) { if (period [i] === undefined) continue; dimAccessors [i] = "(" + dimAccessors [i] + " + " + period [i] + ") % " + period [i]; } } return callback (dimAccessors); }; } function createAccessor (name, data) { if (! data) return undefined; switch (infer_type(data)) { case infer_type .ARRAY_OF_OBJECTS: { return wrapAccessor (accessors => { const e = accessors .pop (); return name + "[" + accessors .join ("][") + "]" + properties [e]; }); } case infer_type .ARRAY_OF_ARRAYS: { return wrapAccessor (accessors => { return name + "[" + accessors .join ("][") + "]"; }); } case infer_type .GENERIC_NDARRAY: { return wrapAccessor (accessors => { return name + ".get(" + accessors.join(",") + ")"; }); } case infer_type .NDARRAY: { return wrapAccessor (accessors => { const code = [name + "Offset"]; for (let i = 0; i < accessors.length; ++ i) { code.push(name + "Stride" + i + " * (" + accessors[i] + ")"); } return name + "[" + code.join(" + ") + "]"; }); } case infer_type.PACKED: default: return undefined; } } const create_accessors_default_ = function (nurbs) { const accessors = { }; let accessor = createAccessor ("x", nurbs .points); if (accessor) accessors .point = accessor; accessor = createAccessor ("w", nurbs .weights); if (accessor) accessors .weight = accessor; accessor = createAccessor ("k", nurbs .knots); if (accessor) accessors .knot = accessor; return accessors; }; ; /* harmony default export */ const create_accessors = (external_X_ITE_X3D_Namespace_default().add ("create-accessors", create_accessors_default_)); ;// ./src/lib/nurbs/src/numerical-derivative.js const args = []; const tmp = []; const numerical_derivative_default_ = function numericalDerivative (out, order, dimension) { if (order !== 1) { throw new Error("Numerical derivative not implemented for order n = " + order + "."); } const h = arguments[this.splineDimension + 3] === undefined ? 1e-4 : arguments[this.splineDimension + 3]; args.length = this.splineDimension; for (let i = 0; i < this.splineDimension; ++ i) { args[i + 1] = arguments[i + 3]; } const domain = this.domain; const k0 = domain[dimension][0]; const k1 = domain[dimension][1]; const t0 = args[dimension + 1]; let tm, tp; let dt = (k1 - k0) * h; if (this.boundary[dimension] === "closed") { const T = k1 - k0; tm = k0 + ((t0 - k0 - dt + T) % T); tp = k0 + ((t0 - k0 + dt + T) % T); dt *= 2; } else { tm = Math.min(k1, Math.max(k0, t0 - dt)); tp = Math.min(k1, Math.max(k0, t0 + dt)); dt = tp - tm; } args[dimension + 1] = tm; args[0] = tmp; this.evaluate.apply(null, args); args[dimension + 1] = tp; args[0] = out; this.evaluate.apply(null, args); for (let i = 0; i < this .dimension; ++ i) { out[i] = (out[i] - tmp[i]) / dt; } return out; }; ; /* harmony default export */ const numerical_derivative = (external_X_ITE_X3D_Namespace_default().add ("numerical-derivative", numerical_derivative_default_)); ;// ./src/lib/nurbs/src/utils/ndloop.js const ndloop_default_ = function ndloop (n, callback) { let m = 1, i = [ ]; for (let k = 0; k < n .length; ++ k) { m *= Array .isArray (n [k]) ? (n [k] [1] - n [k] [0]) : n [k]; i [k] = Array .isArray (n [k]) ? n [k] [0] : 0; } for (let ptr = 0; ptr < m; ++ ptr) { callback (i .slice ()); for (let k = n .length - 1; k >= 0; -- k) { if (i [k] === (Array .isArray (n [k]) ? n [k] [1] : n [k]) - 1) { i [k] = Array .isArray (n [k]) ? n [k] [0] : 0; } else { ++ i [k]; break; } } } }; ; /* harmony default export */ const ndloop = (external_X_ITE_X3D_Namespace_default().add ("ndloop", ndloop_default_)); ;// ./src/lib/nurbs/src/utils/accessor-preamble.js const accessor_preamble_default_ = function (nurbs, variableName, propertyName, data) { const code = [ ]; switch (infer_type (data)) { case infer_type .NDARRAY: { code .push (` var ${variableName} = ${propertyName}.data;`); code .push (` var ${variableName}Offset = ${propertyName}.offset;`); for (let i = 0; i < data .dimension; ++ i) { code .push (` var ${variableName}Stride${i} = ${propertyName}.stride[${i}];`); } break; } case infer_type .ARRAY_OF_OBJECTS: case infer_type .ARRAY_OF_ARRAYS: { code .push (` var ${variableName} = ${propertyName};`); break; } } return code .join ("\n"); }; ; /* harmony default export */ const accessor_preamble = (external_X_ITE_X3D_Namespace_default().add ("accessor-preamble", accessor_preamble_default_)); ;// ./src/lib/nurbs/src/utils/size-getter.js const size_getter_default_ = function (data, dataVariableName, dimension) { if (!data) { return "this.size[" + dimension + "]"; } else if (is_ndarray_like(data)) { return dataVariableName + ".shape[" + dimension + "]"; } else { let str = dataVariableName; for (let i = 0; i < dimension; ++ i) { str += "[0]"; } return str + ".length"; } }; ; /* harmony default export */ const size_getter = (external_X_ITE_X3D_Namespace_default().add ("size-getter", size_getter_default_)); ;// ./src/lib/nurbs/src/evaluator.js const evaluatorCache = {}; const codeCache = {}; const evaluator_default_ = function (cacheKey, nurbs, accessors, debug, checkBounds, isBasis, derivative) { const splineDimension = nurbs.splineDimension; const points = nurbs.points; const degree = nurbs.degree; const weights = nurbs.weights; const hasWeights = weights !== undefined; const knots = nurbs.knots; const spaceDimension = nurbs.dimension; const boundary = nurbs.boundary; if (derivative !== undefined && derivative !== null) { if (!Array.isArray(derivative)) { derivative = [derivative]; } let totalDerivativeOrder = 0; for (let i = 0; i < splineDimension; ++ i) { if (derivative[i] === undefined) derivative[i] = 0; totalDerivativeOrder += derivative[i]; } if (hasWeights && totalDerivativeOrder > 1) { throw new Error("Analytical derivative not implemented for rational b-splines with order n = " + totalDerivativeOrder + "."); } } if (isBasis) cacheKey = "Basis" + cacheKey; if (derivative) cacheKey = "Der" + derivative.join("_") + "_" + cacheKey; const cachedEvaluator = evaluatorCache[cacheKey]; const logger = debug ? (typeof debug === "function" ? debug : console.log) : null; if (cachedEvaluator) { if (debug) { logger(codeCache[cacheKey]); } return cachedEvaluator.bind(nurbs); } const code = []; const functionName = "evaluate" + cacheKey; let pointAccessor = accessors.point; if (isBasis) { pointAccessor = function (src, period) { const terms = []; for (let i = 0; i < src.length; ++ i) { const terms2 = []; let accessor = src[i]; for (let j = 0; j < accessor.length; ++ j) { if (accessor[j] !== 0) terms2.push(accessor[j]); } accessor = terms2.join(" + "); if (period[i]) { accessor = "(" + accessor + " + " + period[i] + ") % " + period[i]; } terms.push(accessor + " === " + indexVar(i)); } return "((" + terms.join(" && ") + ") ? 1 : 0)"; }; } const weightAccessor = accessors.weight; const knotAccessor = accessors.knot; const knotVar = variable("k"); const pointVar = variable("x"); const weightVar = variable("w"); const indexVar = variable("i"); const tVar = variable("t"); const domainVar = debug ? "domain" : "d"; const sizeVar = variable(debug ? "size" : "s"); const knotIndex = variable(debug ? "knotIndex" : "j"); let allDimensionUniform = true; for (let d = 0; d < splineDimension; ++ d) { if (is_array_like(knots) && is_array_like(knots[d])) { allDimensionUniform = false; } } // Just to indent properly and save lots of typing function line (str) { code.push(" " + (str || "")); } function debugLine (str) { if (debug) line(str); } // function clog (str) { // if (debug) code.push("console.log(\"" + str + " =\", " + str + ");"); // } const indexArgs = isBasis ? [] : null; const parameterArgs = []; for (let i = 0; i < splineDimension; ++ i) { if (isBasis) { indexArgs.push(indexVar([i])); } parameterArgs.push(tVar([i])); } code.push("function " + functionName + " (" + (isBasis ? "" : "out, ") + parameterArgs.join(", ") + (isBasis ? ", " + indexArgs.join(", ") : "") + ") {"); line("var h, m, a, b;"); if (checkBounds) { line("var " + domainVar + " = this.domain;"); line("for (var i = 0; i < this.splineDimension; ++ i) {"); line(" a = arguments[i + 1];"); line(" if (a < " + domainVar + "[i][0] || a > " + domainVar + "[i][1] || a === undefined || isNaN(a)) {"); line(" throw new Error(\"Invalid Spline parameter in dimension \"+i+\". Valid domain is [\"+" + domainVar + "[i][0]+\", \"+" + domainVar + "[i][1]+\"]. but got t\"+i+\" = \"+arguments[i + 1]+\".\");"); line(" }"); line("}"); } for (let d = 0; d < splineDimension; ++ d) { line("var " + sizeVar(d) + " = " + size_getter(points, "this.points", d) + ";"); } code.push(accessor_preamble(nurbs, "x", "this.points", points)); if (hasWeights) { code.push(accessor_preamble(nurbs, "w", "this.weights", weights)); } if (!allDimensionUniform) { code.push(accessor_preamble(nurbs, "k", "this.knots", knots)); } function ternary (cond, a, b) { return "(" + cond + ") ? (" + a + ") : (" + b + ")"; } const hasKnots = []; for (let d = 0; d < splineDimension; ++ d) { switch (infer_type(knots)) { case infer_type.NDARRAY: hasKnots[d] = true; break; case infer_type.ARRAY_OF_ARRAYS: hasKnots[d] = is_array_like(knots[d]); break; } } for (let d = 0; d < splineDimension; ++ d) { if (hasKnots[d]) { // // LOCATE KNOTS // debugLine("\n // Bisect to locate the knot interval in dimension " + d + "\n"); line("var " + knotIndex(d) + " = 0;"); line("h = " + sizeVar(d) + ";"); line("while(h > " + knotIndex(d) + " + 1) {"); line(" m = 0.5 * (h + " + knotIndex(d) + ") | 0;"); line(" if (" + knotAccessor([d, "m"]) + " > " + tVar(d) + ") h = m;"); line(" else " + knotIndex(d) + " = m;"); line("}"); debugLine("\n // Fetch knots for dimension " + d + "\n"); for (let i = -degree[d] + 1; i <= degree[d]; ++ i) { if (boundary[d] === "closed") { if (i < 0) { // line("var " + knotVar([d, i + degree[d] - 1]) + " = " + knotAccessor([d, [knotIndex(d), i]]) + ";"); // EDIT THIS SECTION line("var " + knotVar([d, i + degree[d] - 1]) + " = " + ternary( knotIndex(d) + " < " + (-i), knotAccessor([d, 0]) + " + " + knotAccessor([d, [sizeVar(d), knotIndex(d), i]]) + " - " + knotAccessor([d, [sizeVar(d)]]), knotAccessor([d, [knotIndex(d), i]]) ) + ";"); } else if (i > 0) { line("var " + knotVar([d, i + degree[d] - 1]) + " = " + ternary( knotIndex(d) + " + " + i + " > " + sizeVar(d), // knotAccessor([d, sizeVar(d)]) + " + " + knotAccessor([d, i]) + " - " + knotAccessor([d, 0]), knotAccessor([d, sizeVar(d)]) + " + " + knotAccessor([d, i + " + " + knotIndex(d) + " - " + sizeVar(d)]) + " - " + knotAccessor([d, 0]), knotAccessor([d, [knotIndex(d), i]]) ) + ";"); } else { line("var " + knotVar([d, i + degree[d] - 1]) + " = " + knotAccessor([d, [knotIndex(d), i]]) + ";"); } } else { line("var " + knotVar([d, i + degree[d] - 1]) + " = " + knotAccessor([d, [knotIndex(d), i]]) + ";"); } } } else { // // UNIFORM B-SPLINE // debugLine("\n // Directly compute knot interval for dimension " + d + "\n"); if (boundary[d] === "closed") { line(knotIndex(d) + " = (" + tVar(d) + " | 0) % " + sizeVar(d) + ";"); } else { line(knotIndex(d) + " = (" + tVar(d) + " | 0);"); line("if (" + knotIndex(d) + " < " + degree[d] + ") " + knotIndex(d) + " = " + degree[d] + ";"); line("if (" + knotIndex(d) + " > " + sizeVar(d) + " - 1) " + knotIndex(d) + " = " + sizeVar(d) + " - 1;"); } debugLine("\n // Compute and clamp knots for dimension " + d + "\n"); for (let i = -degree[d] + 1; i <= degree[d]; ++ i) { const kvar = knotVar([d, i + degree[d] - 1]); line("var " + kvar + " = " + knotIndex(d) + " + " + (i) + ";"); } if (boundary[d] === "clamped") { for (let i = -degree[d] + 1; i <= degree[d]; ++ i) { const kvar = knotVar([d, i + degree[d] - 1]); if (i < 0) { line("if (" + kvar + " < " + degree[d] + ") " + kvar + " = " + degree[d] + ";"); } if (i > 0) { line("if (" + kvar + " > " + sizeVar(d) + ") " + kvar + " = " + sizeVar(d) + ";"); } } } if (boundary[d] === "closed") { debugLine("\n // Wrap the B-Spline parameter for closed boundary"); line(tVar(d) + " %= " + sizeVar(d) + ";"); } } } const n = [ ]; for (let d = 0; d < splineDimension; ++ d) { n[d] = degree[d] + 1; } if (hasWeights) { debugLine("\n // Fetch weights\n"); ndloop(n, function (dst) { const readIdx = []; const period = []; for (let d = 0; d < splineDimension; ++ d) { readIdx[d] = [knotIndex(d), dst[d] - degree[d]]; if (boundary[d] === "closed" && dst[d] - degree[d] < 0) period[d] = sizeVar(d); } line("var " + weightVar(dst) + " = " + weightAccessor(readIdx, period) + ";"); }); } if (debug) { if (hasWeights) { line("\n // Fetch points and project into homogeneous (weighted) coordinates\n"); } else { line("\n // Fetch points\n"); } } ndloop(n, function (dst) { const readIdx = []; const period = []; for (let d = 0; d < splineDimension; ++ d) { readIdx[d] = [knotIndex(d), dst[d] - degree[d]]; if (boundary[d] === "closed" && dst[d] - degree[d] < 0) period[d] = sizeVar(d); } if (isBasis) { if (hasWeights) { line("var " + pointVar(dst) + " = " + pointAccessor(readIdx, period) + " * " + weightVar(dst) + ";"); } else { line("var " + pointVar(dst) + " = " + pointAccessor(readIdx, period) + ";"); } } else { for (let d = 0; d < spaceDimension; ++ d) { const dstWithDim = dst.concat(d); readIdx[splineDimension] = d; if (hasWeights) { line("var " + pointVar(dstWithDim) + " = " + pointAccessor(readIdx, period) + " * " + weightVar(dst) + ";"); } else { line("var " + pointVar(dstWithDim) + " = " + pointAccessor(readIdx, period) + ";"); } } } }); debugLine("\n"); debugLine("// Perform De Boor\"s algorithm"); for (let d = n.length - 1; d >= 0; -- d) { n[d] = [degree[d], degree[d] + 1]; for (let i = 0; i < degree[d]; ++ i) { debugLine("\n // Degree " + degree[d] + " evaluation in dimension " + d + ", step " + (i + 1) + "\n"); for (let j = degree[d]; j > i; -- j) { const isDerivative = derivative && (degree[d] - i - derivative[d] <= 0); if (isDerivative) { line("m = 1 / (" + knotVar([d, j - i + degree[d] - 1]) + " - " + knotVar([d, j - 1]) + ");"); if (hasWeights) { line("a = (" + tVar(d) + " - " + knotVar([d, j - 1]) + ") * m;"); line("b = 1 - a;"); } } else { line("a = (" + tVar(d) + " - " + knotVar([d, j - 1]) + ") / (" + knotVar([d, j - i + degree[d] - 1]) + " - " + knotVar([d, j - 1]) + ");"); line("b = 1 - a;"); } if (hasWeights) { ndloop(n, function (ii) { const ij = ii.slice(); const ij1 = ii.slice(); ij[d] = j; ij1[d] = j - 1; if (isDerivative && hasWeights) line("h = " + weightVar(ij) + ";"); line(weightVar(ij) + " = b * " + weightVar(ij1) + " + a * " + weightVar(ij) + ";"); }); } ndloop(n, function (ii) { let weightFactor, pt1, pt2; const ij = ii.slice(); const ij1 = ii.slice(); // Replace the dimension being interpolated with the interpolation indices ij[d] = j; ij1[d] = j - 1; // Create a version to which we can append the dimension when we loop over spatial dimension if (isDerivative) { const derivCoeff = i + 1; if (isBasis) { weightFactor = hasWeights ? "h * " + weightVar(ij1) + " / " + weightVar(ij) + " * " : ""; pt1 = pointVar(ij) + (hasWeights ? " / h" : ""); pt2 = pointVar(ij1) + (hasWeights ? " / " + weightVar(ij1) : ""); line(pointVar(ij) + " = " + derivCoeff + " * " + weightFactor + "(" + pt1 + " - " + pt2 + ") * m;"); } else { const ijWithDimension = ij.slice(); const ij1WithDimension = ij1.slice(); for (let m = 0; m < spaceDimension; ++ m) { ijWithDimension[splineDimension] = ij1WithDimension[splineDimension] = m; weightFactor = hasWeights ? "h * " + weightVar(ij1) + " / " + weightVar(ij) + " * " : ""; pt1 = pointVar(ijWithDimension) + (hasWeights ? " / h" : ""); pt2 = pointVar(ij1WithDimension) + (hasWeights ? " / " + weightVar(ij1) : ""); line(pointVar(ijWithDimension) + " = " + derivCoeff + " * " + weightFactor + "(" + pt1 + " - " + pt2 + ") * m;"); } } } else { if (isBasis) { line(pointVar(ij) + " = b * " + pointVar(ij1) + " + a * " + pointVar(ij) + ";"); } else { for (let m = 0; m < spaceDimension; ++ m) { ij[splineDimension] = ij1[splineDimension] = m; line(pointVar(ij) + " = b * " + pointVar(ij1) + " + a * " + pointVar(ij) + ";"); } } } }); debugLine("\n"); } } } if (debug) { if (hasWeights) { line("\n // Project back from homogeneous coordinates and return final output\n"); } else { line("\n // Return final output\n"); } } if (isBasis) { if (hasWeights) { line("return " + pointVar(degree) + " / " + weightVar(degree) + ";"); } else { line("return " + pointVar(degree) + ";"); } } else { for (let d = 0; d < spaceDimension; ++ d) { if (hasWeights) { line("out[" + d + "] = " + pointVar(degree.concat([d])) + " / " + weightVar(degree) + ";"); } else { line("out[" + d + "] = " + pointVar(degree.concat([d])) + ";"); } } } if (!isBasis) { line("return out;"); } code.push("}"); if (debug) { const codeStr = code.join("\n"); logger(codeStr); codeCache[cacheKey] = codeStr; } const evaluator = new Function([code.join("\n"), "; return ", functionName].join(""))(); evaluatorCache[cacheKey] = evaluator; return evaluator.bind(nurbs); }; ; /* harmony default export */ const evaluator = (external_X_ITE_X3D_Namespace_default().add ("evaluator", evaluator_default_)); ;// ./src/lib/nurbs/src/transform.js const transformerCache = {}; const transform_default_ = fu