k-l-lambda's picture
feat: add Python ML services (CPU mode) with model download
2b7aae2
import { Curve } from './Curve.js';
import * as Curves from '../curves/Curves.js';
/**************************************************************
* Curved Path - a curve path is simply a array of connected
* curves, but retains the api of a curve
**************************************************************/
class CurvePath extends Curve {
constructor() {
super();
this.type = 'CurvePath';
this.curves = [];
this.autoClose = false; // Automatically closes the path
}
add(curve) {
this.curves.push(curve);
}
closePath() {
// Add a line curve if start and end of lines are not connected
const startPoint = this.curves[0].getPoint(0);
const endPoint = this.curves[this.curves.length - 1].getPoint(1);
if (!startPoint.equals(endPoint)) {
this.curves.push(new Curves['LineCurve'](endPoint, startPoint));
}
}
// To get accurate point with reference to
// entire path distance at time t,
// following has to be done:
// 1. Length of each sub path have to be known
// 2. Locate and identify type of curve
// 3. Get t for the curve
// 4. Return curve.getPointAt(t')
getPoint(t, optionalTarget) {
const d = t * this.getLength();
const curveLengths = this.getCurveLengths();
let i = 0;
// To think about boundaries points.
while (i < curveLengths.length) {
if (curveLengths[i] >= d) {
const diff = curveLengths[i] - d;
const curve = this.curves[i];
const segmentLength = curve.getLength();
const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
return curve.getPointAt(u, optionalTarget);
}
i++;
}
return null;
// loop where sum != 0, sum > d , sum+1 <d
}
// We cannot use the default THREE.Curve getPoint() with getLength() because in
// THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
// getPoint() depends on getLength
getLength() {
const lens = this.getCurveLengths();
return lens[lens.length - 1];
}
// cacheLengths must be recalculated.
updateArcLengths() {
this.needsUpdate = true;
this.cacheLengths = null;
this.getCurveLengths();
}
// Compute lengths and cache them
// We cannot overwrite getLengths() because UtoT mapping uses it.
getCurveLengths() {
// We use cache values if curves and cache array are same length
if (this.cacheLengths && this.cacheLengths.length === this.curves.length) {
return this.cacheLengths;
}
// Get length of sub-curve
// Push sums into cached array
const lengths = [];
let sums = 0;
for (let i = 0, l = this.curves.length; i < l; i++) {
sums += this.curves[i].getLength();
lengths.push(sums);
}
this.cacheLengths = lengths;
return lengths;
}
getSpacedPoints(divisions = 40) {
const points = [];
for (let i = 0; i <= divisions; i++) {
points.push(this.getPoint(i / divisions));
}
if (this.autoClose) {
points.push(points[0]);
}
return points;
}
getPoints(divisions = 12) {
const points = [];
let last;
for (let i = 0, curves = this.curves; i < curves.length; i++) {
const curve = curves[i];
const resolution =
curve && curve.isEllipseCurve
? divisions * 2
: curve && (curve.isLineCurve || curve.isLineCurve3)
? 1
: curve && curve.isSplineCurve
? divisions * curve.points.length
: divisions;
const pts = curve.getPoints(resolution);
for (let j = 0; j < pts.length; j++) {
const point = pts[j];
if (last && last.equals(point)) continue; // ensures no consecutive points are duplicates
points.push(point);
last = point;
}
}
if (this.autoClose && points.length > 1 && !points[points.length - 1].equals(points[0])) {
points.push(points[0]);
}
return points;
}
copy(source) {
super.copy(source);
this.curves = [];
for (let i = 0, l = source.curves.length; i < l; i++) {
const curve = source.curves[i];
this.curves.push(curve.clone());
}
this.autoClose = source.autoClose;
return this;
}
toJSON() {
const data = super.toJSON();
data.autoClose = this.autoClose;
data.curves = [];
for (let i = 0, l = this.curves.length; i < l; i++) {
const curve = this.curves[i];
data.curves.push(curve.toJSON());
}
return data;
}
fromJSON(json) {
super.fromJSON(json);
this.autoClose = json.autoClose;
this.curves = [];
for (let i = 0, l = json.curves.length; i < l; i++) {
const curve = json.curves[i];
this.curves.push(new Curves[curve.type]().fromJSON(curve));
}
return this;
}
}
export { CurvePath };