1 | |
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 | var MakerJs;
|
43 | (function (MakerJs) {
|
44 | |
45 |
|
46 |
|
47 | MakerJs.version = 'debug';
|
48 | |
49 |
|
50 |
|
51 | MakerJs.environmentTypes = {
|
52 | BrowserUI: 'browser',
|
53 | NodeJs: 'node',
|
54 | WebWorker: 'worker',
|
55 | Unknown: 'unknown'
|
56 | };
|
57 | |
58 |
|
59 |
|
60 | function tryEval(name) {
|
61 | try {
|
62 | var value = eval(name);
|
63 | return value;
|
64 | }
|
65 | catch (e) { }
|
66 | return;
|
67 | }
|
68 | |
69 |
|
70 |
|
71 | function detectEnvironment() {
|
72 | if (tryEval('WorkerGlobalScope') && tryEval('self')) {
|
73 | return MakerJs.environmentTypes.WebWorker;
|
74 | }
|
75 | if (tryEval('window') && tryEval('document')) {
|
76 | return MakerJs.environmentTypes.BrowserUI;
|
77 | }
|
78 |
|
79 | if (tryEval('global') && tryEval('process')) {
|
80 | return MakerJs.environmentTypes.NodeJs;
|
81 | }
|
82 | return MakerJs.environmentTypes.Unknown;
|
83 | }
|
84 | |
85 |
|
86 |
|
87 | MakerJs.environment = detectEnvironment();
|
88 |
|
89 | |
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 | MakerJs.unitType = {
|
96 | Centimeter: 'cm',
|
97 | Foot: 'foot',
|
98 | Inch: 'inch',
|
99 | Meter: 'm',
|
100 | Millimeter: 'mm'
|
101 | };
|
102 | |
103 |
|
104 |
|
105 | function split(s, char) {
|
106 | var p = s.indexOf(char);
|
107 | if (p < 0) {
|
108 | return [s];
|
109 | }
|
110 | else if (p > 0) {
|
111 | return [s.substr(0, p), s.substr(p + 1)];
|
112 | }
|
113 | else {
|
114 | return ['', s];
|
115 | }
|
116 | }
|
117 | |
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 | function splitDecimal(n) {
|
129 | var s = n.toString();
|
130 | if (s.indexOf('e') > 0) {
|
131 |
|
132 | s = n.toFixed(20).match(/.*[^(0+$)]/)[0];
|
133 | }
|
134 | return split(s, '.');
|
135 | }
|
136 | MakerJs.splitDecimal = splitDecimal;
|
137 | |
138 |
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | function round(n, accuracy) {
|
150 | if (accuracy === void 0) { accuracy = .0000001; }
|
151 |
|
152 | if (n % 1 === 0)
|
153 | return n;
|
154 | var exp = 1 - String(Math.ceil(1 / accuracy)).length;
|
155 |
|
156 |
|
157 | if (typeof exp === 'undefined' || +exp === 0) {
|
158 | return Math.round(n);
|
159 | }
|
160 | n = +n;
|
161 | exp = +exp;
|
162 |
|
163 | if (isNaN(n) || !(typeof exp === 'number' && exp % 1 === 0)) {
|
164 | return NaN;
|
165 | }
|
166 |
|
167 | if (n < 0) {
|
168 | return -round(-n, accuracy);
|
169 | }
|
170 |
|
171 | var a = split(n.toString(), 'e');
|
172 | n = Math.round(+(a[0] + 'e' + (a[1] ? (+a[1] - exp) : -exp)));
|
173 |
|
174 | a = split(n.toString(), 'e');
|
175 | return +(a[0] + 'e' + (a[1] ? (+a[1] + exp) : exp));
|
176 | }
|
177 | MakerJs.round = round;
|
178 | |
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | function createRouteKey(route) {
|
185 | var converted = [];
|
186 | for (var i = 0; i < route.length; i++) {
|
187 | var element = route[i];
|
188 | var newElement;
|
189 | if (i % 2 === 0) {
|
190 | newElement = (i > 0 ? '.' : '') + element;
|
191 | }
|
192 | else {
|
193 | newElement = JSON.stringify([element]);
|
194 | }
|
195 | converted.push(newElement);
|
196 | }
|
197 | return converted.join('');
|
198 | }
|
199 | MakerJs.createRouteKey = createRouteKey;
|
200 | |
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 | function travel(modelContext, route) {
|
208 | if (!modelContext || !route)
|
209 | return null;
|
210 | var routeArray;
|
211 | if (Array.isArray(route)) {
|
212 | routeArray = route;
|
213 | }
|
214 | else {
|
215 | routeArray = JSON.parse(route);
|
216 | }
|
217 | var props = routeArray.slice();
|
218 | var ref = modelContext;
|
219 | var origin = modelContext.origin || [0, 0];
|
220 | while (props.length) {
|
221 | var prop = props.shift();
|
222 | ref = ref[prop];
|
223 | if (!ref)
|
224 | return null;
|
225 | if (ref.origin && props.length) {
|
226 | origin = MakerJs.point.add(origin, ref.origin);
|
227 | }
|
228 | }
|
229 | return {
|
230 | result: ref,
|
231 | offset: origin
|
232 | };
|
233 | }
|
234 | MakerJs.travel = travel;
|
235 | |
236 |
|
237 |
|
238 | var clone = require('clone');
|
239 | |
240 |
|
241 |
|
242 |
|
243 |
|
244 |
|
245 | function cloneObject(objectToClone) {
|
246 | return clone(objectToClone);
|
247 | }
|
248 | MakerJs.cloneObject = cloneObject;
|
249 | |
250 |
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 | function extendObject(target, other) {
|
262 | if (target && other) {
|
263 | for (var key in other) {
|
264 | if (typeof other[key] !== 'undefined') {
|
265 | target[key] = other[key];
|
266 | }
|
267 | }
|
268 | }
|
269 | return target;
|
270 | }
|
271 | MakerJs.extendObject = extendObject;
|
272 | |
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 | function isFunction(value) {
|
279 | return typeof value === 'function';
|
280 | }
|
281 | MakerJs.isFunction = isFunction;
|
282 | |
283 |
|
284 |
|
285 |
|
286 |
|
287 |
|
288 | function isNumber(value) {
|
289 | return typeof value === 'number';
|
290 | }
|
291 | MakerJs.isNumber = isNumber;
|
292 | |
293 |
|
294 |
|
295 |
|
296 |
|
297 |
|
298 | function isObject(value) {
|
299 | return typeof value === 'object';
|
300 | }
|
301 | MakerJs.isObject = isObject;
|
302 |
|
303 | |
304 |
|
305 |
|
306 |
|
307 |
|
308 | function isPoint(item) {
|
309 | return item && Array.isArray(item) && item.length == 2 && isNumber(item[0]) && isNumber(item[1]);
|
310 | }
|
311 | MakerJs.isPoint = isPoint;
|
312 | |
313 |
|
314 |
|
315 |
|
316 |
|
317 | function isPath(item) {
|
318 | return item && item.type && isPoint(item.origin);
|
319 | }
|
320 | MakerJs.isPath = isPath;
|
321 | |
322 |
|
323 |
|
324 |
|
325 |
|
326 | function isPathLine(item) {
|
327 | return isPath(item) && item.type == MakerJs.pathType.Line && isPoint(item.end);
|
328 | }
|
329 | MakerJs.isPathLine = isPathLine;
|
330 | |
331 |
|
332 |
|
333 |
|
334 |
|
335 | function isPathCircle(item) {
|
336 | return isPath(item) && item.type == MakerJs.pathType.Circle && isNumber(item.radius);
|
337 | }
|
338 | MakerJs.isPathCircle = isPathCircle;
|
339 | |
340 |
|
341 |
|
342 |
|
343 |
|
344 | function isPathArc(item) {
|
345 | return isPath(item) && item.type == MakerJs.pathType.Arc && isNumber(item.radius) && isNumber(item.startAngle) && isNumber(item.endAngle);
|
346 | }
|
347 | MakerJs.isPathArc = isPathArc;
|
348 | |
349 |
|
350 |
|
351 |
|
352 |
|
353 | function isPathArcInBezierCurve(item) {
|
354 | return isPathArc(item) && isObject(item.bezierData) && isNumber(item.bezierData.startT) && isNumber(item.bezierData.endT);
|
355 | }
|
356 | MakerJs.isPathArcInBezierCurve = isPathArcInBezierCurve;
|
357 | |
358 |
|
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 |
|
366 | MakerJs.pathType = {
|
367 | Line: "line",
|
368 | Circle: "circle",
|
369 | Arc: "arc",
|
370 | BezierSeed: "bezier-seed"
|
371 | };
|
372 | |
373 |
|
374 |
|
375 | function isModel(item) {
|
376 | return item && (item.paths || item.models);
|
377 | }
|
378 | MakerJs.isModel = isModel;
|
379 | |
380 |
|
381 |
|
382 |
|
383 |
|
384 | function isChain(item) {
|
385 | var x = item;
|
386 | return x && x.links && Array.isArray(x.links) && isNumber(x.pathLength);
|
387 | }
|
388 | MakerJs.isChain = isChain;
|
389 | |
390 |
|
391 |
|
392 | var Cascade = (function () {
|
393 | function Cascade(_module, $initial) {
|
394 | this._module = _module;
|
395 | this.$initial = $initial;
|
396 | for (var methodName in this._module)
|
397 | this._shadow(methodName);
|
398 | this.$result = $initial;
|
399 | }
|
400 | Cascade.prototype._shadow = function (methodName) {
|
401 | var _this = this;
|
402 | this[methodName] = function () {
|
403 | return _this._apply(_this._module[methodName], arguments);
|
404 | };
|
405 | };
|
406 | Cascade.prototype._apply = function (fn, carriedArguments) {
|
407 | var args = [].slice.call(carriedArguments);
|
408 | args.unshift(this.$result);
|
409 | this.$result = fn.apply(undefined, args);
|
410 | return this;
|
411 | };
|
412 | Cascade.prototype.$reset = function () {
|
413 | this.$result = this.$initial;
|
414 | return this;
|
415 | };
|
416 | return Cascade;
|
417 | }());
|
418 | function $(context) {
|
419 | if (isModel(context)) {
|
420 | return new Cascade(MakerJs.model, context);
|
421 | }
|
422 | else if (isPath(context)) {
|
423 | return new Cascade(MakerJs.path, context);
|
424 | }
|
425 | else if (isPoint(context)) {
|
426 | return new Cascade(MakerJs.point, context);
|
427 | }
|
428 | }
|
429 | MakerJs.$ = $;
|
430 | })(MakerJs || (MakerJs = {}));
|
431 |
|
432 | module.exports = MakerJs;
|
433 |
|
434 | var MakerJs;
|
435 | (function (MakerJs) {
|
436 | var angle;
|
437 | (function (angle) {
|
438 | |
439 |
|
440 |
|
441 | function getFractionalPart(n) {
|
442 | return MakerJs.splitDecimal(n)[1];
|
443 | }
|
444 | |
445 |
|
446 |
|
447 | function setFractionalPart(n, fractionalPart) {
|
448 | if (fractionalPart) {
|
449 | return +(MakerJs.splitDecimal(n)[0] + '.' + fractionalPart);
|
450 | }
|
451 | else {
|
452 | return n;
|
453 | }
|
454 | }
|
455 | |
456 |
|
457 |
|
458 | function copyFractionalPart(src, dest) {
|
459 | if ((src < 0 && dest < 0) || (src > 0 && dest > 0)) {
|
460 | return setFractionalPart(dest, getFractionalPart(src));
|
461 | }
|
462 | return dest;
|
463 | }
|
464 | |
465 |
|
466 |
|
467 |
|
468 |
|
469 |
|
470 | function noRevolutions(angleInDegrees) {
|
471 | var revolutions = Math.floor(angleInDegrees / 360);
|
472 | if (revolutions === 0)
|
473 | return angleInDegrees;
|
474 | var a = angleInDegrees - (360 * revolutions);
|
475 | return copyFractionalPart(angleInDegrees, a);
|
476 | }
|
477 | angle.noRevolutions = noRevolutions;
|
478 | |
479 |
|
480 |
|
481 |
|
482 |
|
483 |
|
484 | function toRadians(angleInDegrees) {
|
485 | return noRevolutions(angleInDegrees) * Math.PI / 180.0;
|
486 | }
|
487 | angle.toRadians = toRadians;
|
488 | |
489 |
|
490 |
|
491 |
|
492 |
|
493 |
|
494 | function toDegrees(angleInRadians) {
|
495 | return angleInRadians * 180.0 / Math.PI;
|
496 | }
|
497 | angle.toDegrees = toDegrees;
|
498 | |
499 |
|
500 |
|
501 |
|
502 |
|
503 |
|
504 | function ofArcEnd(arc) {
|
505 |
|
506 |
|
507 | if (arc.endAngle < arc.startAngle) {
|
508 | var revolutions = Math.ceil((arc.startAngle - arc.endAngle) / 360);
|
509 | var a = revolutions * 360 + arc.endAngle;
|
510 | return copyFractionalPart(arc.endAngle, a);
|
511 | }
|
512 | return arc.endAngle;
|
513 | }
|
514 | angle.ofArcEnd = ofArcEnd;
|
515 | |
516 |
|
517 |
|
518 |
|
519 |
|
520 |
|
521 |
|
522 | function ofArcMiddle(arc, ratio) {
|
523 | if (ratio === void 0) { ratio = .5; }
|
524 | return arc.startAngle + ofArcSpan(arc) * ratio;
|
525 | }
|
526 | angle.ofArcMiddle = ofArcMiddle;
|
527 | |
528 |
|
529 |
|
530 |
|
531 |
|
532 |
|
533 | function ofArcSpan(arc) {
|
534 | var endAngle = angle.ofArcEnd(arc);
|
535 | var a = endAngle - arc.startAngle;
|
536 | if (MakerJs.round(a) > 360) {
|
537 | return noRevolutions(a);
|
538 | }
|
539 | else {
|
540 | return a;
|
541 | }
|
542 | }
|
543 | angle.ofArcSpan = ofArcSpan;
|
544 | |
545 |
|
546 |
|
547 |
|
548 |
|
549 |
|
550 | function ofLineInDegrees(line) {
|
551 | return noRevolutions(toDegrees(ofPointInRadians(line.origin, line.end)));
|
552 | }
|
553 | angle.ofLineInDegrees = ofLineInDegrees;
|
554 | |
555 |
|
556 |
|
557 |
|
558 |
|
559 |
|
560 |
|
561 | function ofPointInDegrees(origin, pointToFindAngle) {
|
562 | return toDegrees(ofPointInRadians(origin, pointToFindAngle));
|
563 | }
|
564 | angle.ofPointInDegrees = ofPointInDegrees;
|
565 | |
566 |
|
567 |
|
568 |
|
569 |
|
570 |
|
571 |
|
572 | function ofPointInRadians(origin, pointToFindAngle) {
|
573 | var d = MakerJs.point.subtract(pointToFindAngle, origin);
|
574 | var x = d[0];
|
575 | var y = d[1];
|
576 | return Math.atan2(-y, -x) + Math.PI;
|
577 | }
|
578 | angle.ofPointInRadians = ofPointInRadians;
|
579 | |
580 |
|
581 |
|
582 |
|
583 |
|
584 |
|
585 |
|
586 |
|
587 | function mirror(angleInDegrees, mirrorX, mirrorY) {
|
588 | if (mirrorY) {
|
589 | angleInDegrees = 360 - angleInDegrees;
|
590 | }
|
591 | if (mirrorX) {
|
592 | angleInDegrees = (angleInDegrees < 180 ? 180 : 540) - angleInDegrees;
|
593 | }
|
594 | return angleInDegrees;
|
595 | }
|
596 | angle.mirror = mirror;
|
597 | |
598 |
|
599 |
|
600 | var linkLineMap = {};
|
601 | linkLineMap[MakerJs.pathType.Arc] = function (arc, first, reversed) {
|
602 | var fromEnd = first != reversed;
|
603 | var angleToRotate = fromEnd ? arc.endAngle - 90 : arc.startAngle + 90;
|
604 | var origin = MakerJs.point.fromArc(arc)[fromEnd ? 1 : 0];
|
605 | var end = MakerJs.point.rotate(MakerJs.point.add(origin, [arc.radius, 0]), angleToRotate, origin);
|
606 | return new MakerJs.paths.Line(first ? [end, origin] : [origin, end]);
|
607 | };
|
608 | linkLineMap[MakerJs.pathType.Line] = function (line, first, reversed) {
|
609 | return reversed ? new MakerJs.paths.Line(line.end, line.origin) : line;
|
610 | };
|
611 | |
612 |
|
613 |
|
614 | function getLinkLine(chainLink, first) {
|
615 | if (chainLink) {
|
616 | var p = chainLink.walkedPath.pathContext;
|
617 | var fn = linkLineMap[p.type];
|
618 | if (fn) {
|
619 | return fn(p, first, chainLink.reversed);
|
620 | }
|
621 | }
|
622 | }
|
623 | |
624 |
|
625 |
|
626 |
|
627 |
|
628 |
|
629 |
|
630 | function ofChainLinkJoint(linkA, linkB) {
|
631 | if (arguments.length < 2)
|
632 | return null;
|
633 | var linkLines = [linkA, linkB].map(function (link, i) { return getLinkLine(link, i === 0); });
|
634 | var result = noRevolutions(ofLineInDegrees(linkLines[1]) - ofLineInDegrees(linkLines[0]));
|
635 | if (result > 180)
|
636 | result -= 360;
|
637 | return result;
|
638 | }
|
639 | angle.ofChainLinkJoint = ofChainLinkJoint;
|
640 | })(angle = MakerJs.angle || (MakerJs.angle = {}));
|
641 | })(MakerJs || (MakerJs = {}));
|
642 | var MakerJs;
|
643 | (function (MakerJs) {
|
644 | var point;
|
645 | (function (point) {
|
646 | |
647 |
|
648 |
|
649 |
|
650 |
|
651 |
|
652 |
|
653 |
|
654 | function add(a, b, subtract) {
|
655 | var newPoint = clone(a);
|
656 | if (!b)
|
657 | return newPoint;
|
658 | for (var i = 2; i--;) {
|
659 | if (subtract) {
|
660 | newPoint[i] -= b[i];
|
661 | }
|
662 | else {
|
663 | newPoint[i] += b[i];
|
664 | }
|
665 | }
|
666 | return newPoint;
|
667 | }
|
668 | point.add = add;
|
669 | |
670 |
|
671 |
|
672 |
|
673 |
|
674 |
|
675 |
|
676 | function average(a, b) {
|
677 | function avg(i) {
|
678 | return (a[i] + b[i]) / 2;
|
679 | }
|
680 | return [avg(0), avg(1)];
|
681 | }
|
682 | point.average = average;
|
683 | |
684 |
|
685 |
|
686 |
|
687 |
|
688 |
|
689 | function clone(pointToClone) {
|
690 | if (!pointToClone)
|
691 | return point.zero();
|
692 | return [pointToClone[0], pointToClone[1]];
|
693 | }
|
694 | point.clone = clone;
|
695 | |
696 |
|
697 |
|
698 |
|
699 |
|
700 |
|
701 |
|
702 | function closest(referencePoint, pointOptions) {
|
703 | var smallest = {
|
704 | index: 0,
|
705 | distance: -1
|
706 | };
|
707 | for (var i = 0; i < pointOptions.length; i++) {
|
708 | var distance = MakerJs.measure.pointDistance(referencePoint, pointOptions[i]);
|
709 | if (smallest.distance == -1 || distance < smallest.distance) {
|
710 | smallest.distance = distance;
|
711 | smallest.index = i;
|
712 | }
|
713 | }
|
714 | return pointOptions[smallest.index];
|
715 | }
|
716 | point.closest = closest;
|
717 | |
718 |
|
719 |
|
720 | var zero_cos = {};
|
721 | zero_cos[Math.PI / 2] = true;
|
722 | zero_cos[3 * Math.PI / 2] = true;
|
723 | |
724 |
|
725 |
|
726 | var zero_sin = {};
|
727 | zero_sin[Math.PI] = true;
|
728 | zero_sin[2 * Math.PI] = true;
|
729 | |
730 |
|
731 |
|
732 |
|
733 |
|
734 |
|
735 |
|
736 | function fromPolar(angleInRadians, radius) {
|
737 | return [
|
738 | (angleInRadians in zero_cos) ? 0 : MakerJs.round(radius * Math.cos(angleInRadians)),
|
739 | (angleInRadians in zero_sin) ? 0 : MakerJs.round(radius * Math.sin(angleInRadians))
|
740 | ];
|
741 | }
|
742 | point.fromPolar = fromPolar;
|
743 | |
744 |
|
745 |
|
746 |
|
747 |
|
748 |
|
749 | function fromAngleOnCircle(angleInDegrees, circle) {
|
750 | return add(circle.origin, fromPolar(MakerJs.angle.toRadians(angleInDegrees), circle.radius));
|
751 | }
|
752 | point.fromAngleOnCircle = fromAngleOnCircle;
|
753 | |
754 |
|
755 |
|
756 |
|
757 |
|
758 |
|
759 | function fromArc(arc) {
|
760 | return [fromAngleOnCircle(arc.startAngle, arc), fromAngleOnCircle(arc.endAngle, arc)];
|
761 | }
|
762 | point.fromArc = fromArc;
|
763 | |
764 |
|
765 |
|
766 | var pathEndsMap = {};
|
767 | pathEndsMap[MakerJs.pathType.Arc] = function (arc) {
|
768 | return point.fromArc(arc);
|
769 | };
|
770 | pathEndsMap[MakerJs.pathType.Line] = function (line) {
|
771 | return [line.origin, line.end];
|
772 | };
|
773 | pathEndsMap[MakerJs.pathType.BezierSeed] = pathEndsMap[MakerJs.pathType.Line];
|
774 | |
775 |
|
776 |
|
777 |
|
778 |
|
779 |
|
780 | function fromPathEnds(pathContext, pathOffset) {
|
781 | var result = null;
|
782 | var fn = pathEndsMap[pathContext.type];
|
783 | if (fn) {
|
784 | result = fn(pathContext);
|
785 | if (pathOffset) {
|
786 | result = result.map(function (p) { return add(p, pathOffset); });
|
787 | }
|
788 | }
|
789 | return result;
|
790 | }
|
791 | point.fromPathEnds = fromPathEnds;
|
792 | |
793 |
|
794 |
|
795 | function verticalIntersectionPoint(verticalLine, nonVerticalSlope) {
|
796 | var x = verticalLine.origin[0];
|
797 | var y = nonVerticalSlope.slope * x + nonVerticalSlope.yIntercept;
|
798 | return [x, y];
|
799 | }
|
800 | |
801 |
|
802 |
|
803 |
|
804 |
|
805 |
|
806 |
|
807 |
|
808 | function fromSlopeIntersection(lineA, lineB, options) {
|
809 | if (options === void 0) { options = {}; }
|
810 | var slopeA = MakerJs.measure.lineSlope(lineA);
|
811 | var slopeB = MakerJs.measure.lineSlope(lineB);
|
812 |
|
813 | if (MakerJs.measure.isSlopeParallel(slopeA, slopeB)) {
|
814 | if (MakerJs.measure.isSlopeEqual(slopeA, slopeB)) {
|
815 |
|
816 | options.out_AreOverlapped = MakerJs.measure.isLineOverlapping(lineA, lineB, options.excludeTangents);
|
817 | }
|
818 | return null;
|
819 | }
|
820 | var pointOfIntersection;
|
821 | if (!slopeA.hasSlope) {
|
822 | pointOfIntersection = verticalIntersectionPoint(lineA, slopeB);
|
823 | }
|
824 | else if (!slopeB.hasSlope) {
|
825 | pointOfIntersection = verticalIntersectionPoint(lineB, slopeA);
|
826 | }
|
827 | else {
|
828 |
|
829 | var x = (slopeB.yIntercept - slopeA.yIntercept) / (slopeA.slope - slopeB.slope);
|
830 | var y = slopeA.slope * x + slopeA.yIntercept;
|
831 | pointOfIntersection = [x, y];
|
832 | }
|
833 | return pointOfIntersection;
|
834 | }
|
835 | point.fromSlopeIntersection = fromSlopeIntersection;
|
836 | |
837 |
|
838 |
|
839 | function midCircle(circle, midAngle) {
|
840 | return point.add(circle.origin, point.fromPolar(MakerJs.angle.toRadians(midAngle), circle.radius));
|
841 | }
|
842 | |
843 |
|
844 |
|
845 | var middleMap = {};
|
846 | middleMap[MakerJs.pathType.Arc] = function (arc, ratio) {
|
847 | var midAngle = MakerJs.angle.ofArcMiddle(arc, ratio);
|
848 | return midCircle(arc, midAngle);
|
849 | };
|
850 | middleMap[MakerJs.pathType.Circle] = function (circle, ratio) {
|
851 | return midCircle(circle, 360 * ratio);
|
852 | };
|
853 | middleMap[MakerJs.pathType.Line] = function (line, ratio) {
|
854 | function ration(a, b) {
|
855 | return a + (b - a) * ratio;
|
856 | }
|
857 | ;
|
858 | return [
|
859 | ration(line.origin[0], line.end[0]),
|
860 | ration(line.origin[1], line.end[1])
|
861 | ];
|
862 | };
|
863 | middleMap[MakerJs.pathType.BezierSeed] = function (seed, ratio) {
|
864 | return MakerJs.models.BezierCurve.computePoint(seed, ratio);
|
865 | };
|
866 | |
867 |
|
868 |
|
869 |
|
870 |
|
871 |
|
872 |
|
873 | function middle(pathContext, ratio) {
|
874 | if (ratio === void 0) { ratio = .5; }
|
875 | var midPoint = null;
|
876 | var fn = middleMap[pathContext.type];
|
877 | if (fn) {
|
878 | midPoint = fn(pathContext, ratio);
|
879 | }
|
880 | return midPoint;
|
881 | }
|
882 | point.middle = middle;
|
883 | |
884 |
|
885 |
|
886 |
|
887 |
|
888 |
|
889 |
|
890 |
|
891 | function mirror(pointToMirror, mirrorX, mirrorY) {
|
892 | var p = clone(pointToMirror);
|
893 | if (mirrorX) {
|
894 | p[0] = -p[0];
|
895 | }
|
896 | if (mirrorY) {
|
897 | p[1] = -p[1];
|
898 | }
|
899 | return p;
|
900 | }
|
901 | point.mirror = mirror;
|
902 | |
903 |
|
904 |
|
905 |
|
906 |
|
907 |
|
908 |
|
909 | function rounded(pointContext, accuracy) {
|
910 | return [MakerJs.round(pointContext[0], accuracy), MakerJs.round(pointContext[1], accuracy)];
|
911 | }
|
912 | point.rounded = rounded;
|
913 | |
914 |
|
915 |
|
916 |
|
917 |
|
918 |
|
919 |
|
920 |
|
921 | function rotate(pointToRotate, angleInDegrees, rotationOrigin) {
|
922 | if (rotationOrigin === void 0) { rotationOrigin = [0, 0]; }
|
923 | var pointAngleInRadians = MakerJs.angle.ofPointInRadians(rotationOrigin, pointToRotate);
|
924 | var d = MakerJs.measure.pointDistance(rotationOrigin, pointToRotate);
|
925 | var rotatedPoint = fromPolar(pointAngleInRadians + MakerJs.angle.toRadians(angleInDegrees), d);
|
926 | return add(rotationOrigin, rotatedPoint);
|
927 | }
|
928 | point.rotate = rotate;
|
929 | |
930 |
|
931 |
|
932 |
|
933 |
|
934 |
|
935 |
|
936 | function scale(pointToScale, scaleValue) {
|
937 | var p = clone(pointToScale);
|
938 | for (var i = 2; i--;) {
|
939 | p[i] *= scaleValue;
|
940 | }
|
941 | return p;
|
942 | }
|
943 | point.scale = scale;
|
944 | |
945 |
|
946 |
|
947 |
|
948 |
|
949 |
|
950 |
|
951 |
|
952 | function distort(pointToDistort, scaleX, scaleY) {
|
953 | return [pointToDistort[0] * scaleX, pointToDistort[1] * scaleY];
|
954 | }
|
955 | point.distort = distort;
|
956 | |
957 |
|
958 |
|
959 |
|
960 |
|
961 |
|
962 |
|
963 | function subtract(a, b) {
|
964 | return add(a, b, true);
|
965 | }
|
966 | point.subtract = subtract;
|
967 | |
968 |
|
969 |
|
970 |
|
971 |
|
972 |
|
973 | function zero() {
|
974 | return [0, 0];
|
975 | }
|
976 | point.zero = zero;
|
977 | })(point = MakerJs.point || (MakerJs.point = {}));
|
978 | })(MakerJs || (MakerJs = {}));
|
979 | var MakerJs;
|
980 | (function (MakerJs) {
|
981 | var path;
|
982 | (function (path) {
|
983 | |
984 |
|
985 |
|
986 |
|
987 |
|
988 |
|
989 |
|
990 |
|
991 |
|
992 |
|
993 |
|
994 |
|
995 |
|
996 | function addTo(childPath, parentModel, pathId, overwrite) {
|
997 | if (overwrite === void 0) { overwrite = false; }
|
998 | MakerJs.model.addPath(parentModel, childPath, pathId, overwrite);
|
999 | return childPath;
|
1000 | }
|
1001 | path.addTo = addTo;
|
1002 | |
1003 |
|
1004 |
|
1005 | function copyLayer(pathA, pathB) {
|
1006 | if (pathA && pathB && typeof pathA.layer !== 'undefined') {
|
1007 | pathB.layer = pathA.layer;
|
1008 | }
|
1009 |
|
1010 | if (pathA && pathB && ('bezierData' in pathA)) {
|
1011 | pathB.bezierData = pathA.bezierData;
|
1012 | }
|
1013 | }
|
1014 | |
1015 |
|
1016 |
|
1017 | var copyPropsMap = {};
|
1018 | copyPropsMap[MakerJs.pathType.Circle] = function (srcCircle, destCircle, offset) {
|
1019 | destCircle.radius = srcCircle.radius;
|
1020 | };
|
1021 | copyPropsMap[MakerJs.pathType.Arc] = function (srcArc, destArc, offset) {
|
1022 | copyPropsMap[MakerJs.pathType.Circle](srcArc, destArc, offset);
|
1023 | destArc.startAngle = srcArc.startAngle;
|
1024 | destArc.endAngle = srcArc.endAngle;
|
1025 | };
|
1026 | copyPropsMap[MakerJs.pathType.Line] = function (srcLine, destLine, offset) {
|
1027 | destLine.end = MakerJs.point.add(srcLine.end, offset);
|
1028 | };
|
1029 | copyPropsMap[MakerJs.pathType.BezierSeed] = function (srcSeed, destSeed, offset) {
|
1030 | copyPropsMap[MakerJs.pathType.Line](srcSeed, destSeed, offset);
|
1031 | destSeed.controls = srcSeed.controls.map(function (p) { return MakerJs.point.add(p, offset); });
|
1032 | };
|
1033 | |
1034 |
|
1035 |
|
1036 |
|
1037 |
|
1038 |
|
1039 |
|
1040 | function clone(pathToClone, offset) {
|
1041 | var result = { type: pathToClone.type, origin: MakerJs.point.add(pathToClone.origin, offset) };
|
1042 | var fn = copyPropsMap[pathToClone.type];
|
1043 | if (fn) {
|
1044 | fn(pathToClone, result, offset);
|
1045 | }
|
1046 | copyLayer(pathToClone, result);
|
1047 | return result;
|
1048 | }
|
1049 | path.clone = clone;
|
1050 | |
1051 |
|
1052 |
|
1053 |
|
1054 |
|
1055 |
|
1056 |
|
1057 | function copyProps(srcPath, destPath) {
|
1058 | var fn = copyPropsMap[srcPath.type];
|
1059 | if (fn) {
|
1060 | destPath.origin = MakerJs.point.clone(srcPath.origin);
|
1061 | fn(srcPath, destPath);
|
1062 | }
|
1063 | copyLayer(srcPath, destPath);
|
1064 | return srcPath;
|
1065 | }
|
1066 | path.copyProps = copyProps;
|
1067 | |
1068 |
|
1069 |
|
1070 | var mirrorMap = {};
|
1071 | mirrorMap[MakerJs.pathType.Line] = function (line, origin, mirrorX, mirrorY) {
|
1072 | return new MakerJs.paths.Line(origin, MakerJs.point.mirror(line.end, mirrorX, mirrorY));
|
1073 | };
|
1074 | mirrorMap[MakerJs.pathType.Circle] = function (circle, origin, mirrorX, mirrorY) {
|
1075 | return new MakerJs.paths.Circle(origin, circle.radius);
|
1076 | };
|
1077 | mirrorMap[MakerJs.pathType.Arc] = function (arc, origin, mirrorX, mirrorY) {
|
1078 | var startAngle = MakerJs.angle.mirror(arc.startAngle, mirrorX, mirrorY);
|
1079 | var endAngle = MakerJs.angle.mirror(MakerJs.angle.ofArcEnd(arc), mirrorX, mirrorY);
|
1080 | var xor = mirrorX != mirrorY;
|
1081 | return new MakerJs.paths.Arc(origin, arc.radius, xor ? endAngle : startAngle, xor ? startAngle : endAngle);
|
1082 | };
|
1083 | mirrorMap[MakerJs.pathType.BezierSeed] = function (seed, origin, mirrorX, mirrorY) {
|
1084 | var mirrored = mirrorMap[MakerJs.pathType.Line](seed, origin, mirrorX, mirrorY);
|
1085 | mirrored.type = MakerJs.pathType.BezierSeed;
|
1086 | mirrored.controls = seed.controls.map(function (c) { return MakerJs.point.mirror(c, mirrorX, mirrorY); });
|
1087 | return mirrored;
|
1088 | };
|
1089 | |
1090 |
|
1091 |
|
1092 |
|
1093 |
|
1094 |
|
1095 |
|
1096 |
|
1097 |
|
1098 |
|
1099 | function layer(pathContext, layer) {
|
1100 | pathContext.layer = layer;
|
1101 | return pathContext;
|
1102 | }
|
1103 | path.layer = layer;
|
1104 | |
1105 |
|
1106 |
|
1107 |
|
1108 |
|
1109 |
|
1110 |
|
1111 |
|
1112 | function mirror(pathToMirror, mirrorX, mirrorY) {
|
1113 | var newPath = null;
|
1114 | if (pathToMirror) {
|
1115 | var origin = MakerJs.point.mirror(pathToMirror.origin, mirrorX, mirrorY);
|
1116 | var fn = mirrorMap[pathToMirror.type];
|
1117 | if (fn) {
|
1118 | newPath = fn(pathToMirror, origin, mirrorX, mirrorY);
|
1119 | }
|
1120 | }
|
1121 | copyLayer(pathToMirror, newPath);
|
1122 | return newPath;
|
1123 | }
|
1124 | path.mirror = mirror;
|
1125 | |
1126 |
|
1127 |
|
1128 | var moveMap = {};
|
1129 | moveMap[MakerJs.pathType.Line] = function (line, origin) {
|
1130 | var delta = MakerJs.point.subtract(line.end, line.origin);
|
1131 | line.end = MakerJs.point.add(origin, delta);
|
1132 | };
|
1133 | |
1134 |
|
1135 |
|
1136 |
|
1137 |
|
1138 |
|
1139 |
|
1140 | function move(pathToMove, origin) {
|
1141 | if (pathToMove) {
|
1142 | var fn = moveMap[pathToMove.type];
|
1143 | if (fn) {
|
1144 | fn(pathToMove, origin);
|
1145 | }
|
1146 | pathToMove.origin = origin;
|
1147 | }
|
1148 | return pathToMove;
|
1149 | }
|
1150 | path.move = move;
|
1151 | |
1152 |
|
1153 |
|
1154 | var moveRelativeMap = {};
|
1155 | moveRelativeMap[MakerJs.pathType.Line] = function (line, delta, subtract) {
|
1156 | line.end = MakerJs.point.add(line.end, delta, subtract);
|
1157 | };
|
1158 | moveRelativeMap[MakerJs.pathType.BezierSeed] = function (seed, delta, subtract) {
|
1159 | moveRelativeMap[MakerJs.pathType.Line](seed, delta, subtract);
|
1160 | seed.controls = seed.controls.map(function (c) { return MakerJs.point.add(c, delta, subtract); });
|
1161 | };
|
1162 | |
1163 |
|
1164 |
|
1165 |
|
1166 |
|
1167 |
|
1168 |
|
1169 |
|
1170 | function moveRelative(pathToMove, delta, subtract) {
|
1171 | if (pathToMove && delta) {
|
1172 | pathToMove.origin = MakerJs.point.add(pathToMove.origin, delta, subtract);
|
1173 | var fn = moveRelativeMap[pathToMove.type];
|
1174 | if (fn) {
|
1175 | fn(pathToMove, delta, subtract);
|
1176 | }
|
1177 | }
|
1178 | return pathToMove;
|
1179 | }
|
1180 | path.moveRelative = moveRelative;
|
1181 | |
1182 |
|
1183 |
|
1184 |
|
1185 |
|
1186 |
|
1187 |
|
1188 | function moveTemporary(pathsToMove, deltas, task) {
|
1189 | var subtract = false;
|
1190 | function move(pathToOffset, i) {
|
1191 | if (deltas[i]) {
|
1192 | moveRelative(pathToOffset, deltas[i], subtract);
|
1193 | }
|
1194 | }
|
1195 | pathsToMove.map(move);
|
1196 | task();
|
1197 | subtract = true;
|
1198 | pathsToMove.map(move);
|
1199 | }
|
1200 | path.moveTemporary = moveTemporary;
|
1201 | |
1202 |
|
1203 |
|
1204 | var rotateMap = {};
|
1205 | rotateMap[MakerJs.pathType.Line] = function (line, angleInDegrees, rotationOrigin) {
|
1206 | line.end = MakerJs.point.rotate(line.end, angleInDegrees, rotationOrigin);
|
1207 | };
|
1208 | rotateMap[MakerJs.pathType.Arc] = function (arc, angleInDegrees, rotationOrigin) {
|
1209 | arc.startAngle = MakerJs.angle.noRevolutions(arc.startAngle + angleInDegrees);
|
1210 | arc.endAngle = MakerJs.angle.noRevolutions(arc.endAngle + angleInDegrees);
|
1211 | };
|
1212 | rotateMap[MakerJs.pathType.BezierSeed] = function (seed, angleInDegrees, rotationOrigin) {
|
1213 | rotateMap[MakerJs.pathType.Line](seed, angleInDegrees, rotationOrigin);
|
1214 | seed.controls = seed.controls.map(function (c) { return MakerJs.point.rotate(c, angleInDegrees, rotationOrigin); });
|
1215 | };
|
1216 | |
1217 |
|
1218 |
|
1219 |
|
1220 |
|
1221 |
|
1222 |
|
1223 |
|
1224 | function rotate(pathToRotate, angleInDegrees, rotationOrigin) {
|
1225 | if (rotationOrigin === void 0) { rotationOrigin = [0, 0]; }
|
1226 | if (!pathToRotate || !angleInDegrees)
|
1227 | return pathToRotate;
|
1228 | pathToRotate.origin = MakerJs.point.rotate(pathToRotate.origin, angleInDegrees, rotationOrigin);
|
1229 | var fn = rotateMap[pathToRotate.type];
|
1230 | if (fn) {
|
1231 | fn(pathToRotate, angleInDegrees, rotationOrigin);
|
1232 | }
|
1233 | return pathToRotate;
|
1234 | }
|
1235 | path.rotate = rotate;
|
1236 | |
1237 |
|
1238 |
|
1239 | var scaleMap = {};
|
1240 | scaleMap[MakerJs.pathType.Line] = function (line, scaleValue) {
|
1241 | line.end = MakerJs.point.scale(line.end, scaleValue);
|
1242 | };
|
1243 | scaleMap[MakerJs.pathType.BezierSeed] = function (seed, scaleValue) {
|
1244 | scaleMap[MakerJs.pathType.Line](seed, scaleValue);
|
1245 | seed.controls = seed.controls.map(function (c) { return MakerJs.point.scale(c, scaleValue); });
|
1246 | };
|
1247 | scaleMap[MakerJs.pathType.Circle] = function (circle, scaleValue) {
|
1248 | circle.radius *= scaleValue;
|
1249 | };
|
1250 | scaleMap[MakerJs.pathType.Arc] = scaleMap[MakerJs.pathType.Circle];
|
1251 | |
1252 |
|
1253 |
|
1254 |
|
1255 |
|
1256 |
|
1257 |
|
1258 | function scale(pathToScale, scaleValue) {
|
1259 | if (!pathToScale || scaleValue === 1 || !scaleValue)
|
1260 | return pathToScale;
|
1261 | pathToScale.origin = MakerJs.point.scale(pathToScale.origin, scaleValue);
|
1262 | var fn = scaleMap[pathToScale.type];
|
1263 | if (fn) {
|
1264 | fn(pathToScale, scaleValue);
|
1265 | }
|
1266 | return pathToScale;
|
1267 | }
|
1268 | path.scale = scale;
|
1269 | |
1270 |
|
1271 |
|
1272 | var distortMap = {};
|
1273 | distortMap[MakerJs.pathType.Arc] = function (arc, scaleX, scaleY) {
|
1274 | return new MakerJs.models.EllipticArc(arc, scaleX, scaleY);
|
1275 | };
|
1276 | distortMap[MakerJs.pathType.Circle] = function (circle, scaleX, scaleY) {
|
1277 | var ellipse = new MakerJs.models.Ellipse(circle.radius * scaleX, circle.radius * scaleY);
|
1278 | ellipse.origin = MakerJs.point.distort(circle.origin, scaleX, scaleY);
|
1279 | return ellipse;
|
1280 | };
|
1281 | distortMap[MakerJs.pathType.Line] = function (line, scaleX, scaleY) {
|
1282 | return new MakerJs.paths.Line([line.origin, line.end].map(function (p) { return MakerJs.point.distort(p, scaleX, scaleY); }));
|
1283 | };
|
1284 | distortMap[MakerJs.pathType.BezierSeed] = function (seed, scaleX, scaleY) {
|
1285 | var d = MakerJs.point.distort;
|
1286 | return {
|
1287 | type: MakerJs.pathType.BezierSeed,
|
1288 | origin: d(seed.origin, scaleX, scaleY),
|
1289 | controls: seed.controls.map(function (c) { return d(c, scaleX, scaleY); }),
|
1290 | end: d(seed.end, scaleX, scaleY)
|
1291 | };
|
1292 | };
|
1293 | |
1294 |
|
1295 |
|
1296 |
|
1297 |
|
1298 |
|
1299 |
|
1300 |
|
1301 | function distort(pathToDistort, scaleX, scaleY) {
|
1302 | if (!pathToDistort || !scaleX || !scaleY)
|
1303 | return null;
|
1304 | var fn = distortMap[pathToDistort.type];
|
1305 | if (fn) {
|
1306 | var distorted = fn(pathToDistort, scaleX, scaleY);
|
1307 | if (typeof pathToDistort.layer !== 'undefined') {
|
1308 | distorted.layer = pathToDistort.layer;
|
1309 | }
|
1310 | return distorted;
|
1311 | }
|
1312 | return null;
|
1313 | }
|
1314 | path.distort = distort;
|
1315 | |
1316 |
|
1317 |
|
1318 |
|
1319 |
|
1320 |
|
1321 |
|
1322 |
|
1323 |
|
1324 | function converge(lineA, lineB, useOriginA, useOriginB) {
|
1325 | var p = MakerJs.point.fromSlopeIntersection(lineA, lineB);
|
1326 | if (p) {
|
1327 | var lines = [lineA, lineB];
|
1328 | var useOrigin = [useOriginA, useOriginB];
|
1329 | if (arguments.length === 2) {
|
1330 |
|
1331 | lines.forEach(function (line, i) {
|
1332 | useOrigin[i] = (MakerJs.point.closest(p, [line.origin, line.end]) === line.origin);
|
1333 | });
|
1334 | }
|
1335 | function setPoint(line, useOrigin) {
|
1336 | var setP;
|
1337 | if (useOrigin) {
|
1338 | setP = line.origin;
|
1339 | }
|
1340 | else {
|
1341 | setP = line.end;
|
1342 | }
|
1343 | setP[0] = p[0];
|
1344 | setP[1] = p[1];
|
1345 | }
|
1346 | lines.forEach(function (line, i) {
|
1347 | setPoint(line, useOrigin[i]);
|
1348 | });
|
1349 | }
|
1350 | return p;
|
1351 | }
|
1352 | path.converge = converge;
|
1353 | |
1354 |
|
1355 |
|
1356 | var alterMap = {};
|
1357 | alterMap[MakerJs.pathType.Arc] = function (arc, pathLength, distance, useOrigin) {
|
1358 | var span = MakerJs.angle.ofArcSpan(arc);
|
1359 | var delta = ((pathLength + distance) * span / pathLength) - span;
|
1360 | if (useOrigin) {
|
1361 | arc.startAngle -= delta;
|
1362 | }
|
1363 | else {
|
1364 | arc.endAngle += delta;
|
1365 | }
|
1366 | };
|
1367 | alterMap[MakerJs.pathType.Circle] = function (circle, pathLength, distance, useOrigin) {
|
1368 | circle.radius *= (pathLength + distance) / pathLength;
|
1369 | };
|
1370 | alterMap[MakerJs.pathType.Line] = function (line, pathLength, distance, useOrigin) {
|
1371 | var delta = MakerJs.point.scale(MakerJs.point.subtract(line.end, line.origin), distance / pathLength);
|
1372 | if (useOrigin) {
|
1373 | line.origin = MakerJs.point.subtract(line.origin, delta);
|
1374 | }
|
1375 | else {
|
1376 | line.end = MakerJs.point.add(line.end, delta);
|
1377 | }
|
1378 | };
|
1379 | |
1380 |
|
1381 |
|
1382 |
|
1383 |
|
1384 |
|
1385 |
|
1386 |
|
1387 | function alterLength(pathToAlter, distance, useOrigin) {
|
1388 | if (useOrigin === void 0) { useOrigin = false; }
|
1389 | if (!pathToAlter || !distance)
|
1390 | return null;
|
1391 | var fn = alterMap[pathToAlter.type];
|
1392 | if (fn) {
|
1393 | var pathLength = MakerJs.measure.pathLength(pathToAlter);
|
1394 | if (!pathLength || -distance >= pathLength)
|
1395 | return null;
|
1396 | fn(pathToAlter, pathLength, distance, useOrigin);
|
1397 | return pathToAlter;
|
1398 | }
|
1399 | return null;
|
1400 | }
|
1401 | path.alterLength = alterLength;
|
1402 | |
1403 |
|
1404 |
|
1405 |
|
1406 |
|
1407 |
|
1408 |
|
1409 | function toPoints(pathContext, numberOfPoints) {
|
1410 |
|
1411 | if (numberOfPoints == 1) {
|
1412 | return [MakerJs.point.middle(pathContext)];
|
1413 | }
|
1414 | var points = [];
|
1415 | var base = numberOfPoints;
|
1416 | if (pathContext.type != MakerJs.pathType.Circle)
|
1417 | base--;
|
1418 | for (var i = 0; i < numberOfPoints; i++) {
|
1419 | points.push(MakerJs.point.middle(pathContext, i / base));
|
1420 | }
|
1421 | return points;
|
1422 | }
|
1423 | path.toPoints = toPoints;
|
1424 | |
1425 |
|
1426 |
|
1427 | var numberOfKeyPointsMap = {};
|
1428 | numberOfKeyPointsMap[MakerJs.pathType.Line] = function (line) {
|
1429 | return 2;
|
1430 | };
|
1431 | numberOfKeyPointsMap[MakerJs.pathType.Circle] = function (circle, maxPointDistance) {
|
1432 | var len = MakerJs.measure.pathLength(circle);
|
1433 | if (!len)
|
1434 | return 0;
|
1435 | maxPointDistance = maxPointDistance || len;
|
1436 | return Math.max(8, Math.ceil(len / (maxPointDistance || len)));
|
1437 | };
|
1438 | numberOfKeyPointsMap[MakerJs.pathType.Arc] = function (arc, maxPointDistance) {
|
1439 | var len = MakerJs.measure.pathLength(arc);
|
1440 | if (!len)
|
1441 | return 0;
|
1442 | var minPoints = Math.ceil(MakerJs.angle.ofArcSpan(arc) / 45) + 1;
|
1443 | return Math.max(minPoints, Math.ceil(len / (maxPointDistance || len)));
|
1444 | };
|
1445 | |
1446 |
|
1447 |
|
1448 |
|
1449 |
|
1450 |
|
1451 |
|
1452 | function toKeyPoints(pathContext, maxArcFacet) {
|
1453 | if (pathContext.type == MakerJs.pathType.BezierSeed) {
|
1454 | var curve = new MakerJs.models.BezierCurve(pathContext);
|
1455 | var curveKeyPoints;
|
1456 | MakerJs.model.findChains(curve, function (chains, loose, layer) {
|
1457 | if (chains.length == 1) {
|
1458 | var c = chains[0];
|
1459 | switch (c.links[0].walkedPath.pathId) {
|
1460 | case 'arc_0':
|
1461 | case 'line_0':
|
1462 | break;
|
1463 | default:
|
1464 | MakerJs.chain.reverse(c);
|
1465 | }
|
1466 | curveKeyPoints = MakerJs.chain.toKeyPoints(c);
|
1467 | }
|
1468 | else if (loose.length === 1) {
|
1469 | curveKeyPoints = toKeyPoints(loose[0].pathContext);
|
1470 | }
|
1471 | });
|
1472 | return curveKeyPoints;
|
1473 | }
|
1474 | else {
|
1475 | var fn = numberOfKeyPointsMap[pathContext.type];
|
1476 | if (fn) {
|
1477 | var numberOfKeyPoints = fn(pathContext, maxArcFacet);
|
1478 | if (numberOfKeyPoints) {
|
1479 | return toPoints(pathContext, numberOfKeyPoints);
|
1480 | }
|
1481 | }
|
1482 | }
|
1483 | return [];
|
1484 | }
|
1485 | path.toKeyPoints = toKeyPoints;
|
1486 | |
1487 |
|
1488 |
|
1489 |
|
1490 |
|
1491 |
|
1492 | function center(pathToCenter) {
|
1493 | var m = MakerJs.measure.pathExtents(pathToCenter);
|
1494 | var c = MakerJs.point.average(m.high, m.low);
|
1495 | var o = MakerJs.point.subtract(pathToCenter.origin || [0, 0], c);
|
1496 | move(pathToCenter, o);
|
1497 | return pathToCenter;
|
1498 | }
|
1499 | path.center = center;
|
1500 | |
1501 |
|
1502 |
|
1503 |
|
1504 |
|
1505 |
|
1506 | function zero(pathToZero) {
|
1507 | var m = MakerJs.measure.pathExtents(pathToZero);
|
1508 | var z = MakerJs.point.subtract(pathToZero.origin || [0, 0], m.low);
|
1509 | move(pathToZero, z);
|
1510 | return pathToZero;
|
1511 | }
|
1512 | path.zero = zero;
|
1513 | })(path = MakerJs.path || (MakerJs.path = {}));
|
1514 | })(MakerJs || (MakerJs = {}));
|
1515 | var MakerJs;
|
1516 | (function (MakerJs) {
|
1517 | var path;
|
1518 | (function (path_1) {
|
1519 | |
1520 |
|
1521 |
|
1522 | var breakPathFunctionMap = {};
|
1523 | breakPathFunctionMap[MakerJs.pathType.Arc] = function (arc, pointOfBreak) {
|
1524 | var angleAtBreakPoint = MakerJs.angle.ofPointInDegrees(arc.origin, pointOfBreak);
|
1525 | if (MakerJs.measure.isAngleEqual(angleAtBreakPoint, arc.startAngle) || MakerJs.measure.isAngleEqual(angleAtBreakPoint, arc.endAngle)) {
|
1526 | return null;
|
1527 | }
|
1528 | function getAngleStrictlyBetweenArcAngles() {
|
1529 | var startAngle = MakerJs.angle.noRevolutions(arc.startAngle);
|
1530 | var endAngle = startAngle + MakerJs.angle.ofArcEnd(arc) - arc.startAngle;
|
1531 | var tries = [0, 1, -1];
|
1532 | for (var i = 0; i < tries.length; i++) {
|
1533 | var add = +360 * tries[i];
|
1534 | if (MakerJs.measure.isBetween(angleAtBreakPoint + add, startAngle, endAngle, true)) {
|
1535 | return arc.startAngle + angleAtBreakPoint + add - startAngle;
|
1536 | }
|
1537 | }
|
1538 | return null;
|
1539 | }
|
1540 | var angleAtBreakPointBetween = getAngleStrictlyBetweenArcAngles();
|
1541 | if (angleAtBreakPointBetween == null) {
|
1542 | return null;
|
1543 | }
|
1544 | var savedEndAngle = arc.endAngle;
|
1545 | arc.endAngle = angleAtBreakPointBetween;
|
1546 |
|
1547 | var copy = MakerJs.cloneObject(arc);
|
1548 | copy.startAngle = angleAtBreakPointBetween;
|
1549 | copy.endAngle = savedEndAngle;
|
1550 | return copy;
|
1551 | };
|
1552 | breakPathFunctionMap[MakerJs.pathType.Circle] = function (circle, pointOfBreak) {
|
1553 |
|
1554 | circle.type = MakerJs.pathType.Arc;
|
1555 | var arc = circle;
|
1556 | var angleAtBreakPoint = MakerJs.angle.ofPointInDegrees(circle.origin, pointOfBreak);
|
1557 | arc.startAngle = angleAtBreakPoint;
|
1558 | arc.endAngle = angleAtBreakPoint + 360;
|
1559 | return null;
|
1560 | };
|
1561 | breakPathFunctionMap[MakerJs.pathType.Line] = function (line, pointOfBreak) {
|
1562 | if (!MakerJs.measure.isBetweenPoints(pointOfBreak, line, true)) {
|
1563 | return null;
|
1564 | }
|
1565 | var savedEndPoint = line.end;
|
1566 | line.end = pointOfBreak;
|
1567 |
|
1568 | var copy = MakerJs.cloneObject(line);
|
1569 | copy.origin = pointOfBreak;
|
1570 | copy.end = savedEndPoint;
|
1571 | return copy;
|
1572 | };
|
1573 | |
1574 |
|
1575 |
|
1576 |
|
1577 |
|
1578 |
|
1579 |
|
1580 |
|
1581 |
|
1582 | function breakAtPoint(pathToBreak, pointOfBreak) {
|
1583 | if (pathToBreak && pointOfBreak) {
|
1584 | var fn = breakPathFunctionMap[pathToBreak.type];
|
1585 | if (fn) {
|
1586 | var result = fn(pathToBreak, pointOfBreak);
|
1587 | if (result && ('layer' in pathToBreak)) {
|
1588 | result.layer = pathToBreak.layer;
|
1589 | }
|
1590 | return result;
|
1591 | }
|
1592 | }
|
1593 | return null;
|
1594 | }
|
1595 | path_1.breakAtPoint = breakAtPoint;
|
1596 | })(path = MakerJs.path || (MakerJs.path = {}));
|
1597 | })(MakerJs || (MakerJs = {}));
|
1598 | var MakerJs;
|
1599 | (function (MakerJs) {
|
1600 | var paths;
|
1601 | (function (paths) {
|
1602 | |
1603 |
|
1604 |
|
1605 | var Arc = (function () {
|
1606 | function Arc() {
|
1607 | var args = [];
|
1608 | for (var _i = 0; _i < arguments.length; _i++) {
|
1609 | args[_i] = arguments[_i];
|
1610 | }
|
1611 | function getSpan(origin) {
|
1612 | var startAngle = MakerJs.angle.ofPointInDegrees(origin, args[clockwise ? 1 : 0]);
|
1613 | var endAngle = MakerJs.angle.ofPointInDegrees(origin, args[clockwise ? 0 : 1]);
|
1614 | if (endAngle < startAngle) {
|
1615 | endAngle += 360;
|
1616 | }
|
1617 | return {
|
1618 | origin: origin,
|
1619 | startAngle: startAngle,
|
1620 | endAngle: endAngle,
|
1621 | size: endAngle - startAngle
|
1622 | };
|
1623 | }
|
1624 | switch (args.length) {
|
1625 | case 5:
|
1626 |
|
1627 | var pointA = args[0];
|
1628 | var pointB = args[1];
|
1629 | this.radius = args[2];
|
1630 | var largeArc = args[3];
|
1631 | var clockwise = args[4];
|
1632 | var span;
|
1633 |
|
1634 | var smallestRadius = MakerJs.measure.pointDistance(pointA, pointB) / 2;
|
1635 | if (MakerJs.round(this.radius - smallestRadius) <= 0) {
|
1636 | this.radius = smallestRadius;
|
1637 | span = getSpan(MakerJs.point.average(pointA, pointB));
|
1638 | }
|
1639 | else {
|
1640 |
|
1641 | var origins = MakerJs.path.intersection(new Circle(pointA, this.radius), new Circle(pointB, this.radius));
|
1642 | var spans = [];
|
1643 | for (var i = origins.intersectionPoints.length; i--;) {
|
1644 | span = getSpan(origins.intersectionPoints[i]);
|
1645 |
|
1646 | if (spans.length == 0 || span.size > spans[0].size) {
|
1647 | spans.push(span);
|
1648 | }
|
1649 | else {
|
1650 | spans.unshift(span);
|
1651 | }
|
1652 | }
|
1653 | var index = largeArc ? 1 : 0;
|
1654 | span = spans[index];
|
1655 | }
|
1656 | this.origin = span.origin;
|
1657 | this.startAngle = span.startAngle;
|
1658 | this.endAngle = span.endAngle;
|
1659 | break;
|
1660 | case 4:
|
1661 | this.origin = args[0];
|
1662 | this.radius = args[1];
|
1663 | this.startAngle = args[2];
|
1664 | this.endAngle = args[3];
|
1665 | break;
|
1666 | case 3:
|
1667 | if (MakerJs.isPoint(args[2])) {
|
1668 |
|
1669 | Circle.apply(this, args);
|
1670 | var angles = [];
|
1671 | for (var i = 0; i < 3; i++) {
|
1672 | angles.push(MakerJs.angle.ofPointInDegrees(this.origin, args[i]));
|
1673 | }
|
1674 | this.startAngle = angles[0];
|
1675 | this.endAngle = angles[2];
|
1676 |
|
1677 | if (!MakerJs.measure.isBetweenArcAngles(angles[1], this, false)) {
|
1678 | this.startAngle = angles[2];
|
1679 | this.endAngle = angles[0];
|
1680 | }
|
1681 |
|
1682 | break;
|
1683 | }
|
1684 |
|
1685 | case 2:
|
1686 |
|
1687 | var clockwise = args[2];
|
1688 | Circle.call(this, args[0], args[1]);
|
1689 | this.startAngle = MakerJs.angle.ofPointInDegrees(this.origin, args[clockwise ? 1 : 0]);
|
1690 | this.endAngle = MakerJs.angle.ofPointInDegrees(this.origin, args[clockwise ? 0 : 1]);
|
1691 | break;
|
1692 | }
|
1693 |
|
1694 | this.type = MakerJs.pathType.Arc;
|
1695 | }
|
1696 | return Arc;
|
1697 | }());
|
1698 | paths.Arc = Arc;
|
1699 | |
1700 |
|
1701 |
|
1702 | var Circle = (function () {
|
1703 | function Circle() {
|
1704 | var args = [];
|
1705 | for (var _i = 0; _i < arguments.length; _i++) {
|
1706 | args[_i] = arguments[_i];
|
1707 | }
|
1708 | this.type = MakerJs.pathType.Circle;
|
1709 | switch (args.length) {
|
1710 | case 1:
|
1711 | this.origin = [0, 0];
|
1712 | this.radius = args[0];
|
1713 | break;
|
1714 | case 2:
|
1715 | if (MakerJs.isNumber(args[1])) {
|
1716 | this.origin = args[0];
|
1717 | this.radius = args[1];
|
1718 | }
|
1719 | else {
|
1720 |
|
1721 | this.origin = MakerJs.point.average(args[0], args[1]);
|
1722 | this.radius = MakerJs.measure.pointDistance(this.origin, args[0]);
|
1723 | }
|
1724 | break;
|
1725 | default:
|
1726 |
|
1727 |
|
1728 | var lines = [
|
1729 | new Line(args[0], args[1]),
|
1730 | new Line(args[1], args[2])
|
1731 | ];
|
1732 |
|
1733 | var perpendiculars = [];
|
1734 | for (var i = 2; i--;) {
|
1735 | var midpoint = MakerJs.point.middle(lines[i]);
|
1736 | perpendiculars.push(MakerJs.path.rotate(lines[i], 90, midpoint));
|
1737 | }
|
1738 |
|
1739 | var origin = MakerJs.point.fromSlopeIntersection(perpendiculars[0], perpendiculars[1]);
|
1740 | if (origin) {
|
1741 | this.origin = origin;
|
1742 |
|
1743 | this.radius = MakerJs.measure.pointDistance(this.origin, args[0]);
|
1744 | }
|
1745 | else {
|
1746 | throw 'invalid parameters - attempted to construct a circle from 3 points on a line: ' + JSON.stringify(args);
|
1747 | }
|
1748 | break;
|
1749 | }
|
1750 | }
|
1751 | return Circle;
|
1752 | }());
|
1753 | paths.Circle = Circle;
|
1754 | |
1755 |
|
1756 |
|
1757 | var Line = (function () {
|
1758 | function Line() {
|
1759 | var args = [];
|
1760 | for (var _i = 0; _i < arguments.length; _i++) {
|
1761 | args[_i] = arguments[_i];
|
1762 | }
|
1763 | this.type = MakerJs.pathType.Line;
|
1764 | switch (args.length) {
|
1765 | case 1:
|
1766 | var points = args[0];
|
1767 | this.origin = points[0];
|
1768 | this.end = points[1];
|
1769 | break;
|
1770 | case 2:
|
1771 | this.origin = args[0];
|
1772 | this.end = args[1];
|
1773 | break;
|
1774 | }
|
1775 | }
|
1776 | return Line;
|
1777 | }());
|
1778 | paths.Line = Line;
|
1779 | |
1780 |
|
1781 |
|
1782 |
|
1783 |
|
1784 | var Chord = (function () {
|
1785 | function Chord(arc) {
|
1786 | var arcPoints = MakerJs.point.fromArc(arc);
|
1787 | this.type = MakerJs.pathType.Line;
|
1788 | this.origin = arcPoints[0];
|
1789 | this.end = arcPoints[1];
|
1790 | }
|
1791 | return Chord;
|
1792 | }());
|
1793 | paths.Chord = Chord;
|
1794 | |
1795 |
|
1796 |
|
1797 |
|
1798 |
|
1799 |
|
1800 |
|
1801 | var Parallel = (function () {
|
1802 | function Parallel(toLine, distance, nearPoint) {
|
1803 | this.type = MakerJs.pathType.Line;
|
1804 | this.origin = MakerJs.point.clone(toLine.origin);
|
1805 | this.end = MakerJs.point.clone(toLine.end);
|
1806 | var angleOfLine = MakerJs.angle.ofLineInDegrees(this);
|
1807 | function getNewOrigin(offsetAngle) {
|
1808 | var origin = MakerJs.point.add(toLine.origin, MakerJs.point.fromPolar(MakerJs.angle.toRadians(angleOfLine + offsetAngle), distance));
|
1809 | return {
|
1810 | origin: origin,
|
1811 | nearness: MakerJs.measure.pointDistance(origin, nearPoint)
|
1812 | };
|
1813 | }
|
1814 | var newOrigins = [getNewOrigin(-90), getNewOrigin(90)];
|
1815 | var newOrigin = (newOrigins[0].nearness < newOrigins[1].nearness) ? newOrigins[0].origin : newOrigins[1].origin;
|
1816 | MakerJs.path.move(this, newOrigin);
|
1817 | }
|
1818 | return Parallel;
|
1819 | }());
|
1820 | paths.Parallel = Parallel;
|
1821 | })(paths = MakerJs.paths || (MakerJs.paths = {}));
|
1822 | })(MakerJs || (MakerJs = {}));
|
1823 | var MakerJs;
|
1824 | (function (MakerJs) {
|
1825 | var model;
|
1826 | (function (model) {
|
1827 | |
1828 |
|
1829 |
|
1830 |
|
1831 |
|
1832 |
|
1833 |
|
1834 |
|
1835 | function addCaption(modelContext, text, leftAnchorPoint, rightAnchorPoint) {
|
1836 | if (!leftAnchorPoint) {
|
1837 | leftAnchorPoint = MakerJs.point.zero();
|
1838 | }
|
1839 | if (!rightAnchorPoint) {
|
1840 | rightAnchorPoint = MakerJs.point.clone(leftAnchorPoint);
|
1841 | }
|
1842 | modelContext.caption = { text: text, anchor: new MakerJs.paths.Line(leftAnchorPoint, rightAnchorPoint) };
|
1843 | return modelContext;
|
1844 | }
|
1845 | model.addCaption = addCaption;
|
1846 | |
1847 |
|
1848 |
|
1849 |
|
1850 |
|
1851 |
|
1852 |
|
1853 |
|
1854 |
|
1855 |
|
1856 |
|
1857 |
|
1858 |
|
1859 | function addPath(modelContext, pathContext, pathId, overWrite) {
|
1860 | if (overWrite === void 0) { overWrite = false; }
|
1861 | var id = overWrite ? pathId : getSimilarPathId(modelContext, pathId);
|
1862 | modelContext.paths = modelContext.paths || {};
|
1863 | modelContext.paths[id] = pathContext;
|
1864 | return modelContext;
|
1865 | }
|
1866 | model.addPath = addPath;
|
1867 | |
1868 |
|
1869 |
|
1870 |
|
1871 |
|
1872 |
|
1873 |
|
1874 |
|
1875 |
|
1876 |
|
1877 |
|
1878 |
|
1879 |
|
1880 | function addModel(parentModel, childModel, childModelId, overWrite) {
|
1881 | if (overWrite === void 0) { overWrite = false; }
|
1882 | var id = overWrite ? childModelId : getSimilarModelId(parentModel, childModelId);
|
1883 | parentModel.models = parentModel.models || {};
|
1884 | parentModel.models[id] = childModel;
|
1885 | return parentModel;
|
1886 | }
|
1887 | model.addModel = addModel;
|
1888 | |
1889 |
|
1890 |
|
1891 |
|
1892 |
|
1893 |
|
1894 |
|
1895 |
|
1896 |
|
1897 |
|
1898 |
|
1899 |
|
1900 |
|
1901 | function addTo(childModel, parentModel, childModelId, overWrite) {
|
1902 | if (overWrite === void 0) { overWrite = false; }
|
1903 | addModel(parentModel, childModel, childModelId, overWrite);
|
1904 | return childModel;
|
1905 | }
|
1906 | model.addTo = addTo;
|
1907 | |
1908 |
|
1909 |
|
1910 |
|
1911 |
|
1912 |
|
1913 | function clone(modelToClone) {
|
1914 | return MakerJs.cloneObject(modelToClone);
|
1915 | }
|
1916 | model.clone = clone;
|
1917 | |
1918 |
|
1919 |
|
1920 |
|
1921 |
|
1922 |
|
1923 | function countChildModels(modelContext) {
|
1924 | var count = 0;
|
1925 | if (modelContext.models) {
|
1926 | for (var id in modelContext.models) {
|
1927 | count++;
|
1928 | }
|
1929 | }
|
1930 | return count;
|
1931 | }
|
1932 | model.countChildModels = countChildModels;
|
1933 | |
1934 |
|
1935 |
|
1936 |
|
1937 |
|
1938 | function getAllCaptionsOffset(modelContext) {
|
1939 | var captions = [];
|
1940 | function tryAddCaption(m, offset) {
|
1941 | if (m.caption) {
|
1942 | captions.push({ text: m.caption.text, anchor: MakerJs.path.clone(m.caption.anchor, offset) });
|
1943 | }
|
1944 | }
|
1945 | tryAddCaption(modelContext, modelContext.origin);
|
1946 | model.walk(modelContext, {
|
1947 | afterChildWalk: function (wm) { return tryAddCaption(wm.childModel, wm.offset); }
|
1948 | });
|
1949 | return captions;
|
1950 | }
|
1951 | model.getAllCaptionsOffset = getAllCaptionsOffset;
|
1952 | |
1953 |
|
1954 |
|
1955 | function getSimilarId(map, id) {
|
1956 | if (!map)
|
1957 | return id;
|
1958 | var i = 0;
|
1959 | var newId = id;
|
1960 | while (newId in map) {
|
1961 | i++;
|
1962 | newId = [id, i].join('_');
|
1963 | }
|
1964 | return newId;
|
1965 | }
|
1966 | |
1967 |
|
1968 |
|
1969 |
|
1970 |
|
1971 |
|
1972 | function getSimilarModelId(modelContext, modelId) {
|
1973 | return getSimilarId(modelContext.models, modelId);
|
1974 | }
|
1975 | model.getSimilarModelId = getSimilarModelId;
|
1976 | |
1977 |
|
1978 |
|
1979 |
|
1980 |
|
1981 |
|
1982 | function getSimilarPathId(modelContext, pathId) {
|
1983 | return getSimilarId(modelContext.paths, pathId);
|
1984 | }
|
1985 | model.getSimilarPathId = getSimilarPathId;
|
1986 | |
1987 |
|
1988 |
|
1989 |
|
1990 |
|
1991 |
|
1992 |
|
1993 |
|
1994 |
|
1995 |
|
1996 | function layer(modelContext, layer) {
|
1997 | modelContext.layer = layer;
|
1998 | return modelContext;
|
1999 | }
|
2000 | model.layer = layer;
|
2001 | |
2002 |
|
2003 |
|
2004 |
|
2005 |
|
2006 |
|
2007 |
|
2008 | function originate(modelToOriginate, origin) {
|
2009 | function innerOriginate(m, o) {
|
2010 | if (!m)
|
2011 | return;
|
2012 | var newOrigin = MakerJs.point.add(m.origin, o);
|
2013 | if (m.type === MakerJs.models.BezierCurve.typeName) {
|
2014 | MakerJs.path.moveRelative(m.seed, newOrigin);
|
2015 | }
|
2016 | if (m.paths) {
|
2017 | for (var id in m.paths) {
|
2018 | MakerJs.path.moveRelative(m.paths[id], newOrigin);
|
2019 | }
|
2020 | }
|
2021 | if (m.models) {
|
2022 | for (var id in m.models) {
|
2023 | innerOriginate(m.models[id], newOrigin);
|
2024 | }
|
2025 | }
|
2026 | if (m.caption) {
|
2027 | MakerJs.path.moveRelative(m.caption.anchor, newOrigin);
|
2028 | }
|
2029 | m.origin = MakerJs.point.zero();
|
2030 | }
|
2031 | innerOriginate(modelToOriginate, origin ? MakerJs.point.subtract([0, 0], origin) : [0, 0]);
|
2032 | if (origin) {
|
2033 | modelToOriginate.origin = origin;
|
2034 | }
|
2035 | return modelToOriginate;
|
2036 | }
|
2037 | model.originate = originate;
|
2038 | |
2039 |
|
2040 |
|
2041 |
|
2042 |
|
2043 |
|
2044 |
|
2045 |
|
2046 | function center(modelToCenter, centerX, centerY) {
|
2047 | if (centerX === void 0) { centerX = true; }
|
2048 | if (centerY === void 0) { centerY = true; }
|
2049 | var m = MakerJs.measure.modelExtents(modelToCenter);
|
2050 | var o = modelToCenter.origin || [0, 0];
|
2051 | if (centerX)
|
2052 | o[0] -= m.center[0];
|
2053 | if (centerY)
|
2054 | o[1] -= m.center[1];
|
2055 | modelToCenter.origin = o;
|
2056 | return modelToCenter;
|
2057 | }
|
2058 | model.center = center;
|
2059 | |
2060 |
|
2061 |
|
2062 |
|
2063 |
|
2064 |
|
2065 |
|
2066 |
|
2067 | function mirror(modelToMirror, mirrorX, mirrorY) {
|
2068 | var newModel = {};
|
2069 | if (!modelToMirror)
|
2070 | return null;
|
2071 | if (modelToMirror.origin) {
|
2072 | newModel.origin = MakerJs.point.mirror(modelToMirror.origin, mirrorX, mirrorY);
|
2073 | }
|
2074 | if (modelToMirror.type) {
|
2075 | newModel.type = modelToMirror.type;
|
2076 | }
|
2077 | if ('layer' in modelToMirror) {
|
2078 | newModel.layer = modelToMirror.layer;
|
2079 | }
|
2080 | if (modelToMirror.units) {
|
2081 | newModel.units = modelToMirror.units;
|
2082 | }
|
2083 | if (modelToMirror.type === MakerJs.models.BezierCurve.typeName) {
|
2084 | newModel.type = MakerJs.models.BezierCurve.typeName;
|
2085 | newModel.seed = MakerJs.path.mirror(modelToMirror.seed, mirrorX, mirrorY);
|
2086 | }
|
2087 | if (modelToMirror.paths) {
|
2088 | newModel.paths = {};
|
2089 | for (var id in modelToMirror.paths) {
|
2090 | var pathToMirror = modelToMirror.paths[id];
|
2091 | if (!pathToMirror)
|
2092 | continue;
|
2093 | var pathMirrored = MakerJs.path.mirror(pathToMirror, mirrorX, mirrorY);
|
2094 | if (!pathMirrored)
|
2095 | continue;
|
2096 | newModel.paths[id] = pathMirrored;
|
2097 | }
|
2098 | }
|
2099 | if (modelToMirror.models) {
|
2100 | newModel.models = {};
|
2101 | for (var id in modelToMirror.models) {
|
2102 | var childModelToMirror = modelToMirror.models[id];
|
2103 | if (!childModelToMirror)
|
2104 | continue;
|
2105 | var childModelMirrored = mirror(childModelToMirror, mirrorX, mirrorY);
|
2106 | if (!childModelMirrored)
|
2107 | continue;
|
2108 | newModel.models[id] = childModelMirrored;
|
2109 | }
|
2110 | }
|
2111 | if (modelToMirror.caption) {
|
2112 | newModel.caption = MakerJs.cloneObject(modelToMirror.caption);
|
2113 | newModel.caption.anchor = MakerJs.path.mirror(modelToMirror.caption.anchor, mirrorX, mirrorY);
|
2114 | }
|
2115 | return newModel;
|
2116 | }
|
2117 | model.mirror = mirror;
|
2118 | |
2119 |
|
2120 |
|
2121 |
|
2122 |
|
2123 |
|
2124 |
|
2125 | function move(modelToMove, origin) {
|
2126 | modelToMove.origin = MakerJs.point.clone(origin);
|
2127 | return modelToMove;
|
2128 | }
|
2129 | model.move = move;
|
2130 | |
2131 |
|
2132 |
|
2133 |
|
2134 |
|
2135 |
|
2136 |
|
2137 | function moveRelative(modelToMove, delta) {
|
2138 | if (modelToMove) {
|
2139 | modelToMove.origin = MakerJs.point.add(modelToMove.origin || MakerJs.point.zero(), delta);
|
2140 | }
|
2141 | return modelToMove;
|
2142 | }
|
2143 | model.moveRelative = moveRelative;
|
2144 | |
2145 |
|
2146 |
|
2147 |
|
2148 |
|
2149 |
|
2150 |
|
2151 | function prefixPathIds(modelToPrefix, prefix) {
|
2152 | var walkedPaths = [];
|
2153 |
|
2154 | walk(modelToPrefix, {
|
2155 | onPath: function (walkedPath) {
|
2156 | walkedPaths.push(walkedPath);
|
2157 | }
|
2158 | });
|
2159 |
|
2160 | for (var i = 0; i < walkedPaths.length; i++) {
|
2161 | var walkedPath = walkedPaths[i];
|
2162 | delete walkedPath.modelContext.paths[walkedPath.pathId];
|
2163 | walkedPath.modelContext.paths[prefix + walkedPath.pathId] = walkedPath.pathContext;
|
2164 | }
|
2165 | return modelToPrefix;
|
2166 | }
|
2167 | model.prefixPathIds = prefixPathIds;
|
2168 | |
2169 |
|
2170 |
|
2171 |
|
2172 |
|
2173 |
|
2174 |
|
2175 |
|
2176 | function rotate(modelToRotate, angleInDegrees, rotationOrigin) {
|
2177 | if (rotationOrigin === void 0) { rotationOrigin = [0, 0]; }
|
2178 | if (!modelToRotate || !angleInDegrees)
|
2179 | return modelToRotate;
|
2180 | var offsetOrigin = MakerJs.point.subtract(rotationOrigin, modelToRotate.origin);
|
2181 | if (modelToRotate.type === MakerJs.models.BezierCurve.typeName) {
|
2182 | MakerJs.path.rotate(modelToRotate.seed, angleInDegrees, offsetOrigin);
|
2183 | }
|
2184 | if (modelToRotate.paths) {
|
2185 | for (var id in modelToRotate.paths) {
|
2186 | MakerJs.path.rotate(modelToRotate.paths[id], angleInDegrees, offsetOrigin);
|
2187 | }
|
2188 | }
|
2189 | if (modelToRotate.models) {
|
2190 | for (var id in modelToRotate.models) {
|
2191 | rotate(modelToRotate.models[id], angleInDegrees, offsetOrigin);
|
2192 | }
|
2193 | }
|
2194 | if (modelToRotate.caption) {
|
2195 | MakerJs.path.rotate(modelToRotate.caption.anchor, angleInDegrees, offsetOrigin);
|
2196 | }
|
2197 | return modelToRotate;
|
2198 | }
|
2199 | model.rotate = rotate;
|
2200 | |
2201 |
|
2202 |
|
2203 |
|
2204 |
|
2205 |
|
2206 |
|
2207 |
|
2208 | function scale(modelToScale, scaleValue, scaleOrigin) {
|
2209 | if (scaleOrigin === void 0) { scaleOrigin = false; }
|
2210 | if (scaleOrigin && modelToScale.origin) {
|
2211 | modelToScale.origin = MakerJs.point.scale(modelToScale.origin, scaleValue);
|
2212 | }
|
2213 | if (modelToScale.type === MakerJs.models.BezierCurve.typeName) {
|
2214 | MakerJs.path.scale(modelToScale.seed, scaleValue);
|
2215 | }
|
2216 | if (modelToScale.paths) {
|
2217 | for (var id in modelToScale.paths) {
|
2218 | MakerJs.path.scale(modelToScale.paths[id], scaleValue);
|
2219 | }
|
2220 | }
|
2221 | if (modelToScale.models) {
|
2222 | for (var id in modelToScale.models) {
|
2223 | scale(modelToScale.models[id], scaleValue, true);
|
2224 | }
|
2225 | }
|
2226 | if (modelToScale.caption) {
|
2227 | MakerJs.path.scale(modelToScale.caption.anchor, scaleValue);
|
2228 | }
|
2229 | return modelToScale;
|
2230 | }
|
2231 | model.scale = scale;
|
2232 | |
2233 |
|
2234 |
|
2235 | function addDistortedPath(parentModel, pathToDistort, pathId, layer, scaleX, scaleY, bezierAccuracy) {
|
2236 | var distortedPath = MakerJs.path.distort(pathToDistort, scaleX, scaleY);
|
2237 | layer = layer || pathToDistort.layer;
|
2238 | if (layer) {
|
2239 | distortedPath.layer = layer;
|
2240 | }
|
2241 | if (MakerJs.isPath(distortedPath)) {
|
2242 | if (distortedPath.type === MakerJs.pathType.BezierSeed) {
|
2243 | var curve = new MakerJs.models.BezierCurve(distortedPath, bezierAccuracy);
|
2244 | addModel(parentModel, curve, pathId);
|
2245 | }
|
2246 | else {
|
2247 | addPath(parentModel, distortedPath, pathId);
|
2248 | }
|
2249 | }
|
2250 | else {
|
2251 | addModel(parentModel, distortedPath, pathId);
|
2252 | }
|
2253 | }
|
2254 | |
2255 |
|
2256 |
|
2257 |
|
2258 |
|
2259 |
|
2260 |
|
2261 |
|
2262 |
|
2263 |
|
2264 | function distort(modelToDistort, scaleX, scaleY, scaleOrigin, bezierAccuracy) {
|
2265 | if (scaleOrigin === void 0) { scaleOrigin = false; }
|
2266 | var distorted = {};
|
2267 | if (modelToDistort.layer) {
|
2268 | distorted.layer = modelToDistort.layer;
|
2269 | }
|
2270 | if (scaleOrigin && modelToDistort.origin) {
|
2271 | distorted.origin = MakerJs.point.distort(modelToDistort.origin, scaleX, scaleY);
|
2272 | }
|
2273 | if (modelToDistort.type === MakerJs.models.BezierCurve.typeName) {
|
2274 | var b = modelToDistort;
|
2275 | var bezierPartsByLayer = MakerJs.models.BezierCurve.getBezierSeeds(b, { byLayers: true });
|
2276 | var _loop_1 = function (layer_1) {
|
2277 | var pathArray = bezierPartsByLayer[layer_1];
|
2278 | pathArray.forEach(function (p, i) {
|
2279 | addDistortedPath(distorted, p, i.toString(), layer_1, scaleX, scaleY, bezierAccuracy);
|
2280 | });
|
2281 | };
|
2282 | for (var layer_1 in bezierPartsByLayer) {
|
2283 | _loop_1(layer_1);
|
2284 | }
|
2285 | }
|
2286 | else if (modelToDistort.paths) {
|
2287 | for (var pathId in modelToDistort.paths) {
|
2288 | var pathToDistort = modelToDistort.paths[pathId];
|
2289 | addDistortedPath(distorted, pathToDistort, pathId, null, scaleX, scaleY, bezierAccuracy);
|
2290 | }
|
2291 | }
|
2292 | if (modelToDistort.models) {
|
2293 | for (var childId in modelToDistort.models) {
|
2294 | var childModel = modelToDistort.models[childId];
|
2295 | var distortedChild = distort(childModel, scaleX, scaleY, true, bezierAccuracy);
|
2296 | addModel(distorted, distortedChild, childId);
|
2297 | }
|
2298 | }
|
2299 | if (modelToDistort.caption) {
|
2300 | distorted.caption = MakerJs.cloneObject(modelToDistort.caption);
|
2301 | distorted.caption.anchor = MakerJs.path.distort(modelToDistort.caption.anchor, scaleX, scaleY);
|
2302 | }
|
2303 | return distorted;
|
2304 | }
|
2305 | model.distort = distort;
|
2306 | |
2307 |
|
2308 |
|
2309 |
|
2310 |
|
2311 |
|
2312 |
|
2313 | function convertUnits(modeltoConvert, destUnitType) {
|
2314 | if (modeltoConvert.units && MakerJs.units.isValidUnit(modeltoConvert.units) && MakerJs.units.isValidUnit(destUnitType)) {
|
2315 | var ratio = MakerJs.units.conversionScale(modeltoConvert.units, destUnitType);
|
2316 | if (ratio != 1) {
|
2317 | scale(modeltoConvert, ratio);
|
2318 |
|
2319 | modeltoConvert.units = destUnitType;
|
2320 | }
|
2321 | }
|
2322 | return modeltoConvert;
|
2323 | }
|
2324 | model.convertUnits = convertUnits;
|
2325 | |
2326 |
|
2327 |
|
2328 |
|
2329 |
|
2330 |
|
2331 |
|
2332 | function walkPaths(modelContext, callback) {
|
2333 | if (modelContext.paths) {
|
2334 | for (var pathId in modelContext.paths) {
|
2335 | if (!modelContext.paths[pathId])
|
2336 | continue;
|
2337 | callback(modelContext, pathId, modelContext.paths[pathId]);
|
2338 | }
|
2339 | }
|
2340 | if (modelContext.models) {
|
2341 | for (var id in modelContext.models) {
|
2342 | if (!modelContext.models[id])
|
2343 | continue;
|
2344 | walkPaths(modelContext.models[id], callback);
|
2345 | }
|
2346 | }
|
2347 | }
|
2348 | model.walkPaths = walkPaths;
|
2349 | |
2350 |
|
2351 |
|
2352 |
|
2353 |
|
2354 |
|
2355 |
|
2356 | function walk(modelContext, options) {
|
2357 | if (!modelContext)
|
2358 | return;
|
2359 | function walkRecursive(modelContext, layer, offset, route, routeKey) {
|
2360 | var newOffset = MakerJs.point.add(modelContext.origin, offset);
|
2361 | layer = (layer != undefined) ? layer : '';
|
2362 | if (modelContext.paths) {
|
2363 | for (var pathId in modelContext.paths) {
|
2364 | var pathContext = modelContext.paths[pathId];
|
2365 | if (!pathContext)
|
2366 | continue;
|
2367 | var walkedPath = {
|
2368 | modelContext: modelContext,
|
2369 | layer: (pathContext.layer != undefined) ? pathContext.layer : layer,
|
2370 | offset: newOffset,
|
2371 | pathContext: pathContext,
|
2372 | pathId: pathId,
|
2373 | route: route.concat(['paths', pathId]),
|
2374 | routeKey: routeKey + (routeKey ? '.' : '') + 'paths' + JSON.stringify([pathId])
|
2375 | };
|
2376 | if (options.onPath)
|
2377 | options.onPath(walkedPath);
|
2378 | }
|
2379 | }
|
2380 | if (modelContext.models) {
|
2381 | for (var modelId in modelContext.models) {
|
2382 | var childModel = modelContext.models[modelId];
|
2383 | if (!childModel)
|
2384 | continue;
|
2385 | var walkedModel = {
|
2386 | parentModel: modelContext,
|
2387 | layer: (childModel.layer != undefined) ? childModel.layer : layer,
|
2388 | offset: newOffset,
|
2389 | route: route.concat(['models', modelId]),
|
2390 | routeKey: routeKey + (routeKey ? '.' : '') + 'models' + JSON.stringify([modelId]),
|
2391 | childId: modelId,
|
2392 | childModel: childModel
|
2393 | };
|
2394 | if (options.beforeChildWalk) {
|
2395 | if (!options.beforeChildWalk(walkedModel))
|
2396 | continue;
|
2397 | }
|
2398 | walkRecursive(walkedModel.childModel, walkedModel.layer, newOffset, walkedModel.route, walkedModel.routeKey);
|
2399 | if (options.afterChildWalk) {
|
2400 | options.afterChildWalk(walkedModel);
|
2401 | }
|
2402 | }
|
2403 | }
|
2404 | }
|
2405 | walkRecursive(modelContext, modelContext.layer, [0, 0], [], '');
|
2406 | return modelContext;
|
2407 | }
|
2408 | model.walk = walk;
|
2409 | |
2410 |
|
2411 |
|
2412 |
|
2413 |
|
2414 |
|
2415 |
|
2416 |
|
2417 | function zero(modelToZero, zeroX, zeroY) {
|
2418 | if (zeroX === void 0) { zeroX = true; }
|
2419 | if (zeroY === void 0) { zeroY = true; }
|
2420 | var m = MakerJs.measure.modelExtents(modelToZero);
|
2421 | var z = modelToZero.origin || [0, 0];
|
2422 | if (zeroX)
|
2423 | z[0] -= m.low[0];
|
2424 | if (zeroY)
|
2425 | z[1] -= m.low[1];
|
2426 | modelToZero.origin = z;
|
2427 | return modelToZero;
|
2428 | }
|
2429 | model.zero = zero;
|
2430 | })(model = MakerJs.model || (MakerJs.model = {}));
|
2431 | })(MakerJs || (MakerJs = {}));
|
2432 | var MakerJs;
|
2433 | (function (MakerJs) {
|
2434 | var model;
|
2435 | (function (model) {
|
2436 | |
2437 |
|
2438 |
|
2439 | function getNonZeroSegments(pathToSegment, breakPoint) {
|
2440 | var segment1 = MakerJs.cloneObject(pathToSegment);
|
2441 | if (!segment1)
|
2442 | return null;
|
2443 | var segment2 = MakerJs.path.breakAtPoint(segment1, breakPoint);
|
2444 | if (segment2) {
|
2445 | var segments = [segment1, segment2];
|
2446 | for (var i = 2; i--;) {
|
2447 | if (MakerJs.round(MakerJs.measure.pathLength(segments[i]), .0001) == 0) {
|
2448 | return null;
|
2449 | }
|
2450 | }
|
2451 | return segments;
|
2452 | }
|
2453 | else if (pathToSegment.type == MakerJs.pathType.Circle) {
|
2454 | return [segment1];
|
2455 | }
|
2456 | return null;
|
2457 | }
|
2458 | |
2459 |
|
2460 |
|
2461 | function getPointsOnPath(points, onPath, popOptions) {
|
2462 | var endpointsOnPath = [];
|
2463 | points.forEach(function (p) {
|
2464 | if (MakerJs.measure.isPointOnPath(p, onPath, .00001, null, popOptions)) {
|
2465 | endpointsOnPath.push(p);
|
2466 | }
|
2467 | });
|
2468 | return endpointsOnPath;
|
2469 | }
|
2470 | |
2471 |
|
2472 |
|
2473 | function breakAlongForeignPath(crossedPath, overlappedSegments, foreignWalkedPath) {
|
2474 | var foreignPath = foreignWalkedPath.pathContext;
|
2475 | var segments = crossedPath.segments;
|
2476 | if (MakerJs.measure.isPathEqual(segments[0].absolutePath, foreignPath, .0001, null, foreignWalkedPath.offset)) {
|
2477 | segments[0].overlapped = true;
|
2478 | segments[0].duplicate = true;
|
2479 | overlappedSegments.push(segments[0]);
|
2480 | return;
|
2481 | }
|
2482 |
|
2483 | var popOptions = {};
|
2484 | var options = { path1Offset: crossedPath.offset, path2Offset: foreignWalkedPath.offset };
|
2485 | var foreignIntersection = MakerJs.path.intersection(crossedPath.pathContext, foreignPath, options);
|
2486 | var intersectionPoints = foreignIntersection ? foreignIntersection.intersectionPoints : null;
|
2487 | var foreignPathEndPoints = MakerJs.point.fromPathEnds(foreignPath, foreignWalkedPath.offset) || [];
|
2488 | for (var i = 0; i < segments.length; i++) {
|
2489 | var pointsOfInterest = intersectionPoints ? foreignPathEndPoints.concat(intersectionPoints) : foreignPathEndPoints;
|
2490 | var pointsToCheck = getPointsOnPath(pointsOfInterest, segments[i].absolutePath, popOptions);
|
2491 | if (options.out_AreOverlapped) {
|
2492 | segments[i].overlapped = true;
|
2493 | overlappedSegments.push(segments[i]);
|
2494 | }
|
2495 | if (pointsToCheck.length > 0) {
|
2496 |
|
2497 | var subSegments = null;
|
2498 | var p = 0;
|
2499 | while (!subSegments && p < pointsToCheck.length) {
|
2500 | subSegments = getNonZeroSegments(segments[i].absolutePath, pointsToCheck[p]);
|
2501 | p++;
|
2502 | }
|
2503 | if (subSegments) {
|
2504 | crossedPath.broken = true;
|
2505 | segments[i].absolutePath = subSegments[0];
|
2506 | if (subSegments[1]) {
|
2507 | var newSegment = {
|
2508 | absolutePath: subSegments[1],
|
2509 | pathId: segments[0].pathId,
|
2510 | overlapped: segments[i].overlapped,
|
2511 | uniqueForeignIntersectionPoints: []
|
2512 | };
|
2513 | if (segments[i].overlapped) {
|
2514 | overlappedSegments.push(newSegment);
|
2515 | }
|
2516 | segments.push(newSegment);
|
2517 | }
|
2518 |
|
2519 | i--;
|
2520 | }
|
2521 | }
|
2522 | }
|
2523 | }
|
2524 | |
2525 |
|
2526 |
|
2527 |
|
2528 |
|
2529 |
|
2530 |
|
2531 |
|
2532 |
|
2533 | function isPathInsideModel(pathContext, modelContext, pathOffset, farPoint, measureAtlas) {
|
2534 | var options = {
|
2535 | farPoint: farPoint,
|
2536 | measureAtlas: measureAtlas
|
2537 | };
|
2538 | var p = MakerJs.point.add(MakerJs.point.middle(pathContext), pathOffset);
|
2539 | return MakerJs.measure.isPointInsideModel(p, modelContext, options);
|
2540 | }
|
2541 | model.isPathInsideModel = isPathInsideModel;
|
2542 | |
2543 |
|
2544 |
|
2545 |
|
2546 |
|
2547 |
|
2548 |
|
2549 |
|
2550 | function breakPathsAtIntersections(modelToBreak, modelToIntersect) {
|
2551 | var modelToBreakAtlas = new MakerJs.measure.Atlas(modelToBreak);
|
2552 | modelToBreakAtlas.measureModels();
|
2553 | var modelToIntersectAtlas;
|
2554 | if (!modelToIntersect) {
|
2555 | modelToIntersect = modelToBreak;
|
2556 | modelToIntersectAtlas = modelToBreakAtlas;
|
2557 | }
|
2558 | else {
|
2559 | modelToIntersectAtlas = new MakerJs.measure.Atlas(modelToIntersect);
|
2560 | modelToIntersectAtlas.measureModels();
|
2561 | }
|
2562 | ;
|
2563 | breakAllPathsAtIntersections(modelToBreak, modelToIntersect || modelToBreak, false, modelToBreakAtlas, modelToIntersectAtlas);
|
2564 | return modelToBreak;
|
2565 | }
|
2566 | model.breakPathsAtIntersections = breakPathsAtIntersections;
|
2567 | |
2568 |
|
2569 |
|
2570 | function breakAllPathsAtIntersections(modelToBreak, modelToIntersect, checkIsInside, modelToBreakAtlas, modelToIntersectAtlas, farPoint) {
|
2571 | var crossedPaths = [];
|
2572 | var overlappedSegments = [];
|
2573 | var walkModelToBreakOptions = {
|
2574 | onPath: function (outerWalkedPath) {
|
2575 |
|
2576 | var segment = {
|
2577 | absolutePath: MakerJs.path.clone(outerWalkedPath.pathContext, outerWalkedPath.offset),
|
2578 | pathId: outerWalkedPath.pathId,
|
2579 | overlapped: false,
|
2580 | uniqueForeignIntersectionPoints: []
|
2581 | };
|
2582 | var thisPath = outerWalkedPath;
|
2583 | thisPath.broken = false;
|
2584 | thisPath.segments = [segment];
|
2585 | var walkModelToIntersectOptions = {
|
2586 | onPath: function (innerWalkedPath) {
|
2587 | if (outerWalkedPath.pathContext !== innerWalkedPath.pathContext && MakerJs.measure.isMeasurementOverlapping(modelToBreakAtlas.pathMap[outerWalkedPath.routeKey], modelToIntersectAtlas.pathMap[innerWalkedPath.routeKey])) {
|
2588 | breakAlongForeignPath(thisPath, overlappedSegments, innerWalkedPath);
|
2589 | }
|
2590 | },
|
2591 | beforeChildWalk: function (innerWalkedModel) {
|
2592 |
|
2593 | var innerModelMeasurement = modelToIntersectAtlas.modelMap[innerWalkedModel.routeKey];
|
2594 | return innerModelMeasurement && MakerJs.measure.isMeasurementOverlapping(modelToBreakAtlas.pathMap[outerWalkedPath.routeKey], innerModelMeasurement);
|
2595 | }
|
2596 | };
|
2597 |
|
2598 | model.walk(modelToIntersect, walkModelToIntersectOptions);
|
2599 | if (checkIsInside) {
|
2600 |
|
2601 | for (var i = 0; i < thisPath.segments.length; i++) {
|
2602 | var p = MakerJs.point.middle(thisPath.segments[i].absolutePath);
|
2603 | var pointInsideOptions = { measureAtlas: modelToIntersectAtlas, farPoint: farPoint };
|
2604 | thisPath.segments[i].isInside = MakerJs.measure.isPointInsideModel(p, modelToIntersect, pointInsideOptions);
|
2605 | thisPath.segments[i].uniqueForeignIntersectionPoints = pointInsideOptions.out_intersectionPoints;
|
2606 | }
|
2607 | }
|
2608 | crossedPaths.push(thisPath);
|
2609 | }
|
2610 | };
|
2611 | model.walk(modelToBreak, walkModelToBreakOptions);
|
2612 | return { crossedPaths: crossedPaths, overlappedSegments: overlappedSegments };
|
2613 | }
|
2614 | |
2615 |
|
2616 |
|
2617 | function checkForEqualOverlaps(crossedPathsA, crossedPathsB, pointMatchingDistance) {
|
2618 | function compareSegments(segment1, segment2) {
|
2619 | if (MakerJs.measure.isPathEqual(segment1.absolutePath, segment2.absolutePath, pointMatchingDistance)) {
|
2620 | segment1.duplicate = segment2.duplicate = true;
|
2621 | }
|
2622 | }
|
2623 | function compareAll(segment) {
|
2624 | for (var i = 0; i < crossedPathsB.length; i++) {
|
2625 | compareSegments(crossedPathsB[i], segment);
|
2626 | }
|
2627 | }
|
2628 | for (var i = 0; i < crossedPathsA.length; i++) {
|
2629 | compareAll(crossedPathsA[i]);
|
2630 | }
|
2631 | }
|
2632 | |
2633 |
|
2634 |
|
2635 | function addOrDeleteSegments(crossedPath, includeInside, includeOutside, keepDuplicates, atlas, trackDeleted) {
|
2636 | function addSegment(modelContext, pathIdBase, segment) {
|
2637 | var id = model.getSimilarPathId(modelContext, pathIdBase);
|
2638 | var newRouteKey = (id == pathIdBase) ? crossedPath.routeKey : MakerJs.createRouteKey(crossedPath.route.slice(0, -1).concat([id]));
|
2639 | segment.addedPath = MakerJs.cloneObject(crossedPath.pathContext);
|
2640 |
|
2641 | segment.addedPath.type = segment.absolutePath.type;
|
2642 | MakerJs.path.copyProps(segment.absolutePath, segment.addedPath);
|
2643 | MakerJs.path.moveRelative(segment.addedPath, crossedPath.offset, true);
|
2644 | modelContext.paths[id] = segment.addedPath;
|
2645 | if (crossedPath.broken) {
|
2646 |
|
2647 | var measurement = MakerJs.measure.pathExtents(segment.absolutePath);
|
2648 | atlas.pathMap[newRouteKey] = measurement;
|
2649 | atlas.modelsMeasured = false;
|
2650 | }
|
2651 | else {
|
2652 |
|
2653 | atlas.pathMap[newRouteKey] = savedMeasurement;
|
2654 | }
|
2655 | }
|
2656 | function checkAddSegment(modelContext, pathIdBase, segment) {
|
2657 | if (segment.isInside && includeInside || !segment.isInside && includeOutside) {
|
2658 | addSegment(modelContext, pathIdBase, segment);
|
2659 | }
|
2660 | else {
|
2661 | atlas.modelsMeasured = false;
|
2662 | trackDeleted(segment.absolutePath, crossedPath.routeKey, 'segment is ' + (segment.isInside ? 'inside' : 'outside') + ' intersectionPoints=' + JSON.stringify(segment.uniqueForeignIntersectionPoints));
|
2663 | }
|
2664 | }
|
2665 |
|
2666 | var savedMeasurement = atlas.pathMap[crossedPath.routeKey];
|
2667 |
|
2668 | delete crossedPath.modelContext.paths[crossedPath.pathId];
|
2669 | delete atlas.pathMap[crossedPath.routeKey];
|
2670 | for (var i = 0; i < crossedPath.segments.length; i++) {
|
2671 | if (crossedPath.segments[i].duplicate) {
|
2672 | if (keepDuplicates) {
|
2673 | addSegment(crossedPath.modelContext, crossedPath.pathId, crossedPath.segments[i]);
|
2674 | }
|
2675 | else {
|
2676 | trackDeleted(crossedPath.segments[i].absolutePath, crossedPath.routeKey, 'segment is duplicate');
|
2677 | }
|
2678 | }
|
2679 | else {
|
2680 | checkAddSegment(crossedPath.modelContext, crossedPath.pathId, crossedPath.segments[i]);
|
2681 | }
|
2682 | }
|
2683 | }
|
2684 | |
2685 |
|
2686 |
|
2687 |
|
2688 |
|
2689 |
|
2690 |
|
2691 |
|
2692 |
|
2693 |
|
2694 |
|
2695 |
|
2696 | function combine(modelA, modelB, includeAInsideB, includeAOutsideB, includeBInsideA, includeBOutsideA, options) {
|
2697 | if (includeAInsideB === void 0) { includeAInsideB = false; }
|
2698 | if (includeAOutsideB === void 0) { includeAOutsideB = true; }
|
2699 | if (includeBInsideA === void 0) { includeBInsideA = false; }
|
2700 | if (includeBOutsideA === void 0) { includeBOutsideA = true; }
|
2701 | var opts = {
|
2702 | trimDeadEnds: true,
|
2703 | pointMatchingDistance: .005,
|
2704 | out_deleted: [{ paths: {} }, { paths: {} }]
|
2705 | };
|
2706 | MakerJs.extendObject(opts, options);
|
2707 | opts.measureA = opts.measureA || new MakerJs.measure.Atlas(modelA);
|
2708 | opts.measureB = opts.measureB || new MakerJs.measure.Atlas(modelB);
|
2709 |
|
2710 | opts.measureA.measureModels();
|
2711 | opts.measureB.measureModels();
|
2712 | if (!opts.farPoint) {
|
2713 | var measureBoth = MakerJs.measure.increase(MakerJs.measure.increase({ high: [null, null], low: [null, null] }, opts.measureA.modelMap['']), opts.measureB.modelMap['']);
|
2714 | opts.farPoint = MakerJs.point.add(measureBoth.high, [1, 1]);
|
2715 | }
|
2716 | var pathsA = breakAllPathsAtIntersections(modelA, modelB, true, opts.measureA, opts.measureB, opts.farPoint);
|
2717 | var pathsB = breakAllPathsAtIntersections(modelB, modelA, true, opts.measureB, opts.measureA, opts.farPoint);
|
2718 | checkForEqualOverlaps(pathsA.overlappedSegments, pathsB.overlappedSegments, opts.pointMatchingDistance);
|
2719 | function trackDeleted(which, deletedPath, routeKey, reason) {
|
2720 | model.addPath(opts.out_deleted[which], deletedPath, 'deleted');
|
2721 | var p = deletedPath;
|
2722 | p.reason = reason;
|
2723 | p.routeKey = routeKey;
|
2724 | }
|
2725 | for (var i = 0; i < pathsA.crossedPaths.length; i++) {
|
2726 | addOrDeleteSegments(pathsA.crossedPaths[i], includeAInsideB, includeAOutsideB, true, opts.measureA, function (p, id, reason) { return trackDeleted(0, p, id, reason); });
|
2727 | }
|
2728 | for (var i = 0; i < pathsB.crossedPaths.length; i++) {
|
2729 | addOrDeleteSegments(pathsB.crossedPaths[i], includeBInsideA, includeBOutsideA, false, opts.measureB, function (p, id, reason) { return trackDeleted(1, p, id, reason); });
|
2730 | }
|
2731 | var result = { models: { a: modelA, b: modelB } };
|
2732 | if (opts.trimDeadEnds) {
|
2733 | var shouldKeep;
|
2734 |
|
2735 | if (!includeAInsideB && !includeBInsideA) {
|
2736 | shouldKeep = function (walkedPath) {
|
2737 |
|
2738 |
|
2739 | for (var i = 0; i < pathsA.overlappedSegments.length; i++) {
|
2740 | if (pathsA.overlappedSegments[i].duplicate && walkedPath.pathContext === pathsA.overlappedSegments[i].addedPath) {
|
2741 | return false;
|
2742 | }
|
2743 | }
|
2744 |
|
2745 | return true;
|
2746 | };
|
2747 | }
|
2748 | model.removeDeadEnds(result, null, shouldKeep, function (wp, reason) {
|
2749 | var which = wp.route[1] === 'a' ? 0 : 1;
|
2750 | trackDeleted(which, wp.pathContext, wp.routeKey, reason);
|
2751 | });
|
2752 | }
|
2753 |
|
2754 | MakerJs.extendObject(options, opts);
|
2755 | return result;
|
2756 | }
|
2757 | model.combine = combine;
|
2758 | |
2759 |
|
2760 |
|
2761 |
|
2762 |
|
2763 |
|
2764 |
|
2765 | function combineIntersection(modelA, modelB) {
|
2766 | return combine(modelA, modelB, true, false, true, false);
|
2767 | }
|
2768 | model.combineIntersection = combineIntersection;
|
2769 | |
2770 |
|
2771 |
|
2772 |
|
2773 |
|
2774 |
|
2775 |
|
2776 | function combineSubtraction(modelA, modelB) {
|
2777 | return combine(modelA, modelB, false, true, true, false);
|
2778 | }
|
2779 | model.combineSubtraction = combineSubtraction;
|
2780 | |
2781 |
|
2782 |
|
2783 |
|
2784 |
|
2785 |
|
2786 |
|
2787 | function combineUnion(modelA, modelB) {
|
2788 | return combine(modelA, modelB, false, true, false, true);
|
2789 | }
|
2790 | model.combineUnion = combineUnion;
|
2791 | })(model = MakerJs.model || (MakerJs.model = {}));
|
2792 | })(MakerJs || (MakerJs = {}));
|
2793 | var MakerJs;
|
2794 | (function (MakerJs) {
|
2795 | |
2796 |
|
2797 |
|
2798 | var Collector = (function () {
|
2799 | function Collector(comparer) {
|
2800 | this.comparer = comparer;
|
2801 | this.collections = [];
|
2802 | }
|
2803 | Collector.prototype.addItemToCollection = function (key, item) {
|
2804 | var found = this.findCollection(key);
|
2805 | if (found) {
|
2806 | found.push(item);
|
2807 | }
|
2808 | else {
|
2809 | var collection = { key: key, items: [item] };
|
2810 | this.collections.push(collection);
|
2811 | }
|
2812 | };
|
2813 | Collector.prototype.findCollection = function (key, action) {
|
2814 | for (var i = 0; i < this.collections.length; i++) {
|
2815 | var collection = this.collections[i];
|
2816 | if (this.comparer(key, collection.key)) {
|
2817 | if (action) {
|
2818 | action(i);
|
2819 | }
|
2820 | return collection.items;
|
2821 | }
|
2822 | }
|
2823 | return null;
|
2824 | };
|
2825 | Collector.prototype.removeCollection = function (key) {
|
2826 | var _this = this;
|
2827 | if (this.findCollection(key, function (index) { _this.collections.splice(index, 1); })) {
|
2828 | return true;
|
2829 | }
|
2830 | return false;
|
2831 | };
|
2832 | Collector.prototype.removeItemFromCollection = function (key, item) {
|
2833 | var collection = this.findCollection(key);
|
2834 | if (!collection)
|
2835 | return;
|
2836 | for (var i = 0; i < collection.length; i++) {
|
2837 | if (collection[i] === item) {
|
2838 | collection.splice(i, 1);
|
2839 | return true;
|
2840 | }
|
2841 | }
|
2842 | return false;
|
2843 | };
|
2844 | Collector.prototype.getCollectionsOfMultiple = function (cb) {
|
2845 | for (var i = 0; i < this.collections.length; i++) {
|
2846 | var collection = this.collections[i];
|
2847 | if (collection.items.length > 1) {
|
2848 | cb(collection.key, collection.items);
|
2849 | }
|
2850 | }
|
2851 | };
|
2852 | return Collector;
|
2853 | }());
|
2854 | MakerJs.Collector = Collector;
|
2855 | |
2856 |
|
2857 |
|
2858 | var _kdbush = require('kdbush');
|
2859 | |
2860 |
|
2861 |
|
2862 | var kdbush = (_kdbush["default"] || _kdbush);
|
2863 | |
2864 |
|
2865 |
|
2866 | var PointGraph = (function () {
|
2867 | function PointGraph() {
|
2868 | this.reset();
|
2869 | }
|
2870 | |
2871 |
|
2872 |
|
2873 | PointGraph.prototype.reset = function () {
|
2874 | this.insertedCount = 0;
|
2875 | this.graph = {};
|
2876 | this.index = {};
|
2877 | this.merged = {};
|
2878 | this.values = [];
|
2879 | };
|
2880 | |
2881 |
|
2882 |
|
2883 |
|
2884 |
|
2885 | PointGraph.prototype.insertValue = function (value) {
|
2886 | this.values.push(value);
|
2887 | return this.values.length - 1;
|
2888 | };
|
2889 | |
2890 |
|
2891 |
|
2892 |
|
2893 |
|
2894 | PointGraph.prototype.insertValueIdAtPoint = function (valueId, p) {
|
2895 | var x = p[0], y = p[1];
|
2896 | if (!this.graph[x]) {
|
2897 | this.graph[x] = {};
|
2898 | }
|
2899 | var pgx = this.graph[x];
|
2900 | var existed = (y in pgx);
|
2901 | var el;
|
2902 | var pointId;
|
2903 | if (!existed) {
|
2904 | pgx[y] = pointId = this.insertedCount++;
|
2905 | el = {
|
2906 | pointId: pointId,
|
2907 | point: p,
|
2908 | valueIds: [valueId]
|
2909 | };
|
2910 | this.index[pointId] = el;
|
2911 | }
|
2912 | else {
|
2913 | pointId = pgx[y];
|
2914 | if (pointId in this.merged) {
|
2915 | pointId = this.merged[pointId];
|
2916 | }
|
2917 | el = this.index[pointId];
|
2918 | el.valueIds.push(valueId);
|
2919 | }
|
2920 | return { existed: existed, pointId: pointId };
|
2921 | };
|
2922 | |
2923 |
|
2924 |
|
2925 |
|
2926 | PointGraph.prototype.mergePoints = function (withinDistance) {
|
2927 | var _this = this;
|
2928 | var points = [];
|
2929 | var kEls = [];
|
2930 | for (var pointId in this.index) {
|
2931 | var el = this.index[pointId];
|
2932 | var p = el.point;
|
2933 | el.kdId = points.length;
|
2934 | points.push(p);
|
2935 | kEls.push(el);
|
2936 | }
|
2937 | this.kdbush = kdbush(points);
|
2938 | var _loop_2 = function (pointId) {
|
2939 | if (pointId in this_1.merged)
|
2940 | return "continue";
|
2941 | var el = this_1.index[pointId];
|
2942 | var mergeIds = this_1.kdbush.within(el.point[0], el.point[1], withinDistance);
|
2943 | mergeIds.forEach(function (kdId) {
|
2944 | if (kdId === el.kdId)
|
2945 | return;
|
2946 | _this.mergeIndexElements(el, kEls[kdId]);
|
2947 | });
|
2948 | };
|
2949 | var this_1 = this;
|
2950 | for (var pointId in this.index) {
|
2951 | _loop_2(pointId);
|
2952 | }
|
2953 | };
|
2954 | |
2955 |
|
2956 |
|
2957 |
|
2958 |
|
2959 | PointGraph.prototype.mergeNearestSinglePoints = function (withinDistance) {
|
2960 | var _this = this;
|
2961 | var singles = [];
|
2962 | for (var pointId in this.index) {
|
2963 | var el = this.index[pointId];
|
2964 | if (el.valueIds.length === 1) {
|
2965 | singles.push(el);
|
2966 | }
|
2967 | }
|
2968 | this.kdbush = kdbush(singles.map(function (el) { return el.point; }));
|
2969 | singles.forEach(function (el) {
|
2970 | if (el.pointId in _this.merged)
|
2971 | return;
|
2972 | var mergeIds = _this.kdbush.within(el.point[0], el.point[1], withinDistance);
|
2973 | var byDistance = [];
|
2974 | mergeIds.forEach(function (i) {
|
2975 | var other = singles[i];
|
2976 | if (other.pointId === el.pointId)
|
2977 | return;
|
2978 | byDistance.push({ el: other, distance: MakerJs.measure.pointDistance(other.point, el.point) });
|
2979 | });
|
2980 | byDistance.sort(function (a, b) { return a.distance - b.distance; });
|
2981 | for (var i = 0; i < byDistance.length; i++) {
|
2982 | var other = byDistance[i].el;
|
2983 | if (other.pointId in _this.merged)
|
2984 | continue;
|
2985 | if (other.merged && other.merged.length > 0) {
|
2986 | _this.mergeIndexElements(other, el);
|
2987 | }
|
2988 | else {
|
2989 | _this.mergeIndexElements(el, other);
|
2990 | }
|
2991 | return;
|
2992 | }
|
2993 | });
|
2994 | };
|
2995 | PointGraph.prototype.mergeIndexElements = function (keep, remove) {
|
2996 | keep.merged = keep.merged || [];
|
2997 | keep.merged.push(remove.pointId);
|
2998 | this.merged[remove.pointId] = keep.pointId;
|
2999 | keep.valueIds.push.apply(keep.valueIds, remove.valueIds);
|
3000 | delete this.index[remove.pointId];
|
3001 | return keep.pointId;
|
3002 | };
|
3003 | |
3004 |
|
3005 |
|
3006 |
|
3007 | PointGraph.prototype.forEachPoint = function (cb) {
|
3008 | var _this = this;
|
3009 | for (var pointId = 0; pointId < this.insertedCount; pointId++) {
|
3010 | var el = this.index[pointId];
|
3011 | if (!el)
|
3012 | continue;
|
3013 | var length_1 = el.valueIds.length;
|
3014 | if (length_1 > 0) {
|
3015 | cb(el.point, el.valueIds.map(function (i) { return _this.values[i]; }), pointId, el);
|
3016 | }
|
3017 | }
|
3018 | };
|
3019 | |
3020 |
|
3021 |
|
3022 |
|
3023 | PointGraph.prototype.getIdOfPoint = function (p) {
|
3024 | var px = this.graph[p[0]];
|
3025 | if (px) {
|
3026 | var pointId = px[p[1]];
|
3027 | if (pointId >= 0) {
|
3028 | if (pointId in this.merged) {
|
3029 | return this.merged[pointId];
|
3030 | }
|
3031 | else {
|
3032 | return pointId;
|
3033 | }
|
3034 | }
|
3035 | }
|
3036 | };
|
3037 | |
3038 |
|
3039 |
|
3040 |
|
3041 | PointGraph.prototype.getElementAtPoint = function (p) {
|
3042 | var pointId = this.getIdOfPoint(p);
|
3043 | if (pointId >= 0) {
|
3044 | return this.index[pointId];
|
3045 | }
|
3046 | };
|
3047 | return PointGraph;
|
3048 | }());
|
3049 | MakerJs.PointGraph = PointGraph;
|
3050 | })(MakerJs || (MakerJs = {}));
|
3051 | var MakerJs;
|
3052 | (function (MakerJs) {
|
3053 | var model;
|
3054 | (function (model) {
|
3055 | |
3056 |
|
3057 |
|
3058 | function checkForOverlaps(refPaths, isOverlapping, overlapUnion) {
|
3059 | var currIndex = 0;
|
3060 | do {
|
3061 | var root = refPaths[currIndex];
|
3062 | do {
|
3063 | var overlaps = false;
|
3064 | for (var i = currIndex + 1; i < refPaths.length; i++) {
|
3065 | var arcRef = refPaths[i];
|
3066 | overlaps = isOverlapping(root.pathContext, arcRef.pathContext, false);
|
3067 | if (overlaps) {
|
3068 | overlapUnion(root.pathContext, arcRef.pathContext);
|
3069 | delete arcRef.modelContext.paths[arcRef.pathId];
|
3070 | refPaths.splice(i, 1);
|
3071 | break;
|
3072 | }
|
3073 | }
|
3074 | } while (overlaps);
|
3075 | currIndex++;
|
3076 | } while (currIndex < refPaths.length);
|
3077 | }
|
3078 | |
3079 |
|
3080 |
|
3081 |
|
3082 |
|
3083 |
|
3084 |
|
3085 | function simplify(modelToSimplify, options) {
|
3086 | function compareCircles(circleA, circleB) {
|
3087 | if (Math.abs(circleA.radius - circleB.radius) <= opts.scalarMatchingDistance) {
|
3088 | var distance = MakerJs.measure.pointDistance(circleA.origin, circleB.origin);
|
3089 | return distance <= opts.pointMatchingDistance;
|
3090 | }
|
3091 | return false;
|
3092 | }
|
3093 | var similarArcs = new MakerJs.Collector(compareCircles);
|
3094 | var similarCircles = new MakerJs.Collector(compareCircles);
|
3095 | var similarLines = new MakerJs.Collector(MakerJs.measure.isSlopeEqual);
|
3096 | var map = {};
|
3097 | map[MakerJs.pathType.Arc] = function (arcRef) {
|
3098 | similarArcs.addItemToCollection(arcRef.pathContext, arcRef);
|
3099 | };
|
3100 | map[MakerJs.pathType.Circle] = function (circleRef) {
|
3101 | similarCircles.addItemToCollection(circleRef.pathContext, circleRef);
|
3102 | };
|
3103 | map[MakerJs.pathType.Line] = function (lineRef) {
|
3104 | var slope = MakerJs.measure.lineSlope(lineRef.pathContext);
|
3105 | similarLines.addItemToCollection(slope, lineRef);
|
3106 | };
|
3107 | var opts = {
|
3108 | scalarMatchingDistance: .001,
|
3109 | pointMatchingDistance: .005
|
3110 | };
|
3111 | MakerJs.extendObject(opts, options);
|
3112 |
|
3113 | var walkOptions = {
|
3114 | onPath: function (walkedPath) {
|
3115 | var fn = map[walkedPath.pathContext.type];
|
3116 | if (fn) {
|
3117 | fn(walkedPath);
|
3118 | }
|
3119 | }
|
3120 | };
|
3121 | model.walk(modelToSimplify, walkOptions);
|
3122 |
|
3123 |
|
3124 | similarArcs.getCollectionsOfMultiple(function (key, arcRefs) {
|
3125 | checkForOverlaps(arcRefs, MakerJs.measure.isArcOverlapping, function (arcA, arcB) {
|
3126 |
|
3127 | var aEndsInB = MakerJs.measure.isBetweenArcAngles(arcA.endAngle, arcB, false);
|
3128 | var bEndsInA = MakerJs.measure.isBetweenArcAngles(arcB.endAngle, arcA, false);
|
3129 |
|
3130 | if (aEndsInB && bEndsInA) {
|
3131 | arcA.endAngle = arcA.startAngle + 360;
|
3132 | return;
|
3133 | }
|
3134 |
|
3135 | var ordered = aEndsInB ? [arcA, arcB] : [arcB, arcA];
|
3136 |
|
3137 | arcA.startAngle = MakerJs.angle.noRevolutions(ordered[0].startAngle);
|
3138 | arcA.endAngle = ordered[1].endAngle;
|
3139 | });
|
3140 | });
|
3141 |
|
3142 | similarCircles.getCollectionsOfMultiple(function (key, circleRefs) {
|
3143 | for (var i = 1; i < circleRefs.length; i++) {
|
3144 | var circleRef = circleRefs[i];
|
3145 | delete circleRef.modelContext.paths[circleRef.pathId];
|
3146 | }
|
3147 | });
|
3148 |
|
3149 |
|
3150 | similarLines.getCollectionsOfMultiple(function (slope, arcRefs) {
|
3151 | checkForOverlaps(arcRefs, MakerJs.measure.isLineOverlapping, function (lineA, lineB) {
|
3152 | var box = { paths: { lineA: lineA, lineB: lineB } };
|
3153 | var m = MakerJs.measure.modelExtents(box);
|
3154 | if (!slope.hasSlope) {
|
3155 |
|
3156 | lineA.origin[1] = m.low[1];
|
3157 | lineA.end[1] = m.high[1];
|
3158 | }
|
3159 | else {
|
3160 |
|
3161 | if (slope.slope < 0) {
|
3162 |
|
3163 | lineA.origin = [m.low[0], m.high[1]];
|
3164 | lineA.end = [m.high[0], m.low[1]];
|
3165 | }
|
3166 | else if (slope.slope > 0) {
|
3167 |
|
3168 | lineA.origin = m.low;
|
3169 | lineA.end = m.high;
|
3170 | }
|
3171 | else {
|
3172 |
|
3173 | lineA.origin[0] = m.low[0];
|
3174 | lineA.end[0] = m.high[0];
|
3175 | }
|
3176 | }
|
3177 | });
|
3178 | });
|
3179 | return modelToSimplify;
|
3180 | }
|
3181 | model.simplify = simplify;
|
3182 | })(model = MakerJs.model || (MakerJs.model = {}));
|
3183 | })(MakerJs || (MakerJs = {}));
|
3184 | var MakerJs;
|
3185 | (function (MakerJs) {
|
3186 | var path;
|
3187 | (function (path) {
|
3188 | |
3189 |
|
3190 |
|
3191 | var map = {};
|
3192 | map[MakerJs.pathType.Arc] = function (arc, expansion, isolateCaps) {
|
3193 | return new MakerJs.models.OvalArc(arc.startAngle, arc.endAngle, arc.radius, expansion, false, isolateCaps);
|
3194 | };
|
3195 | map[MakerJs.pathType.Circle] = function (circle, expansion, isolateCaps) {
|
3196 | return new MakerJs.models.Ring(circle.radius + expansion, circle.radius - expansion);
|
3197 | };
|
3198 | map[MakerJs.pathType.Line] = function (line, expansion, isolateCaps) {
|
3199 | return new MakerJs.models.Slot(line.origin, line.end, expansion, isolateCaps);
|
3200 | };
|
3201 | |
3202 |
|
3203 |
|
3204 |
|
3205 |
|
3206 |
|
3207 |
|
3208 |
|
3209 | function expand(pathToExpand, expansion, isolateCaps) {
|
3210 | if (!pathToExpand)
|
3211 | return null;
|
3212 | var result = null;
|
3213 | var fn = map[pathToExpand.type];
|
3214 | if (fn) {
|
3215 | result = fn(pathToExpand, expansion, isolateCaps);
|
3216 | result.origin = pathToExpand.origin;
|
3217 | }
|
3218 | return result;
|
3219 | }
|
3220 | path.expand = expand;
|
3221 | |
3222 |
|
3223 |
|
3224 |
|
3225 |
|
3226 |
|
3227 |
|
3228 |
|
3229 |
|
3230 | function straighten(arc, bevel, prefix, close) {
|
3231 | var arcSpan = MakerJs.angle.ofArcSpan(arc);
|
3232 | var joints = 1;
|
3233 | if (arcSpan >= 270) {
|
3234 | joints = 4;
|
3235 | }
|
3236 | else if (arcSpan > 180) {
|
3237 | joints = 3;
|
3238 | }
|
3239 | else if (arcSpan > 150 || bevel) {
|
3240 | joints = 2;
|
3241 | }
|
3242 | var jointAngleInRadians = MakerJs.angle.toRadians(arcSpan / joints);
|
3243 | var circumscribedRadius = MakerJs.models.Polygon.circumscribedRadius(arc.radius, jointAngleInRadians);
|
3244 | var ends = MakerJs.point.fromArc(arc);
|
3245 | var points = [MakerJs.point.subtract(ends[0], arc.origin)];
|
3246 | var a = MakerJs.angle.toRadians(arc.startAngle) + jointAngleInRadians / 2;
|
3247 | for (var i = 0; i < joints; i++) {
|
3248 | points.push(MakerJs.point.fromPolar(a, circumscribedRadius));
|
3249 | a += jointAngleInRadians;
|
3250 | }
|
3251 | points.push(MakerJs.point.subtract(ends[1], arc.origin));
|
3252 | var result = new MakerJs.models.ConnectTheDots(close, points);
|
3253 | result.origin = arc.origin;
|
3254 | if (typeof prefix === 'string' && prefix.length) {
|
3255 | MakerJs.model.prefixPathIds(result, prefix);
|
3256 | }
|
3257 | return result;
|
3258 | }
|
3259 | path.straighten = straighten;
|
3260 | })(path = MakerJs.path || (MakerJs.path = {}));
|
3261 | })(MakerJs || (MakerJs = {}));
|
3262 | (function (MakerJs) {
|
3263 | var model;
|
3264 | (function (model) {
|
3265 | |
3266 |
|
3267 |
|
3268 |
|
3269 |
|
3270 |
|
3271 |
|
3272 |
|
3273 |
|
3274 | function expandPaths(modelToExpand, distance, joints, combineOptions) {
|
3275 | if (joints === void 0) { joints = 0; }
|
3276 | if (combineOptions === void 0) { combineOptions = {}; }
|
3277 | if (distance <= 0)
|
3278 | return null;
|
3279 | var result = {
|
3280 | models: {
|
3281 | expansions: { models: {} },
|
3282 | caps: { models: {} }
|
3283 | }
|
3284 | };
|
3285 | var first = true;
|
3286 | var lastFarPoint = combineOptions.farPoint;
|
3287 | var walkOptions = {
|
3288 | onPath: function (walkedPath) {
|
3289 |
|
3290 | if (combineOptions.pointMatchingDistance && MakerJs.measure.pathLength(walkedPath.pathContext) < combineOptions.pointMatchingDistance)
|
3291 | return;
|
3292 | var expandedPathModel = MakerJs.path.expand(walkedPath.pathContext, distance, true);
|
3293 | if (expandedPathModel) {
|
3294 | model.moveRelative(expandedPathModel, walkedPath.offset);
|
3295 | var newId = model.getSimilarModelId(result.models['expansions'], walkedPath.pathId);
|
3296 | model.prefixPathIds(expandedPathModel, walkedPath.pathId + '_');
|
3297 | model.originate(expandedPathModel);
|
3298 | if (!first) {
|
3299 | model.combine(result, expandedPathModel, false, true, false, true, combineOptions);
|
3300 | combineOptions.measureA.modelsMeasured = false;
|
3301 | lastFarPoint = combineOptions.farPoint;
|
3302 | delete combineOptions.farPoint;
|
3303 | delete combineOptions.measureB;
|
3304 | }
|
3305 | result.models['expansions'].models[newId] = expandedPathModel;
|
3306 | if (expandedPathModel.models) {
|
3307 | var caps = expandedPathModel.models['Caps'];
|
3308 | if (caps) {
|
3309 | delete expandedPathModel.models['Caps'];
|
3310 | result.models['caps'].models[newId] = caps;
|
3311 | }
|
3312 | }
|
3313 | first = false;
|
3314 | }
|
3315 | }
|
3316 | };
|
3317 | model.walk(modelToExpand, walkOptions);
|
3318 | if (joints) {
|
3319 | var roundCaps = result.models['caps'];
|
3320 | var straightCaps = { models: {} };
|
3321 | result.models['straightcaps'] = straightCaps;
|
3322 | model.simplify(roundCaps);
|
3323 |
|
3324 | for (var id in roundCaps.models) {
|
3325 |
|
3326 | straightCaps.models[id] = { models: {} };
|
3327 | model.walk(roundCaps.models[id], {
|
3328 | onPath: function (walkedPath) {
|
3329 | var arc = walkedPath.pathContext;
|
3330 |
|
3331 | var straightened = MakerJs.path.straighten(arc, joints == 2, walkedPath.pathId + '_', true);
|
3332 |
|
3333 | model.combine(result, straightened, false, true, false, true, combineOptions);
|
3334 | combineOptions.measureA.modelsMeasured = false;
|
3335 | lastFarPoint = combineOptions.farPoint;
|
3336 | delete combineOptions.farPoint;
|
3337 | delete combineOptions.measureB;
|
3338 |
|
3339 | straightCaps.models[id].models[walkedPath.pathId] = straightened;
|
3340 |
|
3341 | delete walkedPath.modelContext.paths[walkedPath.pathId];
|
3342 | }
|
3343 | });
|
3344 | }
|
3345 |
|
3346 | delete result.models['caps'];
|
3347 | }
|
3348 | combineOptions.farPoint = lastFarPoint;
|
3349 | return result;
|
3350 | }
|
3351 | model.expandPaths = expandPaths;
|
3352 | |
3353 |
|
3354 |
|
3355 | function getEndlessChains(modelContext) {
|
3356 | var endlessChains = [];
|
3357 | model.findChains(modelContext, function (chains, loose, layer) {
|
3358 | endlessChains = chains.filter(function (chain) { return chain.endless; });
|
3359 | });
|
3360 | return endlessChains;
|
3361 | }
|
3362 | |
3363 |
|
3364 |
|
3365 | function getClosedGeometries(modelContext) {
|
3366 |
|
3367 | var endlessChains = getEndlessChains(modelContext);
|
3368 | if (endlessChains.length == 0)
|
3369 | return null;
|
3370 |
|
3371 | var closed = { models: {} };
|
3372 | endlessChains.forEach(function (c, i) {
|
3373 | closed.models[i] = MakerJs.chain.toNewModel(c);
|
3374 | });
|
3375 | return closed;
|
3376 | }
|
3377 | |
3378 |
|
3379 |
|
3380 |
|
3381 |
|
3382 |
|
3383 |
|
3384 |
|
3385 |
|
3386 |
|
3387 | function outline(modelToOutline, distance, joints, inside, options) {
|
3388 | if (joints === void 0) { joints = 0; }
|
3389 | if (inside === void 0) { inside = false; }
|
3390 | if (options === void 0) { options = {}; }
|
3391 | var expanded = expandPaths(modelToOutline, distance, joints, options);
|
3392 | if (!expanded)
|
3393 | return null;
|
3394 |
|
3395 | var closed = getClosedGeometries(modelToOutline);
|
3396 | if (closed) {
|
3397 | var childCount = 0;
|
3398 | var result = { models: {} };
|
3399 |
|
3400 | var chains = getEndlessChains(expanded);
|
3401 | chains.forEach(function (c) {
|
3402 |
|
3403 | var wp = c.links[0].walkedPath;
|
3404 |
|
3405 | var isInside = MakerJs.measure.isPointInsideModel(MakerJs.point.middle(wp.pathContext), closed, wp.offset);
|
3406 |
|
3407 | if (inside && isInside || !inside && !isInside) {
|
3408 | result.models[childCount++] = MakerJs.chain.toNewModel(c);
|
3409 | }
|
3410 | ;
|
3411 | });
|
3412 | return result;
|
3413 | }
|
3414 | else {
|
3415 | return expanded;
|
3416 | }
|
3417 | }
|
3418 | model.outline = outline;
|
3419 | })(model = MakerJs.model || (MakerJs.model = {}));
|
3420 | })(MakerJs || (MakerJs = {}));
|
3421 | var MakerJs;
|
3422 | (function (MakerJs) {
|
3423 | var units;
|
3424 | (function (units) {
|
3425 | |
3426 |
|
3427 |
|
3428 |
|
3429 | var base = MakerJs.unitType.Millimeter;
|
3430 | |
3431 |
|
3432 |
|
3433 |
|
3434 | function init() {
|
3435 | addBaseConversion(MakerJs.unitType.Centimeter, 10);
|
3436 | addBaseConversion(MakerJs.unitType.Meter, 1000);
|
3437 | addBaseConversion(MakerJs.unitType.Inch, 25.4);
|
3438 | addBaseConversion(MakerJs.unitType.Foot, 25.4 * 12);
|
3439 | }
|
3440 | |
3441 |
|
3442 |
|
3443 |
|
3444 | var table;
|
3445 | |
3446 |
|
3447 |
|
3448 |
|
3449 | function addConversion(srcUnitType, destUnitType, value) {
|
3450 | function row(unitType) {
|
3451 | if (!table[unitType]) {
|
3452 | table[unitType] = {};
|
3453 | }
|
3454 | return table[unitType];
|
3455 | }
|
3456 | row(srcUnitType)[destUnitType] = value;
|
3457 | row(destUnitType)[srcUnitType] = 1 / value;
|
3458 | }
|
3459 | |
3460 |
|
3461 |
|
3462 |
|
3463 | function addBaseConversion(destUnitType, value) {
|
3464 | addConversion(destUnitType, base, value);
|
3465 | }
|
3466 | |
3467 |
|
3468 |
|
3469 |
|
3470 |
|
3471 |
|
3472 |
|
3473 | function conversionScale(srcUnitType, destUnitType) {
|
3474 | if (srcUnitType == destUnitType) {
|
3475 | return 1;
|
3476 | }
|
3477 |
|
3478 | if (!table) {
|
3479 | table = {};
|
3480 | init();
|
3481 | }
|
3482 |
|
3483 | if (!table[srcUnitType][destUnitType]) {
|
3484 |
|
3485 | addConversion(srcUnitType, destUnitType, table[srcUnitType][base] * table[base][destUnitType]);
|
3486 | }
|
3487 | return table[srcUnitType] && table[srcUnitType][destUnitType];
|
3488 | }
|
3489 | units.conversionScale = conversionScale;
|
3490 | |
3491 |
|
3492 |
|
3493 |
|
3494 |
|
3495 |
|
3496 | function isValidUnit(tryUnit) {
|
3497 | for (var id in MakerJs.unitType) {
|
3498 | if (MakerJs.unitType[id] == tryUnit) {
|
3499 | return true;
|
3500 | }
|
3501 | }
|
3502 | return false;
|
3503 | }
|
3504 | units.isValidUnit = isValidUnit;
|
3505 | })(units = MakerJs.units || (MakerJs.units = {}));
|
3506 | })(MakerJs || (MakerJs = {}));
|
3507 | var MakerJs;
|
3508 | (function (MakerJs) {
|
3509 | var measure;
|
3510 | (function (measure) {
|
3511 | |
3512 |
|
3513 |
|
3514 |
|
3515 |
|
3516 |
|
3517 |
|
3518 | function isAngleEqual(angleA, angleB, accuracy) {
|
3519 | if (accuracy === void 0) { accuracy = .0001; }
|
3520 | var a = MakerJs.angle.noRevolutions(angleA);
|
3521 | var b = MakerJs.angle.noRevolutions(angleB);
|
3522 | var d = MakerJs.angle.noRevolutions(MakerJs.round(b - a, accuracy));
|
3523 | return d == 0;
|
3524 | }
|
3525 | measure.isAngleEqual = isAngleEqual;
|
3526 | |
3527 |
|
3528 |
|
3529 | var pathAreEqualMap = {};
|
3530 | pathAreEqualMap[MakerJs.pathType.Line] = function (lineA, lineB, withinPointDistance) {
|
3531 | return (isPointEqual(lineA.origin, lineB.origin, withinPointDistance) && isPointEqual(lineA.end, lineB.end, withinPointDistance))
|
3532 | || (isPointEqual(lineA.origin, lineB.end, withinPointDistance) && isPointEqual(lineA.end, lineB.origin, withinPointDistance));
|
3533 | };
|
3534 | pathAreEqualMap[MakerJs.pathType.Circle] = function (circleA, circleB, withinPointDistance) {
|
3535 | return isPointEqual(circleA.origin, circleB.origin, withinPointDistance) && circleA.radius == circleB.radius;
|
3536 | };
|
3537 | pathAreEqualMap[MakerJs.pathType.Arc] = function (arcA, arcB, withinPointDistance) {
|
3538 | return pathAreEqualMap[MakerJs.pathType.Circle](arcA, arcB, withinPointDistance) && isAngleEqual(arcA.startAngle, arcB.startAngle) && isAngleEqual(arcA.endAngle, arcB.endAngle);
|
3539 | };
|
3540 | |
3541 |
|
3542 |
|
3543 |
|
3544 |
|
3545 |
|
3546 |
|
3547 | function isPathEqual(pathA, pathB, withinPointDistance, pathAOffset, pathBOffset) {
|
3548 | var result = false;
|
3549 | if (pathA.type == pathB.type) {
|
3550 | var fn = pathAreEqualMap[pathA.type];
|
3551 | if (fn) {
|
3552 | function getResult() {
|
3553 | result = fn(pathA, pathB, withinPointDistance);
|
3554 | }
|
3555 | if (pathAOffset || pathBOffset) {
|
3556 | MakerJs.path.moveTemporary([pathA, pathB], [pathAOffset, pathBOffset], getResult);
|
3557 | }
|
3558 | else {
|
3559 | getResult();
|
3560 | }
|
3561 | }
|
3562 | }
|
3563 | return result;
|
3564 | }
|
3565 | measure.isPathEqual = isPathEqual;
|
3566 | |
3567 |
|
3568 |
|
3569 |
|
3570 |
|
3571 |
|
3572 |
|
3573 |
|
3574 | function isPointEqual(a, b, withinDistance) {
|
3575 | if (!withinDistance) {
|
3576 | return MakerJs.round(a[0] - b[0]) == 0 && MakerJs.round(a[1] - b[1]) == 0;
|
3577 | }
|
3578 | else {
|
3579 | if (!a || !b)
|
3580 | return false;
|
3581 | var distance = measure.pointDistance(a, b);
|
3582 | return distance <= withinDistance;
|
3583 | }
|
3584 | }
|
3585 | measure.isPointEqual = isPointEqual;
|
3586 | |
3587 |
|
3588 |
|
3589 |
|
3590 |
|
3591 |
|
3592 |
|
3593 |
|
3594 | function isPointDistinct(pointToCheck, pointArray, withinDistance) {
|
3595 | for (var i = 0; i < pointArray.length; i++) {
|
3596 | if (isPointEqual(pointArray[i], pointToCheck, withinDistance)) {
|
3597 | return false;
|
3598 | }
|
3599 | }
|
3600 | return true;
|
3601 | }
|
3602 | measure.isPointDistinct = isPointDistinct;
|
3603 | |
3604 |
|
3605 |
|
3606 |
|
3607 |
|
3608 |
|
3609 |
|
3610 |
|
3611 | function isPointOnSlope(p, slope, withinDistance) {
|
3612 | if (withinDistance === void 0) { withinDistance = 0; }
|
3613 | if (slope.hasSlope) {
|
3614 |
|
3615 | return Math.abs(p[1] - (slope.slope * p[0] + slope.yIntercept)) <= withinDistance;
|
3616 | }
|
3617 | else {
|
3618 |
|
3619 | return Math.abs(p[0] - slope.line.origin[0]) <= withinDistance;
|
3620 | }
|
3621 | }
|
3622 | measure.isPointOnSlope = isPointOnSlope;
|
3623 | |
3624 |
|
3625 |
|
3626 |
|
3627 |
|
3628 |
|
3629 |
|
3630 |
|
3631 | function isPointOnCircle(p, circle, withinDistance) {
|
3632 | if (withinDistance === void 0) { withinDistance = 0; }
|
3633 | var d = Math.abs(measure.pointDistance(p, circle.origin) - circle.radius);
|
3634 | return d <= withinDistance;
|
3635 | }
|
3636 | measure.isPointOnCircle = isPointOnCircle;
|
3637 | |
3638 |
|
3639 |
|
3640 | var onPathMap = {};
|
3641 | onPathMap[MakerJs.pathType.Circle] = function (p, circle, withinDistance) {
|
3642 | return isPointOnCircle(p, circle, withinDistance);
|
3643 | };
|
3644 | onPathMap[MakerJs.pathType.Arc] = function (p, arc, withinDistance) {
|
3645 | if (onPathMap[MakerJs.pathType.Circle](p, arc, withinDistance)) {
|
3646 | var a = MakerJs.angle.ofPointInDegrees(arc.origin, p);
|
3647 | return measure.isBetweenArcAngles(a, arc, false);
|
3648 | }
|
3649 | return false;
|
3650 | };
|
3651 | onPathMap[MakerJs.pathType.Line] = function (p, line, withinDistance, options) {
|
3652 | var slope = (options && options.cachedLineSlope) || measure.lineSlope(line);
|
3653 | if (options && !options.cachedLineSlope) {
|
3654 | options.cachedLineSlope = slope;
|
3655 | }
|
3656 | return isPointOnSlope(p, slope, withinDistance) && measure.isBetweenPoints(p, line, false);
|
3657 | };
|
3658 | |
3659 |
|
3660 |
|
3661 |
|
3662 |
|
3663 |
|
3664 |
|
3665 |
|
3666 | function isPointOnPath(pointToCheck, onPath, withinDistance, pathOffset, options) {
|
3667 | if (withinDistance === void 0) { withinDistance = 0; }
|
3668 | var fn = onPathMap[onPath.type];
|
3669 | if (fn) {
|
3670 | var offsetPath = pathOffset ? MakerJs.path.clone(onPath, pathOffset) : onPath;
|
3671 | return fn(pointToCheck, offsetPath, withinDistance, options);
|
3672 | }
|
3673 | return false;
|
3674 | }
|
3675 | measure.isPointOnPath = isPointOnPath;
|
3676 | |
3677 |
|
3678 |
|
3679 |
|
3680 |
|
3681 |
|
3682 |
|
3683 | function isSlopeEqual(slopeA, slopeB) {
|
3684 | if (!isSlopeParallel(slopeA, slopeB))
|
3685 | return false;
|
3686 | if (!slopeA.hasSlope && !slopeB.hasSlope) {
|
3687 |
|
3688 | return MakerJs.round(slopeA.line.origin[0] - slopeB.line.origin[0]) == 0;
|
3689 | }
|
3690 |
|
3691 | return MakerJs.round(slopeA.yIntercept - slopeB.yIntercept, .00001) == 0;
|
3692 | }
|
3693 | measure.isSlopeEqual = isSlopeEqual;
|
3694 | |
3695 |
|
3696 |
|
3697 |
|
3698 |
|
3699 |
|
3700 |
|
3701 | function isSlopeParallel(slopeA, slopeB) {
|
3702 | if (!slopeA.hasSlope && !slopeB.hasSlope) {
|
3703 | return true;
|
3704 | }
|
3705 | if (slopeA.hasSlope && slopeB.hasSlope && (MakerJs.round(slopeA.slope - slopeB.slope, .00001) == 0)) {
|
3706 |
|
3707 | return true;
|
3708 | }
|
3709 | return false;
|
3710 | }
|
3711 | measure.isSlopeParallel = isSlopeParallel;
|
3712 | })(measure = MakerJs.measure || (MakerJs.measure = {}));
|
3713 | })(MakerJs || (MakerJs = {}));
|
3714 | var MakerJs;
|
3715 | (function (MakerJs) {
|
3716 | var measure;
|
3717 | (function (measure) {
|
3718 | |
3719 |
|
3720 |
|
3721 |
|
3722 |
|
3723 |
|
3724 |
|
3725 |
|
3726 | function increase(baseMeasure, addMeasure, augmentBaseMeasure) {
|
3727 | function getExtreme(basePoint, newPoint, fn) {
|
3728 | if (!newPoint)
|
3729 | return;
|
3730 | for (var i = 2; i--;) {
|
3731 | if (newPoint[i] == null)
|
3732 | continue;
|
3733 | if (basePoint[i] == null) {
|
3734 | basePoint[i] = newPoint[i];
|
3735 | }
|
3736 | else {
|
3737 | basePoint[i] = fn(basePoint[i], newPoint[i]);
|
3738 | }
|
3739 | }
|
3740 | }
|
3741 | if (addMeasure) {
|
3742 | getExtreme(baseMeasure.low, addMeasure.low, Math.min);
|
3743 | getExtreme(baseMeasure.high, addMeasure.high, Math.max);
|
3744 | }
|
3745 | if (augmentBaseMeasure) {
|
3746 | augment(baseMeasure);
|
3747 | }
|
3748 | return baseMeasure;
|
3749 | }
|
3750 | measure.increase = increase;
|
3751 | |
3752 |
|
3753 |
|
3754 |
|
3755 |
|
3756 |
|
3757 |
|
3758 | function isArcConcaveTowardsPoint(arc, towardsPoint) {
|
3759 | if (pointDistance(arc.origin, towardsPoint) <= arc.radius) {
|
3760 | return true;
|
3761 | }
|
3762 | var midPointToNearPoint = new MakerJs.paths.Line(MakerJs.point.middle(arc), towardsPoint);
|
3763 | var options = {};
|
3764 | var intersectionPoint = MakerJs.path.intersection(midPointToNearPoint, new MakerJs.paths.Chord(arc), options);
|
3765 | if (intersectionPoint || options.out_AreOverlapped) {
|
3766 | return true;
|
3767 | }
|
3768 | return false;
|
3769 | }
|
3770 | measure.isArcConcaveTowardsPoint = isArcConcaveTowardsPoint;
|
3771 | |
3772 |
|
3773 |
|
3774 | function isArcOverlapping(arcA, arcB, excludeTangents) {
|
3775 | return isArcSpanOverlapping(arcA, arcB, excludeTangents);
|
3776 | }
|
3777 | measure.isArcOverlapping = isArcOverlapping;
|
3778 | |
3779 |
|
3780 |
|
3781 |
|
3782 |
|
3783 |
|
3784 |
|
3785 |
|
3786 | function isArcSpanOverlapping(arcA, arcB, excludeTangents) {
|
3787 | var pointsOfIntersection = [];
|
3788 | function checkAngles(a, b) {
|
3789 | function checkAngle(n) {
|
3790 | return isBetweenArcAngles(n, a, excludeTangents);
|
3791 | }
|
3792 | return checkAngle(b.startAngle) || checkAngle(b.endAngle);
|
3793 | }
|
3794 | return checkAngles(arcA, arcB) || checkAngles(arcB, arcA) || (arcA.startAngle == arcB.startAngle && arcA.endAngle == arcB.endAngle);
|
3795 | }
|
3796 | measure.isArcSpanOverlapping = isArcSpanOverlapping;
|
3797 | |
3798 |
|
3799 |
|
3800 |
|
3801 |
|
3802 |
|
3803 |
|
3804 |
|
3805 |
|
3806 | function isBetween(valueInQuestion, limitA, limitB, exclusive) {
|
3807 | if (exclusive) {
|
3808 | return Math.min(limitA, limitB) < valueInQuestion && valueInQuestion < Math.max(limitA, limitB);
|
3809 | }
|
3810 | else {
|
3811 | return Math.min(limitA, limitB) <= valueInQuestion && valueInQuestion <= Math.max(limitA, limitB);
|
3812 | }
|
3813 | }
|
3814 | measure.isBetween = isBetween;
|
3815 | |
3816 |
|
3817 |
|
3818 |
|
3819 |
|
3820 |
|
3821 |
|
3822 |
|
3823 | function isBetweenArcAngles(angleInQuestion, arc, exclusive) {
|
3824 | var startAngle = MakerJs.angle.noRevolutions(arc.startAngle);
|
3825 | var span = MakerJs.angle.ofArcSpan(arc);
|
3826 | var endAngle = startAngle + span;
|
3827 | angleInQuestion = MakerJs.angle.noRevolutions(angleInQuestion);
|
3828 |
|
3829 | return (isBetween(angleInQuestion, startAngle, endAngle, exclusive) || isBetween(angleInQuestion, startAngle + 360, endAngle + 360, exclusive) || isBetween(angleInQuestion, startAngle - 360, endAngle - 360, exclusive));
|
3830 | }
|
3831 | measure.isBetweenArcAngles = isBetweenArcAngles;
|
3832 | |
3833 |
|
3834 |
|
3835 |
|
3836 |
|
3837 |
|
3838 |
|
3839 |
|
3840 | function isBetweenPoints(pointInQuestion, line, exclusive) {
|
3841 | var oneDimension = false;
|
3842 | for (var i = 2; i--;) {
|
3843 | if (MakerJs.round(line.origin[i] - line.end[i], .000001) == 0) {
|
3844 | if (oneDimension)
|
3845 | return false;
|
3846 | oneDimension = true;
|
3847 | continue;
|
3848 | }
|
3849 | var origin_value = MakerJs.round(line.origin[i]);
|
3850 | var end_value = MakerJs.round(line.end[i]);
|
3851 | if (!isBetween(MakerJs.round(pointInQuestion[i]), origin_value, end_value, exclusive))
|
3852 | return false;
|
3853 | }
|
3854 | return true;
|
3855 | }
|
3856 | measure.isBetweenPoints = isBetweenPoints;
|
3857 | |
3858 |
|
3859 |
|
3860 |
|
3861 |
|
3862 |
|
3863 |
|
3864 | function isBezierSeedLinear(seed, exclusive) {
|
3865 |
|
3866 | var slope = lineSlope(seed);
|
3867 | for (var i = 0; i < seed.controls.length; i++) {
|
3868 | if (!(measure.isPointOnSlope(seed.controls[i], slope))) {
|
3869 | if (!exclusive)
|
3870 | return false;
|
3871 | if (isBetweenPoints(seed.controls[i], seed, false))
|
3872 | return false;
|
3873 | }
|
3874 | }
|
3875 | return true;
|
3876 | }
|
3877 | measure.isBezierSeedLinear = isBezierSeedLinear;
|
3878 | |
3879 |
|
3880 |
|
3881 | var graham_scan = require('graham_scan');
|
3882 | |
3883 |
|
3884 |
|
3885 | function serializePoint(p) {
|
3886 | return p.join(',');
|
3887 | }
|
3888 | |
3889 |
|
3890 |
|
3891 |
|
3892 |
|
3893 |
|
3894 |
|
3895 | function isChainClockwise(chainContext, out_result) {
|
3896 |
|
3897 | if (!chainContext.endless || chainContext.links.length === 1) {
|
3898 | return null;
|
3899 | }
|
3900 | var keyPoints = MakerJs.chain.toKeyPoints(chainContext);
|
3901 | return isPointArrayClockwise(keyPoints, out_result);
|
3902 | }
|
3903 | measure.isChainClockwise = isChainClockwise;
|
3904 | |
3905 |
|
3906 |
|
3907 |
|
3908 |
|
3909 |
|
3910 |
|
3911 | function isPointArrayClockwise(points, out_result) {
|
3912 | var convexHull = new graham_scan();
|
3913 | var pointsInOrder = [];
|
3914 | function add(endPoint) {
|
3915 | convexHull.addPoint(endPoint[0], endPoint[1]);
|
3916 | pointsInOrder.push(serializePoint(endPoint));
|
3917 | }
|
3918 | points.forEach(add);
|
3919 |
|
3920 | var hull = convexHull.getHull();
|
3921 | var hullPoints = hull.slice(0, 3).map(function (p) { return serializePoint([p.x, p.y]); });
|
3922 | var ordered = [];
|
3923 | pointsInOrder.forEach(function (p) {
|
3924 | if (~hullPoints.indexOf(p))
|
3925 | ordered.push(p);
|
3926 | });
|
3927 |
|
3928 | switch (ordered.indexOf(hullPoints[1])) {
|
3929 | case 0:
|
3930 |
|
3931 | ordered.unshift(ordered.pop());
|
3932 | break;
|
3933 | case 2:
|
3934 |
|
3935 | ordered.push(ordered.shift());
|
3936 | break;
|
3937 | }
|
3938 | if (out_result) {
|
3939 | out_result.hullPoints = hull.map(function (p) { return [p.x, p.y]; });
|
3940 | out_result.keyPoints = points;
|
3941 | }
|
3942 |
|
3943 | return hullPoints[0] != ordered[0];
|
3944 | }
|
3945 | measure.isPointArrayClockwise = isPointArrayClockwise;
|
3946 | |
3947 |
|
3948 |
|
3949 |
|
3950 |
|
3951 |
|
3952 |
|
3953 |
|
3954 | function isLineOverlapping(lineA, lineB, excludeTangents) {
|
3955 | var pointsOfIntersection = [];
|
3956 | function checkPoints(index, a, b) {
|
3957 | function checkPoint(p) {
|
3958 | return isBetweenPoints(p, a, excludeTangents);
|
3959 | }
|
3960 | return checkPoint(b.origin) || checkPoint(b.end);
|
3961 | }
|
3962 | return checkPoints(0, lineA, lineB) || checkPoints(1, lineB, lineA);
|
3963 | }
|
3964 | measure.isLineOverlapping = isLineOverlapping;
|
3965 | |
3966 |
|
3967 |
|
3968 |
|
3969 |
|
3970 |
|
3971 |
|
3972 | function isMeasurementOverlapping(measureA, measureB) {
|
3973 | for (var i = 2; i--;) {
|
3974 | if (!(MakerJs.round(measureA.low[i] - measureB.high[i]) <= 0 && MakerJs.round(measureA.high[i] - measureB.low[i]) >= 0))
|
3975 | return false;
|
3976 | }
|
3977 | return true;
|
3978 | }
|
3979 | measure.isMeasurementOverlapping = isMeasurementOverlapping;
|
3980 | |
3981 |
|
3982 |
|
3983 | function lineSlope(line) {
|
3984 | var dx = line.end[0] - line.origin[0];
|
3985 | if (MakerJs.round(dx, .000001) == 0) {
|
3986 | return {
|
3987 | line: line,
|
3988 | hasSlope: false
|
3989 | };
|
3990 | }
|
3991 | var dy = line.end[1] - line.origin[1];
|
3992 | var slope = dy / dx;
|
3993 | var yIntercept = line.origin[1] - slope * line.origin[0];
|
3994 | return {
|
3995 | line: line,
|
3996 | hasSlope: true,
|
3997 | slope: slope,
|
3998 | yIntercept: yIntercept
|
3999 | };
|
4000 | }
|
4001 | measure.lineSlope = lineSlope;
|
4002 | |
4003 |
|
4004 |
|
4005 |
|
4006 |
|
4007 |
|
4008 |
|
4009 | function pointDistance(a, b) {
|
4010 | var dx = b[0] - a[0];
|
4011 | var dy = b[1] - a[1];
|
4012 | return Math.sqrt(dx * dx + dy * dy);
|
4013 | }
|
4014 | measure.pointDistance = pointDistance;
|
4015 | |
4016 |
|
4017 |
|
4018 | function getExtremePoint(a, b, fn) {
|
4019 | return [
|
4020 | fn(a[0], b[0]),
|
4021 | fn(a[1], b[1])
|
4022 | ];
|
4023 | }
|
4024 | |
4025 |
|
4026 |
|
4027 | var pathExtentsMap = {};
|
4028 | pathExtentsMap[MakerJs.pathType.Line] = function (line) {
|
4029 | return {
|
4030 | low: getExtremePoint(line.origin, line.end, Math.min),
|
4031 | high: getExtremePoint(line.origin, line.end, Math.max)
|
4032 | };
|
4033 | };
|
4034 | pathExtentsMap[MakerJs.pathType.Circle] = function (circle) {
|
4035 | var r = circle.radius;
|
4036 | return {
|
4037 | low: MakerJs.point.add(circle.origin, [-r, -r]),
|
4038 | high: MakerJs.point.add(circle.origin, [r, r])
|
4039 | };
|
4040 | };
|
4041 | pathExtentsMap[MakerJs.pathType.Arc] = function (arc) {
|
4042 | var r = arc.radius;
|
4043 | var arcPoints = MakerJs.point.fromArc(arc);
|
4044 | function extremeAngle(xyAngle, value, fn) {
|
4045 | var extremePoint = getExtremePoint(arcPoints[0], arcPoints[1], fn);
|
4046 | for (var i = 2; i--;) {
|
4047 | if (isBetweenArcAngles(xyAngle[i], arc, false)) {
|
4048 | extremePoint[i] = value + arc.origin[i];
|
4049 | }
|
4050 | }
|
4051 | return extremePoint;
|
4052 | }
|
4053 | return {
|
4054 | low: extremeAngle([180, 270], -r, Math.min),
|
4055 | high: extremeAngle([360, 90], r, Math.max)
|
4056 | };
|
4057 | };
|
4058 | |
4059 |
|
4060 |
|
4061 |
|
4062 |
|
4063 |
|
4064 | function pathExtents(pathToMeasure, addOffset) {
|
4065 | if (pathToMeasure) {
|
4066 | var fn = pathExtentsMap[pathToMeasure.type];
|
4067 | if (fn) {
|
4068 | var m = fn(pathToMeasure);
|
4069 | if (addOffset) {
|
4070 | m.high = MakerJs.point.add(m.high, addOffset);
|
4071 | m.low = MakerJs.point.add(m.low, addOffset);
|
4072 | }
|
4073 | return m;
|
4074 | }
|
4075 | }
|
4076 | return { low: null, high: null };
|
4077 | }
|
4078 | measure.pathExtents = pathExtents;
|
4079 | |
4080 |
|
4081 |
|
4082 | var pathLengthMap = {};
|
4083 | pathLengthMap[MakerJs.pathType.Line] = function (line) {
|
4084 | return pointDistance(line.origin, line.end);
|
4085 | };
|
4086 | pathLengthMap[MakerJs.pathType.Circle] = function (circle) {
|
4087 | return 2 * Math.PI * circle.radius;
|
4088 | };
|
4089 | pathLengthMap[MakerJs.pathType.Arc] = function (arc) {
|
4090 | var value = pathLengthMap[MakerJs.pathType.Circle](arc);
|
4091 | var pct = MakerJs.angle.ofArcSpan(arc) / 360;
|
4092 | value *= pct;
|
4093 | return value;
|
4094 | };
|
4095 | pathLengthMap[MakerJs.pathType.BezierSeed] = function (seed) {
|
4096 | return MakerJs.models.BezierCurve.computeLength(seed);
|
4097 | };
|
4098 | |
4099 |
|
4100 |
|
4101 |
|
4102 |
|
4103 |
|
4104 | function pathLength(pathToMeasure) {
|
4105 | if (pathToMeasure) {
|
4106 | var fn = pathLengthMap[pathToMeasure.type];
|
4107 | if (fn) {
|
4108 | return fn(pathToMeasure);
|
4109 | }
|
4110 | }
|
4111 | return 0;
|
4112 | }
|
4113 | measure.pathLength = pathLength;
|
4114 | |
4115 |
|
4116 |
|
4117 |
|
4118 |
|
4119 |
|
4120 | function modelPathLength(modelToMeasure) {
|
4121 | var total = 0;
|
4122 | MakerJs.model.walk(modelToMeasure, {
|
4123 | onPath: function (walkedPath) {
|
4124 | total += pathLength(walkedPath.pathContext);
|
4125 | }
|
4126 | });
|
4127 | return total;
|
4128 | }
|
4129 | measure.modelPathLength = modelPathLength;
|
4130 | |
4131 |
|
4132 |
|
4133 | function cloneMeasure(measureToclone) {
|
4134 | return {
|
4135 | high: MakerJs.point.clone(measureToclone.high),
|
4136 | low: MakerJs.point.clone(measureToclone.low)
|
4137 | };
|
4138 | }
|
4139 | |
4140 |
|
4141 |
|
4142 |
|
4143 |
|
4144 |
|
4145 |
|
4146 | function modelExtents(modelToMeasure, atlas) {
|
4147 | function increaseParentModel(childRoute, childMeasurement) {
|
4148 | if (!childMeasurement)
|
4149 | return;
|
4150 |
|
4151 | var parentRoute = childRoute.slice(0, -2);
|
4152 | var parentRouteKey = MakerJs.createRouteKey(parentRoute);
|
4153 | if (!(parentRouteKey in atlas.modelMap)) {
|
4154 |
|
4155 | atlas.modelMap[parentRouteKey] = cloneMeasure(childMeasurement);
|
4156 | }
|
4157 | else {
|
4158 | increase(atlas.modelMap[parentRouteKey], childMeasurement);
|
4159 | }
|
4160 | }
|
4161 | if (!atlas)
|
4162 | atlas = new Atlas(modelToMeasure);
|
4163 | var walkOptions = {
|
4164 | onPath: function (walkedPath) {
|
4165 |
|
4166 | if (!(walkedPath.routeKey in atlas.pathMap)) {
|
4167 | atlas.pathMap[walkedPath.routeKey] = pathExtents(walkedPath.pathContext, walkedPath.offset);
|
4168 | }
|
4169 | increaseParentModel(walkedPath.route, atlas.pathMap[walkedPath.routeKey]);
|
4170 | },
|
4171 | afterChildWalk: function (walkedModel) {
|
4172 |
|
4173 | increaseParentModel(walkedModel.route, atlas.modelMap[walkedModel.routeKey]);
|
4174 | }
|
4175 | };
|
4176 | MakerJs.model.walk(modelToMeasure, walkOptions);
|
4177 | atlas.modelsMeasured = true;
|
4178 | var m = atlas.modelMap[''];
|
4179 | if (m) {
|
4180 | return augment(m);
|
4181 | }
|
4182 | return m;
|
4183 | }
|
4184 | measure.modelExtents = modelExtents;
|
4185 | |
4186 |
|
4187 |
|
4188 |
|
4189 |
|
4190 |
|
4191 | function augment(measureToAugment) {
|
4192 | var m = measureToAugment;
|
4193 | m.center = MakerJs.point.average(m.high, m.low);
|
4194 | m.width = m.high[0] - m.low[0];
|
4195 | m.height = m.high[1] - m.low[1];
|
4196 | return m;
|
4197 | }
|
4198 | measure.augment = augment;
|
4199 | |
4200 |
|
4201 |
|
4202 |
|
4203 |
|
4204 |
|
4205 |
|
4206 | var Atlas = (function () {
|
4207 | |
4208 |
|
4209 |
|
4210 |
|
4211 | function Atlas(modelContext) {
|
4212 | this.modelContext = modelContext;
|
4213 | |
4214 |
|
4215 |
|
4216 | this.modelsMeasured = false;
|
4217 | |
4218 |
|
4219 |
|
4220 | this.modelMap = {};
|
4221 | |
4222 |
|
4223 |
|
4224 | this.pathMap = {};
|
4225 | }
|
4226 | Atlas.prototype.measureModels = function () {
|
4227 | if (!this.modelsMeasured) {
|
4228 | modelExtents(this.modelContext, this);
|
4229 | }
|
4230 | };
|
4231 | return Atlas;
|
4232 | }());
|
4233 | measure.Atlas = Atlas;
|
4234 | |
4235 |
|
4236 |
|
4237 | function loopIndex(base, i) {
|
4238 | if (i >= base)
|
4239 | return i - base;
|
4240 | if (i < 0)
|
4241 | return i + base;
|
4242 | return i;
|
4243 | }
|
4244 | |
4245 |
|
4246 |
|
4247 | function yAtX(slope, x) {
|
4248 | return slope.slope * x + slope.yIntercept;
|
4249 | }
|
4250 | |
4251 |
|
4252 |
|
4253 | function pointOnSlopeAtX(line, x) {
|
4254 | var slope = lineSlope(line);
|
4255 | return [x, yAtX(slope, x)];
|
4256 | }
|
4257 | |
4258 |
|
4259 |
|
4260 | function isCircular(bounds) {
|
4261 | for (var i = 1; i < 3; i++) {
|
4262 | if (!measure.isPointEqual(bounds[0].center, bounds[i].center, .000001) || !(MakerJs.round(bounds[0].width - bounds[i].width) === 0)) {
|
4263 | return false;
|
4264 | }
|
4265 | }
|
4266 | return true;
|
4267 | }
|
4268 | |
4269 |
|
4270 |
|
4271 | function getAngledBounds(index, modelToMeasure, rotateModel, rotatePaths) {
|
4272 | MakerJs.model.rotate(modelToMeasure, rotateModel);
|
4273 | var m = modelExtents(modelToMeasure);
|
4274 | var result = {
|
4275 | index: index,
|
4276 | rotation: rotatePaths,
|
4277 | center: MakerJs.point.rotate(m.center, rotatePaths),
|
4278 |
|
4279 | width: m.height,
|
4280 | height: m.width,
|
4281 | bottom: new MakerJs.paths.Line(m.low, [m.high[0], m.low[1]]),
|
4282 | middle: new MakerJs.paths.Line([m.low[0], m.center[1]], [m.high[0], m.center[1]]),
|
4283 | top: new MakerJs.paths.Line(m.high, [m.low[0], m.high[1]])
|
4284 | };
|
4285 | [result.top, result.middle, result.bottom].forEach(function (line) { return MakerJs.path.rotate(line, rotatePaths); });
|
4286 | return result;
|
4287 | }
|
4288 | |
4289 |
|
4290 |
|
4291 | function hexSolution(lines, bounds) {
|
4292 | var tip = lines[1].origin;
|
4293 | var tipX = tip[0];
|
4294 | var left = lines[3].origin[0];
|
4295 | var right = lines[0].origin[0];
|
4296 |
|
4297 | var altRight = tipX - right;
|
4298 | if ((right - left) > 2 * altRight)
|
4299 | return null;
|
4300 |
|
4301 | var altLeft = (tipX - left) / 3;
|
4302 | if (altRight < altLeft)
|
4303 | return null;
|
4304 | var altitudeViaSide = Math.min(altLeft, altRight);
|
4305 | var radiusViaSide = MakerJs.solvers.equilateralSide(altitudeViaSide);
|
4306 |
|
4307 | var peakPoints = [MakerJs.point.fromSlopeIntersection(lines[1], lines[2]), MakerJs.point.fromSlopeIntersection(lines[4], lines[5])];
|
4308 | var peakRadii = peakPoints.map(function (p) { return Math.abs(p[1] - tip[1]); });
|
4309 | var peakNum = (peakRadii[0] > peakRadii[1]) ? 0 : 1;
|
4310 | var radiusViaPeak = peakRadii[peakNum];
|
4311 | if (radiusViaPeak > radiusViaSide) {
|
4312 | var altitudeViaPeak = MakerJs.solvers.equilateralAltitude(radiusViaPeak);
|
4313 | var peakX = tipX - 2 * altitudeViaPeak;
|
4314 |
|
4315 | if (right > peakX + altitudeViaPeak)
|
4316 | return null;
|
4317 |
|
4318 | if (left < peakX - altitudeViaPeak)
|
4319 | return null;
|
4320 |
|
4321 |
|
4322 | var leftGap = left - peakX + altitudeViaPeak;
|
4323 | var peakGap = 2 * altitudeViaPeak - bounds[peakNum + 1].width;
|
4324 | var minHalfGap = Math.min(leftGap, peakGap) / 2;
|
4325 | return {
|
4326 | origin: pointOnSlopeAtX(bounds[2 - peakNum].middle, peakX + minHalfGap),
|
4327 | radius: radiusViaPeak,
|
4328 | type: 'peak ' + peakNum
|
4329 | };
|
4330 | }
|
4331 | else {
|
4332 | return {
|
4333 | origin: [tipX - 2 * altitudeViaSide, tip[1]],
|
4334 | radius: radiusViaSide,
|
4335 | type: 'side'
|
4336 | };
|
4337 | }
|
4338 | }
|
4339 | |
4340 |
|
4341 |
|
4342 |
|
4343 |
|
4344 |
|
4345 | function boundingHexagon(modelToMeasure) {
|
4346 | var clone = MakerJs.cloneObject(modelToMeasure);
|
4347 | MakerJs.model.originate(clone);
|
4348 | var originalMeasure = modelExtents(clone);
|
4349 | var bounds = [];
|
4350 | var scratch = { paths: {} };
|
4351 | MakerJs.model.center(clone);
|
4352 | function result(radius, origin, notes) {
|
4353 | return {
|
4354 | radius: radius,
|
4355 | paths: new MakerJs.models.Polygon(6, radius, 30).paths,
|
4356 | origin: MakerJs.point.add(origin, originalMeasure.center),
|
4357 |
|
4358 | notes: notes
|
4359 | };
|
4360 | }
|
4361 | var boundRotations = [[90, -90], [-60, -30], [-60, 30]];
|
4362 | while (boundRotations.length) {
|
4363 | var rotation = boundRotations.shift();
|
4364 | var bound = getAngledBounds(bounds.length, clone, rotation[0], rotation[1]);
|
4365 | var side = MakerJs.solvers.equilateralSide(bound.width / 2);
|
4366 | if (side >= bound.height) {
|
4367 | return result(side, bound.center, 'solved by bound ' + bounds.length);
|
4368 | }
|
4369 | bounds.push(bound);
|
4370 | }
|
4371 |
|
4372 |
|
4373 |
|
4374 | if (isCircular(bounds)) {
|
4375 | return result(MakerJs.solvers.equilateralSide(bounds[0].width / 2), bounds[0].center, 'solved as circular');
|
4376 | }
|
4377 | var perimeters = bounds.map(function (b) { return b.top; }).concat(bounds.map(function (b) { return b.bottom; }));
|
4378 | perimeters.forEach(function (p, i) {
|
4379 | scratch.paths[i] = p;
|
4380 |
|
4381 | MakerJs.path.converge(perimeters[loopIndex(6, i + 2)], p, true);
|
4382 | });
|
4383 | bounds.forEach(function (b, i) {
|
4384 | scratch.paths['m' + i] = b.middle;
|
4385 | });
|
4386 | var boundCopy = bounds.slice();
|
4387 | var solution;
|
4388 |
|
4389 | for (var i = 0; i < 6; i++) {
|
4390 |
|
4391 | if (i > 0) {
|
4392 | perimeters.push(perimeters.shift());
|
4393 | boundCopy.push(boundCopy.shift());
|
4394 | MakerJs.model.rotate(scratch, -60);
|
4395 | }
|
4396 | var s = hexSolution(perimeters, boundCopy);
|
4397 | if (s) {
|
4398 | if (!solution || s.radius < solution.radius) {
|
4399 | solution = s;
|
4400 | solution.index = i;
|
4401 | }
|
4402 | }
|
4403 | }
|
4404 | var p = MakerJs.point.rotate(solution.origin, solution.index * 60);
|
4405 | return result(solution.radius, p, 'solved by ' + solution.index + ' as ' + solution.type);
|
4406 | }
|
4407 | measure.boundingHexagon = boundingHexagon;
|
4408 | |
4409 |
|
4410 |
|
4411 | function addUniquePoints(pointArray, pointsToAdd) {
|
4412 | var added = 0;
|
4413 | pointsToAdd.forEach(function (p) {
|
4414 | if (!measure.isPointDistinct(p, pointArray, .00000001))
|
4415 | return;
|
4416 | pointArray.push(p);
|
4417 | added++;
|
4418 | });
|
4419 | return added;
|
4420 | }
|
4421 | |
4422 |
|
4423 |
|
4424 | function getFarPoint(modelContext, farPoint, measureAtlas) {
|
4425 | if (farPoint)
|
4426 | return farPoint;
|
4427 | var high = modelExtents(modelContext).high;
|
4428 | if (high) {
|
4429 | return MakerJs.point.add(high, [1, 1]);
|
4430 | }
|
4431 | return [7654321, 1234567];
|
4432 | }
|
4433 | |
4434 |
|
4435 |
|
4436 |
|
4437 |
|
4438 |
|
4439 |
|
4440 |
|
4441 | function isPointInsideModel(pointToCheck, modelContext, options) {
|
4442 | if (options === void 0) { options = {}; }
|
4443 | if (!options.farPoint) {
|
4444 | options.farPoint = getFarPoint(modelContext, options.farPoint, options.measureAtlas);
|
4445 | }
|
4446 | options.out_intersectionPoints = [];
|
4447 | var isInside;
|
4448 | var lineToFarPoint = new MakerJs.paths.Line(pointToCheck, options.farPoint);
|
4449 | var measureFarPoint = pathExtents(lineToFarPoint);
|
4450 | var walkOptions = {
|
4451 | onPath: function (walkedPath) {
|
4452 | if (options.measureAtlas && !isMeasurementOverlapping(measureFarPoint, options.measureAtlas.pathMap[walkedPath.routeKey])) {
|
4453 | return;
|
4454 | }
|
4455 | var intersectOptions = { path2Offset: walkedPath.offset };
|
4456 | var farInt = MakerJs.path.intersection(lineToFarPoint, walkedPath.pathContext, intersectOptions);
|
4457 | if (farInt) {
|
4458 | var added = addUniquePoints(options.out_intersectionPoints, farInt.intersectionPoints);
|
4459 |
|
4460 | if (added % 2 == 1) {
|
4461 | isInside = !!!isInside;
|
4462 | }
|
4463 | }
|
4464 | },
|
4465 | beforeChildWalk: function (innerWalkedModel) {
|
4466 | if (!options.measureAtlas) {
|
4467 | return true;
|
4468 | }
|
4469 |
|
4470 | var innerModelMeasurement = options.measureAtlas.modelMap[innerWalkedModel.routeKey];
|
4471 | return innerModelMeasurement && isMeasurementOverlapping(measureFarPoint, innerModelMeasurement);
|
4472 | }
|
4473 | };
|
4474 | MakerJs.model.walk(modelContext, walkOptions);
|
4475 | return !!isInside;
|
4476 | }
|
4477 | measure.isPointInsideModel = isPointInsideModel;
|
4478 | })(measure = MakerJs.measure || (MakerJs.measure = {}));
|
4479 | })(MakerJs || (MakerJs = {}));
|
4480 | var MakerJs;
|
4481 | (function (MakerJs) {
|
4482 | var exporter;
|
4483 | (function (exporter) {
|
4484 | |
4485 |
|
4486 |
|
4487 |
|
4488 |
|
4489 |
|
4490 |
|
4491 |
|
4492 |
|
4493 | function toJson(itemToExport, options) {
|
4494 | if (options === void 0) { options = {}; }
|
4495 | function replacer(key, value) {
|
4496 | if (MakerJs.isNumber(value)) {
|
4497 | var newValue = MakerJs.round(value, options.accuracy);
|
4498 | return newValue;
|
4499 | }
|
4500 | if (MakerJs.isPoint(value)) {
|
4501 | var newPoint = MakerJs.point.rounded(value, options.accuracy);
|
4502 | return newPoint;
|
4503 | }
|
4504 | return value;
|
4505 | }
|
4506 | return JSON.stringify(itemToExport, options.accuracy && replacer, options.indentation);
|
4507 | }
|
4508 | exporter.toJson = toJson;
|
4509 | |
4510 |
|
4511 |
|
4512 |
|
4513 | function tryGetModelUnits(itemToExport) {
|
4514 | if (MakerJs.isModel(itemToExport)) {
|
4515 | return itemToExport.units;
|
4516 | }
|
4517 | }
|
4518 | exporter.tryGetModelUnits = tryGetModelUnits;
|
4519 | |
4520 |
|
4521 |
|
4522 |
|
4523 | exporter.colors = {
|
4524 | black: 0,
|
4525 | red: 1,
|
4526 | yellow: 2,
|
4527 | lime: 3,
|
4528 | aqua: 4,
|
4529 | blue: 5,
|
4530 | fuchsia: 6,
|
4531 | white: 7,
|
4532 | gray: 9,
|
4533 | maroon: 14,
|
4534 | orange: 30,
|
4535 | olive: 58,
|
4536 | green: 94,
|
4537 | teal: 134,
|
4538 | navy: 174,
|
4539 | purple: 214,
|
4540 | silver: 254
|
4541 | };
|
4542 | })(exporter = MakerJs.exporter || (MakerJs.exporter = {}));
|
4543 | })(MakerJs || (MakerJs = {}));
|
4544 | var MakerJs;
|
4545 | (function (MakerJs) {
|
4546 | var importer;
|
4547 | (function (importer) {
|
4548 | |
4549 |
|
4550 |
|
4551 |
|
4552 |
|
4553 |
|
4554 |
|
4555 |
|
4556 |
|
4557 |
|
4558 |
|
4559 | function parseNumericList(s) {
|
4560 | var result = [];
|
4561 |
|
4562 | var re = /[\.-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
|
4563 | var matches;
|
4564 | while ((matches = re.exec(s)) !== null) {
|
4565 | if (matches.index === re.lastIndex) {
|
4566 | re.lastIndex++;
|
4567 | }
|
4568 | result.push(parseFloat(matches[0]));
|
4569 | }
|
4570 | return result;
|
4571 | }
|
4572 | importer.parseNumericList = parseNumericList;
|
4573 | })(importer = MakerJs.importer || (MakerJs.importer = {}));
|
4574 | })(MakerJs || (MakerJs = {}));
|
4575 | var MakerJs;
|
4576 | (function (MakerJs) {
|
4577 | var exporter;
|
4578 | (function (exporter) {
|
4579 | |
4580 |
|
4581 |
|
4582 |
|
4583 |
|
4584 |
|
4585 |
|
4586 |
|
4587 | function toDXF(itemToExport, options) {
|
4588 |
|
4589 |
|
4590 | if (options === void 0) { options = {}; }
|
4591 | var opts = {
|
4592 | fontSize: 9
|
4593 | };
|
4594 | var layerIds = [];
|
4595 | var doc = {
|
4596 | entities: [],
|
4597 | header: {},
|
4598 | tables: {}
|
4599 | };
|
4600 | MakerJs.extendObject(opts, options);
|
4601 | if (MakerJs.isModel(itemToExport)) {
|
4602 | var modelToExport = itemToExport;
|
4603 | if (modelToExport.exporterOptions) {
|
4604 | MakerJs.extendObject(opts, modelToExport.exporterOptions['toDXF']);
|
4605 | }
|
4606 | }
|
4607 | function colorLayerOptions(layer) {
|
4608 | if (opts.layerOptions && opts.layerOptions[layer])
|
4609 | return opts.layerOptions[layer];
|
4610 | if (layer in exporter.colors) {
|
4611 | return {
|
4612 | color: exporter.colors[layer]
|
4613 | };
|
4614 | }
|
4615 | }
|
4616 | function defaultLayer(pathContext, parentLayer) {
|
4617 | var layerId = (pathContext && pathContext.layer) || parentLayer || '0';
|
4618 | if (layerIds.indexOf(layerId) < 0) {
|
4619 | layerIds.push(layerId);
|
4620 | }
|
4621 | return layerId;
|
4622 | }
|
4623 | var map = {};
|
4624 | map[MakerJs.pathType.Line] = function (line, offset, layer) {
|
4625 | var lineEntity = {
|
4626 | type: "LINE",
|
4627 | layer: defaultLayer(line, layer),
|
4628 | vertices: [
|
4629 | {
|
4630 | x: MakerJs.round(line.origin[0] + offset[0], opts.accuracy),
|
4631 | y: MakerJs.round(line.origin[1] + offset[1], opts.accuracy)
|
4632 | },
|
4633 | {
|
4634 | x: MakerJs.round(line.end[0] + offset[0], opts.accuracy),
|
4635 | y: MakerJs.round(line.end[1] + offset[1], opts.accuracy)
|
4636 | }
|
4637 | ]
|
4638 | };
|
4639 | return lineEntity;
|
4640 | };
|
4641 | map[MakerJs.pathType.Circle] = function (circle, offset, layer) {
|
4642 | var circleEntity = {
|
4643 | type: "CIRCLE",
|
4644 | layer: defaultLayer(circle, layer),
|
4645 | center: {
|
4646 | x: MakerJs.round(circle.origin[0] + offset[0], opts.accuracy),
|
4647 | y: MakerJs.round(circle.origin[1] + offset[1], opts.accuracy)
|
4648 | },
|
4649 | radius: MakerJs.round(circle.radius, opts.accuracy)
|
4650 | };
|
4651 | return circleEntity;
|
4652 | };
|
4653 | map[MakerJs.pathType.Arc] = function (arc, offset, layer) {
|
4654 | var arcEntity = {
|
4655 | type: "ARC",
|
4656 | layer: defaultLayer(arc, layer),
|
4657 | center: {
|
4658 | x: MakerJs.round(arc.origin[0] + offset[0], opts.accuracy),
|
4659 | y: MakerJs.round(arc.origin[1] + offset[1], opts.accuracy)
|
4660 | },
|
4661 | radius: MakerJs.round(arc.radius, opts.accuracy),
|
4662 | startAngle: MakerJs.round(arc.startAngle, opts.accuracy),
|
4663 | endAngle: MakerJs.round(arc.endAngle, opts.accuracy)
|
4664 | };
|
4665 | return arcEntity;
|
4666 | };
|
4667 |
|
4668 |
|
4669 | function appendVertex(v, layer, bulge) {
|
4670 | var vertex = {
|
4671 | type: "VERTEX",
|
4672 | layer: defaultLayer(null, layer),
|
4673 | x: MakerJs.round(v[0], opts.accuracy),
|
4674 | y: MakerJs.round(v[1], opts.accuracy),
|
4675 | bulge: bulge
|
4676 | };
|
4677 | return vertex;
|
4678 | }
|
4679 | function polyline(c) {
|
4680 | var polylineEntity = {
|
4681 | type: "POLYLINE",
|
4682 | layer: defaultLayer(null, c.layer),
|
4683 | shape: c.chain.endless,
|
4684 | vertices: []
|
4685 | };
|
4686 | c.chain.links.forEach(function (link, i) {
|
4687 | var bulge;
|
4688 | if (link.walkedPath.pathContext.type === MakerJs.pathType.Arc) {
|
4689 | var arc = link.walkedPath.pathContext;
|
4690 | bulge = MakerJs.round(Math.tan(MakerJs.angle.toRadians(MakerJs.angle.ofArcSpan(arc)) / 4), opts.accuracy);
|
4691 | if (link.reversed) {
|
4692 | bulge *= -1;
|
4693 | }
|
4694 | }
|
4695 | var vertex = link.endPoints[link.reversed ? 1 : 0];
|
4696 | polylineEntity.vertices.push(appendVertex(vertex, c.layer, bulge));
|
4697 | });
|
4698 | if (!c.chain.endless) {
|
4699 | var lastLink = c.chain.links[c.chain.links.length - 1];
|
4700 | var endPoint = lastLink.endPoints[lastLink.reversed ? 0 : 1];
|
4701 | polylineEntity.vertices.push(appendVertex(endPoint, c.layer));
|
4702 | }
|
4703 | return polylineEntity;
|
4704 | }
|
4705 | function mtext(caption) {
|
4706 | var center = MakerJs.point.middle(caption.anchor);
|
4707 | var mtextEntity = {
|
4708 | type: "MTEXT",
|
4709 | position: {
|
4710 | x: MakerJs.round(center[0], opts.accuracy),
|
4711 | y: MakerJs.round(center[1], opts.accuracy)
|
4712 | },
|
4713 | height: opts.fontSize,
|
4714 | text: caption.text,
|
4715 | attachmentPoint: 5,
|
4716 | drawingDirection: 1,
|
4717 | rotation: MakerJs.angle.ofPointInRadians(caption.anchor.origin, caption.anchor.end)
|
4718 | };
|
4719 | return mtextEntity;
|
4720 | }
|
4721 | function layerOut(layerId, layerColor) {
|
4722 | var layerEntity = {
|
4723 | name: layerId,
|
4724 | color: layerColor
|
4725 | };
|
4726 | return layerEntity;
|
4727 | }
|
4728 | function lineTypesOut() {
|
4729 | var lineStyleTable = {
|
4730 | lineTypes: {
|
4731 | "CONTINUOUS": {
|
4732 | name: "CONTINUOUS",
|
4733 | description: "______",
|
4734 | patternLength: 0
|
4735 | }
|
4736 | }
|
4737 | };
|
4738 | var tableName = 'lineType';
|
4739 | doc.tables[tableName] = lineStyleTable;
|
4740 | }
|
4741 | function layersOut() {
|
4742 | var layerTable = {
|
4743 | layers: {}
|
4744 | };
|
4745 | layerIds.forEach(function (layerId) {
|
4746 | var layerOptions = colorLayerOptions(layerId);
|
4747 | if (layerOptions) {
|
4748 | layerTable.layers[layerId] = layerOut(layerId, layerOptions.color);
|
4749 | }
|
4750 | });
|
4751 | var tableName = 'layer';
|
4752 | doc.tables[tableName] = layerTable;
|
4753 | }
|
4754 | function header() {
|
4755 | if (opts.units) {
|
4756 | var units = dxfUnit[opts.units];
|
4757 | doc.header["$INSUNITS"] = units;
|
4758 | }
|
4759 | }
|
4760 | function entities(walkedPaths, chains, captions) {
|
4761 | var entityArray = doc.entities;
|
4762 | entityArray.push.apply(entityArray, chains.map(polyline));
|
4763 | walkedPaths.forEach(function (walkedPath) {
|
4764 | var fn = map[walkedPath.pathContext.type];
|
4765 | if (fn) {
|
4766 | var entity = fn(walkedPath.pathContext, walkedPath.offset, walkedPath.layer);
|
4767 | entityArray.push(entity);
|
4768 | }
|
4769 | });
|
4770 | entityArray.push.apply(entityArray, captions.map(mtext));
|
4771 | }
|
4772 |
|
4773 | if (!opts.units) {
|
4774 | var units = exporter.tryGetModelUnits(itemToExport);
|
4775 | if (units) {
|
4776 | opts.units = units;
|
4777 | }
|
4778 | }
|
4779 |
|
4780 | MakerJs.extendObject(options, opts);
|
4781 |
|
4782 | var chainsOnLayers = [];
|
4783 | var walkedPaths = [];
|
4784 | if (opts.usePOLYLINE) {
|
4785 | var cb = function (chains, loose, layer) {
|
4786 | chains.forEach(function (c) {
|
4787 | if (c.endless && c.links.length === 1 && c.links[0].walkedPath.pathContext.type === MakerJs.pathType.Circle) {
|
4788 |
|
4789 | walkedPaths.push(c.links[0].walkedPath);
|
4790 | return;
|
4791 | }
|
4792 | var chainOnLayer = { chain: c, layer: layer };
|
4793 | chainsOnLayers.push(chainOnLayer);
|
4794 | });
|
4795 | walkedPaths.push.apply(walkedPaths, loose);
|
4796 | };
|
4797 | MakerJs.model.findChains(modelToExport, cb, { byLayers: true, pointMatchingDistance: opts.pointMatchingDistance });
|
4798 | }
|
4799 | else {
|
4800 | var walkOptions = {
|
4801 | onPath: function (walkedPath) {
|
4802 | walkedPaths.push(walkedPath);
|
4803 | }
|
4804 | };
|
4805 | MakerJs.model.walk(modelToExport, walkOptions);
|
4806 | }
|
4807 | entities(walkedPaths, chainsOnLayers, MakerJs.model.getAllCaptionsOffset(modelToExport));
|
4808 | header();
|
4809 | lineTypesOut();
|
4810 | layersOut();
|
4811 | return outputDocument(doc);
|
4812 | }
|
4813 | exporter.toDXF = toDXF;
|
4814 | |
4815 |
|
4816 |
|
4817 | function outputDocument(doc) {
|
4818 | var dxf = [];
|
4819 | function append() {
|
4820 | var values = [];
|
4821 | for (var _i = 0; _i < arguments.length; _i++) {
|
4822 | values[_i] = arguments[_i];
|
4823 | }
|
4824 | dxf.push.apply(dxf, values);
|
4825 | }
|
4826 | var map = {};
|
4827 | map["LINE"] = function (line) {
|
4828 | append("0", "LINE", "8", line.layer, "10", line.vertices[0].x, "20", line.vertices[0].y, "11", line.vertices[1].x, "21", line.vertices[1].y);
|
4829 | };
|
4830 | map["CIRCLE"] = function (circle) {
|
4831 | append("0", "CIRCLE", "8", circle.layer, "10", circle.center.x, "20", circle.center.y, "40", circle.radius);
|
4832 | };
|
4833 | map["ARC"] = function (arc) {
|
4834 | append("0", "ARC", "8", arc.layer, "10", arc.center.x, "20", arc.center.y, "40", arc.radius, "50", arc.startAngle, "51", arc.endAngle);
|
4835 | };
|
4836 |
|
4837 |
|
4838 | map["VERTEX"] = function (vertex) {
|
4839 | append("0", "VERTEX", "8", vertex.layer, "10", vertex.x, "20", vertex.y);
|
4840 | if (vertex.bulge !== undefined) {
|
4841 | append("42", vertex.bulge);
|
4842 | }
|
4843 | };
|
4844 | map["POLYLINE"] = function (polyline) {
|
4845 | append("0", "POLYLINE", "8", polyline.layer, "66", 1, "70", polyline.shape ? 1 : 0);
|
4846 | polyline.vertices.forEach(function (vertex) { return map["VERTEX"](vertex); });
|
4847 | append("0", "SEQEND");
|
4848 | };
|
4849 | map["MTEXT"] = function (mtext) {
|
4850 | append("0", "MTEXT", "10", mtext.position.x, "20", mtext.position.y, "40", mtext.height, "71", mtext.attachmentPoint, "72", mtext.drawingDirection, "1", mtext.text,
|
4851 | "50", mtext.rotation);
|
4852 | };
|
4853 | function section(sectionFn) {
|
4854 | append("0", "SECTION");
|
4855 | sectionFn();
|
4856 | append("0", "ENDSEC");
|
4857 | }
|
4858 | function table(fn) {
|
4859 | append("0", "TABLE");
|
4860 | fn();
|
4861 | append("0", "ENDTAB");
|
4862 | }
|
4863 | function tables() {
|
4864 | append("2", "TABLES");
|
4865 | table(lineTypesOut);
|
4866 | table(layersOut);
|
4867 | }
|
4868 | function layerOut(layer) {
|
4869 | append("0", "LAYER", "2", layer.name, "70", "0", "62", layer.color, "6", "CONTINUOUS");
|
4870 | }
|
4871 | function lineTypeOut(lineType) {
|
4872 | append("0", "LTYPE", "72",
|
4873 | "65", "70", "64", "2", lineType.name, "3", lineType.description, "73", "0", "40", lineType.patternLength);
|
4874 | }
|
4875 | function lineTypesOut() {
|
4876 | var lineTypeTableName = 'lineType';
|
4877 | var lineTypeTable = doc.tables[lineTypeTableName];
|
4878 | append("2", "LTYPE");
|
4879 | for (var lineTypeId in lineTypeTable.lineTypes) {
|
4880 | var lineType = lineTypeTable.lineTypes[lineTypeId];
|
4881 | lineTypeOut(lineType);
|
4882 | }
|
4883 | }
|
4884 | function layersOut() {
|
4885 | var layerTableName = 'layer';
|
4886 | var layerTable = doc.tables[layerTableName];
|
4887 | append("2", "LAYER");
|
4888 | for (var layerId in layerTable.layers) {
|
4889 | var layer = layerTable.layers[layerId];
|
4890 | layerOut(layer);
|
4891 | }
|
4892 | }
|
4893 | function header() {
|
4894 | append("2", "HEADER");
|
4895 | for (var key in doc.header) {
|
4896 | var value = doc.header[key];
|
4897 | append("9", key, "70", value);
|
4898 | }
|
4899 | }
|
4900 | function entities(entityArray) {
|
4901 | append("2", "ENTITIES");
|
4902 | entityArray.forEach(function (entity) {
|
4903 | var fn = map[entity.type];
|
4904 | if (fn) {
|
4905 | fn(entity);
|
4906 | }
|
4907 | });
|
4908 | }
|
4909 |
|
4910 | section(header);
|
4911 | section(tables);
|
4912 | section(function () { return entities(doc.entities); });
|
4913 | append("0", "EOF");
|
4914 | return dxf.join('\n');
|
4915 | }
|
4916 | |
4917 |
|
4918 |
|
4919 | var dxfUnit = {};
|
4920 |
|
4921 |
|
4922 |
|
4923 |
|
4924 | dxfUnit[''] = 0;
|
4925 | dxfUnit[MakerJs.unitType.Inch] = 1;
|
4926 | dxfUnit[MakerJs.unitType.Foot] = 2;
|
4927 | dxfUnit[MakerJs.unitType.Millimeter] = 4;
|
4928 | dxfUnit[MakerJs.unitType.Centimeter] = 5;
|
4929 | dxfUnit[MakerJs.unitType.Meter] = 6;
|
4930 | })(exporter = MakerJs.exporter || (MakerJs.exporter = {}));
|
4931 | })(MakerJs || (MakerJs = {}));
|
4932 | var MakerJs;
|
4933 | (function (MakerJs) {
|
4934 | var solvers;
|
4935 | (function (solvers) {
|
4936 | |
4937 |
|
4938 |
|
4939 | var equilateral = Math.sqrt(3) / 2;
|
4940 | |
4941 |
|
4942 |
|
4943 |
|
4944 |
|
4945 |
|
4946 | function equilateralAltitude(sideLength) {
|
4947 | return sideLength * equilateral;
|
4948 | }
|
4949 | solvers.equilateralAltitude = equilateralAltitude;
|
4950 | |
4951 |
|
4952 |
|
4953 |
|
4954 |
|
4955 |
|
4956 | function equilateralSide(altitude) {
|
4957 | return altitude / equilateral;
|
4958 | }
|
4959 | solvers.equilateralSide = equilateralSide;
|
4960 | |
4961 |
|
4962 |
|
4963 |
|
4964 |
|
4965 |
|
4966 |
|
4967 |
|
4968 | function solveTriangleSSS(lengthA, lengthB, lengthC) {
|
4969 | return MakerJs.angle.toDegrees(Math.acos((lengthB * lengthB + lengthC * lengthC - lengthA * lengthA) / (2 * lengthB * lengthC)));
|
4970 | }
|
4971 | solvers.solveTriangleSSS = solveTriangleSSS;
|
4972 | |
4973 |
|
4974 |
|
4975 |
|
4976 |
|
4977 |
|
4978 |
|
4979 |
|
4980 | function solveTriangleASA(oppositeAngleInDegrees, lengthOfSideBetweenAngles, otherAngleInDegrees) {
|
4981 | var angleOppositeSide = 180 - oppositeAngleInDegrees - otherAngleInDegrees;
|
4982 | return (lengthOfSideBetweenAngles * Math.sin(MakerJs.angle.toRadians(oppositeAngleInDegrees))) / Math.sin(MakerJs.angle.toRadians(angleOppositeSide));
|
4983 | }
|
4984 | solvers.solveTriangleASA = solveTriangleASA;
|
4985 | |
4986 |
|
4987 |
|
4988 |
|
4989 |
|
4990 |
|
4991 |
|
4992 |
|
4993 | function circleTangentAngles(a, b, inner) {
|
4994 | if (inner === void 0) { inner = false; }
|
4995 | var connect = new MakerJs.paths.Line(a.origin, b.origin);
|
4996 | var distance = MakerJs.measure.pointDistance(a.origin, b.origin);
|
4997 |
|
4998 | if (a.radius >= distance + b.radius || b.radius >= distance + a.radius)
|
4999 | return null;
|
5000 |
|
5001 | if (inner && (a.radius + b.radius >= distance))
|
5002 | return null;
|
5003 | var tangentAngles;
|
5004 | if (!inner && MakerJs.round(a.radius - b.radius) == 0) {
|
5005 | tangentAngles = [90, 270];
|
5006 | }
|
5007 | else {
|
5008 |
|
5009 | var d2 = distance / 2;
|
5010 | var between = new MakerJs.paths.Circle([d2, 0], d2);
|
5011 | var diff = new MakerJs.paths.Circle(a.radius > b.radius ? [0, 0] : [distance, 0], inner ? (a.radius + b.radius) : Math.abs(a.radius - b.radius));
|
5012 | var int = MakerJs.path.intersection(diff, between);
|
5013 | if (!int || !int.path1Angles)
|
5014 | return null;
|
5015 | tangentAngles = int.path1Angles;
|
5016 | }
|
5017 | var connectAngle = MakerJs.angle.ofLineInDegrees(connect);
|
5018 |
|
5019 | return tangentAngles.map(function (a) { return MakerJs.angle.noRevolutions(a + connectAngle); });
|
5020 | }
|
5021 | solvers.circleTangentAngles = circleTangentAngles;
|
5022 | })(solvers = MakerJs.solvers || (MakerJs.solvers = {}));
|
5023 | })(MakerJs || (MakerJs = {}));
|
5024 | var MakerJs;
|
5025 | (function (MakerJs) {
|
5026 | var path;
|
5027 | (function (path) {
|
5028 | |
5029 |
|
5030 |
|
5031 | var map = {};
|
5032 | map[MakerJs.pathType.Arc] = {};
|
5033 | map[MakerJs.pathType.Circle] = {};
|
5034 | map[MakerJs.pathType.Line] = {};
|
5035 | map[MakerJs.pathType.Arc][MakerJs.pathType.Arc] = function (arc1, arc2, options, swapOffsets) {
|
5036 | var result = null;
|
5037 | moveTemp([arc1, arc2], options, swapOffsets, function () {
|
5038 | var angles = circleToCircle(arc1, arc2, options);
|
5039 | if (angles) {
|
5040 | var arc1Angles = getAnglesWithinArc(angles[0], arc1, options);
|
5041 | var arc2Angles = getAnglesWithinArc(angles[1], arc2, options);
|
5042 | if (arc1Angles && arc2Angles) {
|
5043 |
|
5044 | if (arc1Angles.length === 1 || arc2Angles.length === 1) {
|
5045 | for (var i1 = 0; i1 < arc1Angles.length; i1++) {
|
5046 | for (var i2 = 0; i2 < arc2Angles.length; i2++) {
|
5047 | var p1 = MakerJs.point.fromAngleOnCircle(arc1Angles[i1], arc1);
|
5048 | var p2 = MakerJs.point.fromAngleOnCircle(arc2Angles[i2], arc2);
|
5049 |
|
5050 | if (MakerJs.measure.isPointEqual(p1, p2, .0001)) {
|
5051 | result = {
|
5052 | intersectionPoints: [p1],
|
5053 | path1Angles: [arc1Angles[i1]],
|
5054 | path2Angles: [arc2Angles[i2]]
|
5055 | };
|
5056 | return;
|
5057 | }
|
5058 | }
|
5059 | }
|
5060 | }
|
5061 | else {
|
5062 | result = {
|
5063 | intersectionPoints: pointsFromAnglesOnCircle(arc1Angles, arc1),
|
5064 | path1Angles: arc1Angles,
|
5065 | path2Angles: arc2Angles
|
5066 | };
|
5067 | }
|
5068 | }
|
5069 | }
|
5070 | else {
|
5071 | if (options.out_AreOverlapped) {
|
5072 |
|
5073 | options.out_AreOverlapped = MakerJs.measure.isArcOverlapping(arc1, arc2, options.excludeTangents);
|
5074 | }
|
5075 | }
|
5076 | });
|
5077 | return result;
|
5078 | };
|
5079 | map[MakerJs.pathType.Arc][MakerJs.pathType.Circle] = function (arc, circle, options, swapOffsets) {
|
5080 | var result = null;
|
5081 | moveTemp([arc, circle], options, swapOffsets, function () {
|
5082 | var angles = circleToCircle(arc, circle, options);
|
5083 | if (angles) {
|
5084 | var arcAngles = getAnglesWithinArc(angles[0], arc, options);
|
5085 | if (arcAngles) {
|
5086 | var circleAngles;
|
5087 |
|
5088 | if (arcAngles.length == 2) {
|
5089 | circleAngles = angles[1];
|
5090 | }
|
5091 | else {
|
5092 |
|
5093 | var index = findCorrespondingAngleIndex(angles[0], arcAngles[0]);
|
5094 | circleAngles = [angles[1][index]];
|
5095 | }
|
5096 | result = {
|
5097 | intersectionPoints: pointsFromAnglesOnCircle(arcAngles, arc),
|
5098 | path1Angles: arcAngles,
|
5099 | path2Angles: circleAngles
|
5100 | };
|
5101 | }
|
5102 | }
|
5103 | });
|
5104 | return result;
|
5105 | };
|
5106 | map[MakerJs.pathType.Arc][MakerJs.pathType.Line] = function (arc, line, options, swapOffsets) {
|
5107 | var result = null;
|
5108 | moveTemp([arc, line], options, swapOffsets, function () {
|
5109 | var angles = lineToCircle(line, arc, options);
|
5110 | if (angles) {
|
5111 | var arcAngles = getAnglesWithinArc(angles, arc, options);
|
5112 | if (arcAngles) {
|
5113 | result = {
|
5114 | intersectionPoints: pointsFromAnglesOnCircle(arcAngles, arc),
|
5115 | path1Angles: arcAngles
|
5116 | };
|
5117 | }
|
5118 | }
|
5119 | });
|
5120 | return result;
|
5121 | };
|
5122 | map[MakerJs.pathType.Circle][MakerJs.pathType.Arc] = function (circle, arc, options) {
|
5123 | var result = map[MakerJs.pathType.Arc][MakerJs.pathType.Circle](arc, circle, options, true);
|
5124 | if (result) {
|
5125 | return swapAngles(result);
|
5126 | }
|
5127 | return null;
|
5128 | };
|
5129 | map[MakerJs.pathType.Circle][MakerJs.pathType.Circle] = function (circle1, circle2, options, swapOffsets) {
|
5130 | var result = null;
|
5131 | moveTemp([circle1, circle2], options, swapOffsets, function () {
|
5132 | var angles = circleToCircle(circle1, circle2, options);
|
5133 | if (angles) {
|
5134 | result = {
|
5135 | intersectionPoints: pointsFromAnglesOnCircle(angles[0], circle1),
|
5136 | path1Angles: angles[0],
|
5137 | path2Angles: angles[1]
|
5138 | };
|
5139 | }
|
5140 | });
|
5141 | return result;
|
5142 | };
|
5143 | map[MakerJs.pathType.Circle][MakerJs.pathType.Line] = function (circle, line, options, swapOffsets) {
|
5144 | var result = null;
|
5145 | moveTemp([circle, line], options, swapOffsets, function () {
|
5146 | var angles = lineToCircle(line, circle, options);
|
5147 | if (angles) {
|
5148 | result = {
|
5149 | intersectionPoints: pointsFromAnglesOnCircle(angles, circle),
|
5150 | path1Angles: angles
|
5151 | };
|
5152 | }
|
5153 | });
|
5154 | return result;
|
5155 | };
|
5156 | map[MakerJs.pathType.Line][MakerJs.pathType.Arc] = function (line, arc, options) {
|
5157 | var result = map[MakerJs.pathType.Arc][MakerJs.pathType.Line](arc, line, options, true);
|
5158 | if (result) {
|
5159 | return swapAngles(result);
|
5160 | }
|
5161 | return null;
|
5162 | };
|
5163 | map[MakerJs.pathType.Line][MakerJs.pathType.Circle] = function (line, circle, options) {
|
5164 | var result = map[MakerJs.pathType.Circle][MakerJs.pathType.Line](circle, line, options, true);
|
5165 | if (result) {
|
5166 | return swapAngles(result);
|
5167 | }
|
5168 | return null;
|
5169 | };
|
5170 | map[MakerJs.pathType.Line][MakerJs.pathType.Line] = function (line1, line2, options, swapOffsets) {
|
5171 | var result = null;
|
5172 | moveTemp([line1, line2], options, swapOffsets, function () {
|
5173 | var intersectionPoint = MakerJs.point.fromSlopeIntersection(line1, line2, options);
|
5174 | if (intersectionPoint) {
|
5175 |
|
5176 | if (MakerJs.measure.isBetweenPoints(intersectionPoint, line1, options.excludeTangents) && MakerJs.measure.isBetweenPoints(intersectionPoint, line2, options.excludeTangents)) {
|
5177 | result = {
|
5178 | intersectionPoints: [intersectionPoint]
|
5179 | };
|
5180 | }
|
5181 | }
|
5182 | });
|
5183 | return result;
|
5184 | };
|
5185 | |
5186 |
|
5187 |
|
5188 | function moveTemp(pathsToOffset, options, swapOffsets, task) {
|
5189 | var offsets = swapOffsets ? [options.path2Offset, options.path1Offset] : [options.path1Offset, options.path2Offset];
|
5190 | path.moveTemporary(pathsToOffset, offsets, task);
|
5191 | }
|
5192 | ;
|
5193 | |
5194 |
|
5195 |
|
5196 | function swapAngles(result) {
|
5197 | var temp = result.path1Angles;
|
5198 | if (result.path2Angles) {
|
5199 | result.path1Angles = result.path2Angles;
|
5200 | }
|
5201 | else {
|
5202 | delete result.path1Angles;
|
5203 | }
|
5204 | if (temp) {
|
5205 | result.path2Angles = temp;
|
5206 | }
|
5207 | return result;
|
5208 | }
|
5209 | |
5210 |
|
5211 |
|
5212 |
|
5213 |
|
5214 |
|
5215 |
|
5216 |
|
5217 | function intersection(path1, path2, options) {
|
5218 | if (options === void 0) { options = {}; }
|
5219 | if (path1 && path2) {
|
5220 | var fn = map[path1.type][path2.type];
|
5221 | if (fn) {
|
5222 | return fn(path1, path2, options);
|
5223 | }
|
5224 | }
|
5225 | return null;
|
5226 | }
|
5227 | path.intersection = intersection;
|
5228 | |
5229 |
|
5230 |
|
5231 | function findCorrespondingAngleIndex(circleAngles, arcAngle) {
|
5232 | for (var i = 2; i--;) {
|
5233 | if (circleAngles[i] === arcAngle)
|
5234 | return i;
|
5235 | }
|
5236 | }
|
5237 | |
5238 |
|
5239 |
|
5240 | function pointsFromAnglesOnCircle(anglesInDegrees, circle) {
|
5241 | var result = [];
|
5242 | for (var i = 0; i < anglesInDegrees.length; i++) {
|
5243 | result.push(MakerJs.point.fromAngleOnCircle(anglesInDegrees[i], circle));
|
5244 | }
|
5245 | return result;
|
5246 | }
|
5247 | |
5248 |
|
5249 |
|
5250 | function getAnglesWithinArc(angles, arc, options) {
|
5251 | if (!angles)
|
5252 | return null;
|
5253 | var anglesWithinArc = [];
|
5254 | for (var i = 0; i < angles.length; i++) {
|
5255 | if (MakerJs.measure.isBetweenArcAngles(angles[i], arc, options.excludeTangents)) {
|
5256 | anglesWithinArc.push(angles[i]);
|
5257 | }
|
5258 | }
|
5259 | if (anglesWithinArc.length == 0)
|
5260 | return null;
|
5261 | return anglesWithinArc;
|
5262 | }
|
5263 | |
5264 |
|
5265 |
|
5266 | function lineToCircle(line, circle, options) {
|
5267 | var radius = MakerJs.round(circle.radius);
|
5268 |
|
5269 | if (circle.radius <= 0) {
|
5270 | return null;
|
5271 | }
|
5272 |
|
5273 | var clonedLine = new MakerJs.paths.Line(MakerJs.point.subtract(line.origin, circle.origin), MakerJs.point.subtract(line.end, circle.origin));
|
5274 |
|
5275 | var lineAngleNormal = MakerJs.angle.ofLineInDegrees(line);
|
5276 |
|
5277 | var lineAngle = (lineAngleNormal >= 180) ? lineAngleNormal - 360 : lineAngleNormal;
|
5278 |
|
5279 | path.rotate(clonedLine, -lineAngle, MakerJs.point.zero());
|
5280 |
|
5281 | function unRotate(resultAngle) {
|
5282 | var unrotated = resultAngle + lineAngle;
|
5283 | return MakerJs.round(MakerJs.angle.noRevolutions(unrotated));
|
5284 | }
|
5285 |
|
5286 | var lineY = MakerJs.round(clonedLine.origin[1]);
|
5287 | var lineYabs = Math.abs(lineY);
|
5288 |
|
5289 | if (lineYabs > radius) {
|
5290 | return null;
|
5291 | }
|
5292 | var anglesOfIntersection = [];
|
5293 |
|
5294 | if (lineYabs == radius) {
|
5295 | if (options.excludeTangents) {
|
5296 | return null;
|
5297 | }
|
5298 | anglesOfIntersection.push(unRotate(lineY > 0 ? 90 : 270));
|
5299 | }
|
5300 | else {
|
5301 | function intersectionBetweenEndpoints(x, angleOfX) {
|
5302 | if (MakerJs.measure.isBetween(MakerJs.round(x), MakerJs.round(clonedLine.origin[0]), MakerJs.round(clonedLine.end[0]), options.excludeTangents)) {
|
5303 | anglesOfIntersection.push(unRotate(angleOfX));
|
5304 | }
|
5305 | }
|
5306 |
|
5307 | var intersectRadians = Math.asin(lineY / radius);
|
5308 | var intersectDegrees = MakerJs.angle.toDegrees(intersectRadians);
|
5309 |
|
5310 | var intersectX = Math.cos(intersectRadians) * radius;
|
5311 | intersectionBetweenEndpoints(-intersectX, 180 - intersectDegrees);
|
5312 | intersectionBetweenEndpoints(intersectX, intersectDegrees);
|
5313 | }
|
5314 | if (anglesOfIntersection.length > 0) {
|
5315 | return anglesOfIntersection;
|
5316 | }
|
5317 | return null;
|
5318 | }
|
5319 | |
5320 |
|
5321 |
|
5322 | function circleToCircle(circle1, circle2, options) {
|
5323 |
|
5324 | if (circle1.radius <= 0 || circle2.radius <= 0) {
|
5325 | return null;
|
5326 | }
|
5327 |
|
5328 | if (circle1.radius == circle2.radius && MakerJs.measure.isPointEqual(circle1.origin, circle2.origin, .0001)) {
|
5329 | options.out_AreOverlapped = true;
|
5330 | return null;
|
5331 | }
|
5332 |
|
5333 | var offset = MakerJs.point.subtract(MakerJs.point.zero(), circle1.origin);
|
5334 |
|
5335 | var c1 = new MakerJs.paths.Circle(MakerJs.point.zero(), circle1.radius);
|
5336 |
|
5337 | var c2 = new MakerJs.paths.Circle(MakerJs.point.subtract(circle2.origin, circle1.origin), circle2.radius);
|
5338 |
|
5339 | var c2Angle = MakerJs.angle.ofPointInDegrees(MakerJs.point.zero(), c2.origin);
|
5340 | path.rotate(c2, -c2Angle, MakerJs.point.zero());
|
5341 | function unRotate(resultAngle) {
|
5342 | var unrotated = resultAngle + c2Angle;
|
5343 | return MakerJs.angle.noRevolutions(unrotated);
|
5344 | }
|
5345 |
|
5346 | var x = c2.origin[0];
|
5347 |
|
5348 | if (MakerJs.round(c2.radius - x - c1.radius) == 0) {
|
5349 | if (options.excludeTangents) {
|
5350 | return null;
|
5351 | }
|
5352 | return [[unRotate(180)], [unRotate(180)]];
|
5353 | }
|
5354 |
|
5355 | if (MakerJs.round(c2.radius + x - c1.radius) == 0) {
|
5356 | if (options.excludeTangents) {
|
5357 | return null;
|
5358 | }
|
5359 | return [[unRotate(0)], [unRotate(0)]];
|
5360 | }
|
5361 |
|
5362 | if (MakerJs.round(x - c2.radius - c1.radius) == 0) {
|
5363 | if (options.excludeTangents) {
|
5364 | return null;
|
5365 | }
|
5366 | return [[unRotate(0)], [unRotate(180)]];
|
5367 | }
|
5368 |
|
5369 | if (MakerJs.round(x - c2.radius) > c1.radius) {
|
5370 | return null;
|
5371 | }
|
5372 |
|
5373 | if (MakerJs.round(x + c2.radius) < c1.radius) {
|
5374 | return null;
|
5375 | }
|
5376 |
|
5377 | if (MakerJs.round(x - c2.radius) < -c1.radius) {
|
5378 | return null;
|
5379 | }
|
5380 | function bothAngles(oneAngle) {
|
5381 | return [unRotate(oneAngle), unRotate(MakerJs.angle.mirror(oneAngle, false, true))];
|
5382 | }
|
5383 | var c1IntersectionAngle = MakerJs.solvers.solveTriangleSSS(c2.radius, c1.radius, x);
|
5384 | var c2IntersectionAngle = MakerJs.solvers.solveTriangleSSS(c1.radius, x, c2.radius);
|
5385 | return [bothAngles(c1IntersectionAngle), bothAngles(180 - c2IntersectionAngle)];
|
5386 | }
|
5387 | })(path = MakerJs.path || (MakerJs.path = {}));
|
5388 | })(MakerJs || (MakerJs = {}));
|
5389 | var MakerJs;
|
5390 | (function (MakerJs) {
|
5391 | var path;
|
5392 | (function (path) {
|
5393 | |
5394 |
|
5395 |
|
5396 | var propertyNamesMap = {};
|
5397 | propertyNamesMap[MakerJs.pathType.Arc] = function (arc) {
|
5398 | return ['startAngle', 'endAngle'];
|
5399 | };
|
5400 | propertyNamesMap[MakerJs.pathType.Line] = function (line) {
|
5401 | return ['origin', 'end'];
|
5402 | };
|
5403 | |
5404 |
|
5405 |
|
5406 | function getPointProperties(pathToInspect) {
|
5407 | var points = MakerJs.point.fromPathEnds(pathToInspect);
|
5408 | if (points) {
|
5409 | function pointProperty(index) {
|
5410 | return { point: points[index], propertyName: propertyNames[index] };
|
5411 | }
|
5412 | var propertyNames = null;
|
5413 | var fn = propertyNamesMap[pathToInspect.type];
|
5414 | if (fn) {
|
5415 | propertyNames = fn(pathToInspect);
|
5416 | return [pointProperty(0), pointProperty(1)];
|
5417 | }
|
5418 | }
|
5419 | return null;
|
5420 | }
|
5421 | |
5422 |
|
5423 |
|
5424 | function getMatchingPointProperties(pathA, pathB, options) {
|
5425 | var pathAProperties = getPointProperties(pathA);
|
5426 | var pathBProperties = getPointProperties(pathB);
|
5427 | var result = null;
|
5428 | function makeMatch(pathContext, pointProperties, index) {
|
5429 | return {
|
5430 | path: pathContext,
|
5431 | isStart: index == 0,
|
5432 | propertyName: pointProperties[index].propertyName,
|
5433 | point: pointProperties[index].point,
|
5434 | oppositePoint: pointProperties[1 - index].point
|
5435 | };
|
5436 | }
|
5437 | function check(iA, iB) {
|
5438 | if (MakerJs.measure.isPointEqual(pathAProperties[iA].point, pathBProperties[iB].point, .0001)) {
|
5439 | result = [
|
5440 | makeMatch(pathA, pathAProperties, iA),
|
5441 | makeMatch(pathB, pathBProperties, iB)
|
5442 | ];
|
5443 | return true;
|
5444 | }
|
5445 | return false;
|
5446 | }
|
5447 | check(0, 0) || check(0, 1) || check(1, 0) || check(1, 1);
|
5448 | return result;
|
5449 | }
|
5450 | |
5451 |
|
5452 |
|
5453 | function populateShardPointsFromReferenceCircle(filletRadius, center, properties, options) {
|
5454 | var referenceCircle = new MakerJs.paths.Circle(center, filletRadius);
|
5455 |
|
5456 | for (var i = 0; i < 2; i++) {
|
5457 | var circleIntersection = path.intersection(referenceCircle, properties[i].path);
|
5458 | if (!circleIntersection) {
|
5459 | return false;
|
5460 | }
|
5461 | properties[i].shardPoint = circleIntersection.intersectionPoints[0];
|
5462 | if (MakerJs.measure.isPointEqual(properties[i].point, circleIntersection.intersectionPoints[0], .0001)) {
|
5463 | if (circleIntersection.intersectionPoints.length > 1) {
|
5464 | properties[i].shardPoint = circleIntersection.intersectionPoints[1];
|
5465 | }
|
5466 | else {
|
5467 | return false;
|
5468 | }
|
5469 | }
|
5470 | }
|
5471 | return true;
|
5472 | }
|
5473 | |
5474 |
|
5475 |
|
5476 | function cloneAndBreakPath(pathToShard, shardPoint) {
|
5477 | var shardStart = path.clone(pathToShard);
|
5478 | var shardEnd = path.breakAtPoint(shardStart, shardPoint);
|
5479 | return [shardStart, shardEnd];
|
5480 | }
|
5481 | |
5482 |
|
5483 |
|
5484 | var guidePathMap = {};
|
5485 | guidePathMap[MakerJs.pathType.Arc] = function (arc, filletRadius, nearPoint, shardPoint, isStart) {
|
5486 | var guideRadius = arc.radius;
|
5487 |
|
5488 | var guideArcShard = cloneAndBreakPath(arc, shardPoint)[isStart ? 0 : 1];
|
5489 | if (guideArcShard) {
|
5490 | if (MakerJs.measure.isArcConcaveTowardsPoint(guideArcShard, nearPoint)) {
|
5491 | guideRadius -= filletRadius;
|
5492 | }
|
5493 | else {
|
5494 | guideRadius += filletRadius;
|
5495 | }
|
5496 | if (MakerJs.round(guideRadius) <= 0)
|
5497 | return null;
|
5498 | return new MakerJs.paths.Arc(arc.origin, guideRadius, arc.startAngle, arc.endAngle);
|
5499 | }
|
5500 | return null;
|
5501 | };
|
5502 | guidePathMap[MakerJs.pathType.Line] = function (line, filletRadius, nearPoint, shardPoint, isStart) {
|
5503 | return new MakerJs.paths.Parallel(line, filletRadius, nearPoint);
|
5504 | };
|
5505 | |
5506 |
|
5507 |
|
5508 | function getGuidePath(context, filletRadius, nearPoint) {
|
5509 | var result = null;
|
5510 | var fn = guidePathMap[context.path.type];
|
5511 | if (fn) {
|
5512 | result = fn(context.path, filletRadius, nearPoint, context.shardPoint, context.isStart);
|
5513 | }
|
5514 | return result;
|
5515 | }
|
5516 | |
5517 |
|
5518 |
|
5519 | var filletResultMap = {};
|
5520 | filletResultMap[MakerJs.pathType.Arc] = function (arc, propertyName, filletRadius, filletCenter) {
|
5521 | var guideLine = new MakerJs.paths.Line(arc.origin, filletCenter);
|
5522 | var guideLineAngle = MakerJs.angle.ofLineInDegrees(guideLine);
|
5523 | var filletAngle = guideLineAngle;
|
5524 |
|
5525 | if (!MakerJs.measure.isArcConcaveTowardsPoint(arc, filletCenter)) {
|
5526 | filletAngle += 180;
|
5527 | }
|
5528 | return {
|
5529 | filletAngle: MakerJs.angle.noRevolutions(filletAngle),
|
5530 | clipPath: function () {
|
5531 | arc[propertyName] = guideLineAngle;
|
5532 | }
|
5533 | };
|
5534 | };
|
5535 | filletResultMap[MakerJs.pathType.Line] = function (line, propertyName, filletRadius, filletCenter) {
|
5536 |
|
5537 | var guideLine = new MakerJs.paths.Line([0, 0], [0, 1]);
|
5538 |
|
5539 | var lineAngle = MakerJs.angle.ofLineInDegrees(line);
|
5540 | path.rotate(guideLine, lineAngle, [0, 0]);
|
5541 | path.moveRelative(guideLine, filletCenter);
|
5542 |
|
5543 | var intersectionPoint = MakerJs.point.fromSlopeIntersection(line, guideLine);
|
5544 | if (intersectionPoint) {
|
5545 | return {
|
5546 | filletAngle: MakerJs.angle.ofPointInDegrees(filletCenter, intersectionPoint),
|
5547 | clipPath: function () {
|
5548 | line[propertyName] = intersectionPoint;
|
5549 | }
|
5550 | };
|
5551 | }
|
5552 | return null;
|
5553 | };
|
5554 | |
5555 |
|
5556 |
|
5557 | function getFilletResult(context, filletRadius, filletCenter) {
|
5558 | var result = null;
|
5559 | var fn = filletResultMap[context.path.type];
|
5560 | if (fn) {
|
5561 | result = fn(context.path, context.propertyName, filletRadius, filletCenter);
|
5562 | }
|
5563 | if (!testFilletResult(context, result)) {
|
5564 | result = null;
|
5565 | }
|
5566 | return result;
|
5567 | }
|
5568 | |
5569 |
|
5570 |
|
5571 | function getDogboneResult(context, filletCenter) {
|
5572 | var result = {
|
5573 | filletAngle: MakerJs.angle.ofPointInDegrees(filletCenter, context.shardPoint),
|
5574 | clipPath: function () {
|
5575 | context.path[context.propertyName] = context.shardPoint;
|
5576 | }
|
5577 | };
|
5578 | if (!testFilletResult(context, result)) {
|
5579 | result = null;
|
5580 | }
|
5581 | return result;
|
5582 | }
|
5583 | |
5584 |
|
5585 |
|
5586 | function testFilletResult(context, result) {
|
5587 | var test = false;
|
5588 | if (result) {
|
5589 |
|
5590 | var originalValue = context.path[context.propertyName];
|
5591 | result.clipPath();
|
5592 |
|
5593 | if (MakerJs.measure.pathLength(context.path) > 0) {
|
5594 | test = true;
|
5595 | }
|
5596 |
|
5597 | context.path[context.propertyName] = originalValue;
|
5598 | }
|
5599 | return test;
|
5600 | }
|
5601 | |
5602 |
|
5603 |
|
5604 | function getLineRatio(lines) {
|
5605 | var totalLength = 0;
|
5606 | var lengths = [];
|
5607 | for (var i = 0; i < lines.length; i++) {
|
5608 | var length = MakerJs.measure.pathLength(lines[i]);
|
5609 | lengths.push(length);
|
5610 | totalLength += length;
|
5611 | }
|
5612 | return lengths[0] / totalLength;
|
5613 | }
|
5614 | |
5615 |
|
5616 |
|
5617 |
|
5618 |
|
5619 |
|
5620 |
|
5621 | function dogbone(lineA, lineB, filletRadius, options) {
|
5622 |
|
5623 | if (MakerJs.isPathLine(lineA) && MakerJs.isPathLine(lineB) && filletRadius && filletRadius > 0) {
|
5624 | var opts = {
|
5625 | pointMatchingDistance: .005
|
5626 | };
|
5627 | MakerJs.extendObject(opts, options);
|
5628 |
|
5629 | var commonProperty = getMatchingPointProperties(lineA, lineB, options);
|
5630 | if (commonProperty) {
|
5631 |
|
5632 | var ratio = getLineRatio([lineA, lineB]);
|
5633 |
|
5634 | var span = new MakerJs.paths.Line(commonProperty[0].oppositePoint, commonProperty[1].oppositePoint);
|
5635 | var midRatioPoint = MakerJs.point.middle(span, ratio);
|
5636 |
|
5637 | var bisectionAngle = MakerJs.angle.ofPointInDegrees(commonProperty[0].point, midRatioPoint);
|
5638 | var center = MakerJs.point.add(commonProperty[0].point, MakerJs.point.fromPolar(MakerJs.angle.toRadians(bisectionAngle), filletRadius));
|
5639 | if (!populateShardPointsFromReferenceCircle(filletRadius, center, commonProperty, opts)) {
|
5640 | return null;
|
5641 | }
|
5642 |
|
5643 | var results = [];
|
5644 | for (var i = 0; i < 2; i++) {
|
5645 | var result = getDogboneResult(commonProperty[i], center);
|
5646 | if (!result) {
|
5647 | return null;
|
5648 | }
|
5649 | results.push(result);
|
5650 | }
|
5651 | var filletArc = new MakerJs.paths.Arc(center, filletRadius, results[0].filletAngle, results[1].filletAngle);
|
5652 |
|
5653 | if (MakerJs.round(MakerJs.angle.noRevolutions(MakerJs.angle.ofArcMiddle(filletArc))) == MakerJs.round(bisectionAngle)) {
|
5654 | filletArc.startAngle = results[1].filletAngle;
|
5655 | filletArc.endAngle = results[0].filletAngle;
|
5656 | }
|
5657 |
|
5658 | results[0].clipPath();
|
5659 | results[1].clipPath();
|
5660 | return filletArc;
|
5661 | }
|
5662 | }
|
5663 | return null;
|
5664 | }
|
5665 | path.dogbone = dogbone;
|
5666 | |
5667 |
|
5668 |
|
5669 |
|
5670 |
|
5671 |
|
5672 |
|
5673 |
|
5674 |
|
5675 | function fillet(pathA, pathB, filletRadius, options) {
|
5676 | if (pathA && pathB && filletRadius && filletRadius > 0) {
|
5677 | var opts = {
|
5678 | pointMatchingDistance: .005
|
5679 | };
|
5680 | MakerJs.extendObject(opts, options);
|
5681 |
|
5682 | var commonProperty = getMatchingPointProperties(pathA, pathB, options);
|
5683 | if (commonProperty) {
|
5684 |
|
5685 |
|
5686 | if (!populateShardPointsFromReferenceCircle(filletRadius, commonProperty[0].point, commonProperty, opts)) {
|
5687 | return null;
|
5688 | }
|
5689 |
|
5690 | var guidePaths = [];
|
5691 | for (var i = 0; i < 2; i++) {
|
5692 | var otherPathShardPoint = commonProperty[1 - i].shardPoint;
|
5693 | if (!otherPathShardPoint) {
|
5694 | return null;
|
5695 | }
|
5696 | var guidePath = getGuidePath(commonProperty[i], filletRadius, otherPathShardPoint);
|
5697 | guidePaths.push(guidePath);
|
5698 | }
|
5699 |
|
5700 | var intersectionPoint = path.intersection(guidePaths[0], guidePaths[1]);
|
5701 | if (intersectionPoint) {
|
5702 | var center;
|
5703 |
|
5704 | if (intersectionPoint.intersectionPoints.length == 1) {
|
5705 | center = intersectionPoint.intersectionPoints[0];
|
5706 | }
|
5707 | else {
|
5708 | center = MakerJs.point.closest(commonProperty[0].point, intersectionPoint.intersectionPoints);
|
5709 | }
|
5710 |
|
5711 | var results = [];
|
5712 | for (var i = 0; i < 2; i++) {
|
5713 | var result = getFilletResult(commonProperty[i], filletRadius, center);
|
5714 | if (!result) {
|
5715 | return null;
|
5716 | }
|
5717 | results.push(result);
|
5718 | }
|
5719 |
|
5720 | if (MakerJs.round(results[0].filletAngle - results[1].filletAngle) == 0)
|
5721 | return null;
|
5722 | var filletArc = new MakerJs.paths.Arc(center, filletRadius, results[0].filletAngle, results[1].filletAngle);
|
5723 | var filletSpan = MakerJs.angle.ofArcSpan(filletArc);
|
5724 |
|
5725 | if (filletSpan == 180) {
|
5726 | return null;
|
5727 | }
|
5728 | if (filletSpan > 180) {
|
5729 |
|
5730 | filletArc.startAngle = results[1].filletAngle;
|
5731 | filletArc.endAngle = results[0].filletAngle;
|
5732 | }
|
5733 |
|
5734 | results[0].clipPath();
|
5735 | results[1].clipPath();
|
5736 | return filletArc;
|
5737 | }
|
5738 | }
|
5739 | }
|
5740 | return null;
|
5741 | }
|
5742 | path.fillet = fillet;
|
5743 | })(path = MakerJs.path || (MakerJs.path = {}));
|
5744 | })(MakerJs || (MakerJs = {}));
|
5745 | (function (MakerJs) {
|
5746 | var chain;
|
5747 | (function (chain) {
|
5748 | function dogbone(chainToFillet, filletSpec) {
|
5749 | return chainFillet(false, chainToFillet, filletSpec);
|
5750 | }
|
5751 | chain.dogbone = dogbone;
|
5752 | function fillet(chainToFillet, filletSpec) {
|
5753 | return chainFillet(true, chainToFillet, filletSpec);
|
5754 | }
|
5755 | chain.fillet = fillet;
|
5756 | function chainFillet(traditional, chainToFillet, filletSpec) {
|
5757 | var result = { paths: {} };
|
5758 | var added = 0;
|
5759 | var links = chainToFillet.links;
|
5760 | function add(i1, i2) {
|
5761 | var p1 = links[i1].walkedPath, p2 = links[i2].walkedPath;
|
5762 | if (p1.modelContext === p2.modelContext && p1.modelContext.type == MakerJs.models.BezierCurve.typeName)
|
5763 | return;
|
5764 | MakerJs.path.moveTemporary([p1.pathContext, p2.pathContext], [p1.offset, p2.offset], function () {
|
5765 | var filletRadius;
|
5766 | if (MakerJs.isObject(filletSpec)) {
|
5767 | var a = MakerJs.angle.ofChainLinkJoint(links[i1], links[i2]);
|
5768 | if (MakerJs.round(a) === 0)
|
5769 | return;
|
5770 | filletRadius = (a > 0) ? filletSpec.left : filletSpec.right;
|
5771 | }
|
5772 | else {
|
5773 | filletRadius = filletSpec;
|
5774 | }
|
5775 | if (!filletRadius || filletRadius < 0)
|
5776 | return;
|
5777 | var filletArc;
|
5778 | if (traditional) {
|
5779 | filletArc = MakerJs.path.fillet(p1.pathContext, p2.pathContext, filletRadius);
|
5780 | }
|
5781 | else {
|
5782 | filletArc = MakerJs.path.dogbone(p1.pathContext, p2.pathContext, filletRadius);
|
5783 | }
|
5784 | if (filletArc) {
|
5785 | result.paths['fillet' + added] = filletArc;
|
5786 | added++;
|
5787 | }
|
5788 | });
|
5789 | }
|
5790 | for (var i = 1; i < links.length; i++) {
|
5791 | add(i - 1, i);
|
5792 | }
|
5793 | if (chainToFillet.endless) {
|
5794 | add(i - 1, 0);
|
5795 | }
|
5796 | if (!added)
|
5797 | return null;
|
5798 | return result;
|
5799 | }
|
5800 | })(chain = MakerJs.chain || (MakerJs.chain = {}));
|
5801 | })(MakerJs || (MakerJs = {}));
|
5802 | var MakerJs;
|
5803 | (function (MakerJs) {
|
5804 | var kit;
|
5805 | (function (kit) {
|
5806 |
|
5807 | |
5808 |
|
5809 |
|
5810 |
|
5811 |
|
5812 |
|
5813 |
|
5814 | function construct(ctor, args) {
|
5815 | function F() {
|
5816 | return ctor.apply(this, args);
|
5817 | }
|
5818 | F.prototype = ctor.prototype;
|
5819 | return new F();
|
5820 | }
|
5821 | kit.construct = construct;
|
5822 | |
5823 |
|
5824 |
|
5825 |
|
5826 |
|
5827 |
|
5828 | function getParameterValues(ctor) {
|
5829 | var parameters = [];
|
5830 | var metaParams = ctor.metaParameters;
|
5831 | if (metaParams) {
|
5832 | for (var i = 0; i < metaParams.length; i++) {
|
5833 | var value = metaParams[i].value;
|
5834 | if (Array.isArray(value)) {
|
5835 | value = value[0];
|
5836 | }
|
5837 | parameters.push(value);
|
5838 | }
|
5839 | }
|
5840 | return parameters;
|
5841 | }
|
5842 | kit.getParameterValues = getParameterValues;
|
5843 | })(kit = MakerJs.kit || (MakerJs.kit = {}));
|
5844 | })(MakerJs || (MakerJs = {}));
|
5845 | var MakerJs;
|
5846 | (function (MakerJs) {
|
5847 | var model;
|
5848 | (function (model) {
|
5849 | |
5850 |
|
5851 |
|
5852 | function getOpposedLink(linkedPaths, pathContext) {
|
5853 | if (linkedPaths[0].walkedPath.pathContext === pathContext) {
|
5854 | return linkedPaths[1];
|
5855 | }
|
5856 | return linkedPaths[0];
|
5857 | }
|
5858 | |
5859 |
|
5860 |
|
5861 | function followLinks(pointGraph, chainFound, chainNotFound) {
|
5862 | function followLink(currLink, chain, firstLink) {
|
5863 | while (currLink) {
|
5864 | chain.links.push(currLink);
|
5865 | chain.pathLength += currLink.pathLength;
|
5866 | var next = currLink.reversed ? 0 : 1;
|
5867 | var nextPoint = currLink.endPoints[next];
|
5868 | var nextEl = pointGraph.getElementAtPoint(nextPoint);
|
5869 | if (!nextEl || nextEl.valueIds.length === 0) {
|
5870 | break;
|
5871 | }
|
5872 | var items = nextEl.valueIds.map(function (valueIndex) { return pointGraph.values[valueIndex]; });
|
5873 | var nextLink = getOpposedLink(items, currLink.walkedPath.pathContext);
|
5874 |
|
5875 | nextEl.valueIds.splice(0, 2);
|
5876 | if (!nextLink) {
|
5877 | break;
|
5878 | }
|
5879 | if (nextLink.walkedPath.pathContext === firstLink.walkedPath.pathContext) {
|
5880 | if (chain.links.length > 1) {
|
5881 | chain.endless = true;
|
5882 | }
|
5883 | break;
|
5884 | }
|
5885 | currLink = nextLink;
|
5886 | }
|
5887 | }
|
5888 | pointGraph.forEachPoint(function (p, values, pointId, el) {
|
5889 | if (el.valueIds.length > 0) {
|
5890 | var chain = {
|
5891 | links: [],
|
5892 | pathLength: 0
|
5893 | };
|
5894 | followLink(values[0], chain, values[0]);
|
5895 | if (chain.endless) {
|
5896 | chainFound(chain, false);
|
5897 | }
|
5898 | else {
|
5899 |
|
5900 | chain.links.reverse();
|
5901 | var firstLink = chain.links[0];
|
5902 | chain.links.map(function (link) { link.reversed = !link.reversed; });
|
5903 |
|
5904 | chain.pathLength -= chain.links[chain.links.length - 1].pathLength;
|
5905 | var currLink = chain.links.pop();
|
5906 | followLink(currLink, chain, firstLink);
|
5907 | if (chain.links.length > 1) {
|
5908 | chainFound(chain, true);
|
5909 | }
|
5910 | else {
|
5911 | chainNotFound(chain.links[0].walkedPath);
|
5912 | }
|
5913 | }
|
5914 | }
|
5915 | });
|
5916 | }
|
5917 | |
5918 |
|
5919 |
|
5920 |
|
5921 |
|
5922 |
|
5923 | function findSingleChain(modelContext) {
|
5924 | var singleChain = null;
|
5925 | findChains(modelContext, function (chains, loose, layer) {
|
5926 | singleChain = chains[0];
|
5927 | }, { byLayers: false });
|
5928 | return singleChain;
|
5929 | }
|
5930 | model.findSingleChain = findSingleChain;
|
5931 | |
5932 |
|
5933 |
|
5934 | function linkEndpoint(link, beginning) {
|
5935 | var index = (beginning === link.reversed) ? 1 : 0;
|
5936 | return link.endPoints[index];
|
5937 | }
|
5938 | function findChains(modelContext) {
|
5939 | var args = [];
|
5940 | for (var _i = 1; _i < arguments.length; _i++) {
|
5941 | args[_i - 1] = arguments[_i];
|
5942 | }
|
5943 | var options;
|
5944 | var callback;
|
5945 | switch (args.length) {
|
5946 | case 1:
|
5947 | if (typeof args[0] === 'function') {
|
5948 | callback = args[0];
|
5949 | }
|
5950 | else {
|
5951 | options = args[0];
|
5952 | }
|
5953 | break;
|
5954 | case 2:
|
5955 | callback = args[0];
|
5956 | options = args[1];
|
5957 | break;
|
5958 | }
|
5959 | var opts = {
|
5960 | pointMatchingDistance: .005
|
5961 | };
|
5962 | MakerJs.extendObject(opts, options);
|
5963 | var pointGraphsByLayer = {};
|
5964 | var chainsByLayer = {};
|
5965 | var ignored = {};
|
5966 | var walkOptions = {
|
5967 | onPath: function (walkedPath) {
|
5968 | var layer = opts.byLayers ? walkedPath.layer : '';
|
5969 | if (!pointGraphsByLayer[layer]) {
|
5970 | pointGraphsByLayer[layer] = new MakerJs.PointGraph();
|
5971 | }
|
5972 | var pointGraph = pointGraphsByLayer[layer];
|
5973 | var pathLength = MakerJs.measure.pathLength(walkedPath.pathContext);
|
5974 |
|
5975 | if (walkedPath.pathContext.type === MakerJs.pathType.Circle ||
|
5976 | (walkedPath.pathContext.type === MakerJs.pathType.Arc && MakerJs.round(MakerJs.angle.ofArcSpan(walkedPath.pathContext) - 360) === 0) ||
|
5977 | (walkedPath.pathContext.type === MakerJs.pathType.BezierSeed && MakerJs.measure.isPointEqual(walkedPath.pathContext.origin, walkedPath.pathContext.end, opts.pointMatchingDistance))) {
|
5978 | var chain = {
|
5979 | links: [{
|
5980 | walkedPath: walkedPath,
|
5981 | reversed: null,
|
5982 | endPoints: null,
|
5983 | pathLength: pathLength
|
5984 | }],
|
5985 | endless: true,
|
5986 | pathLength: pathLength
|
5987 | };
|
5988 |
|
5989 | if (!chainsByLayer[layer]) {
|
5990 | chainsByLayer[layer] = [];
|
5991 | }
|
5992 | chainsByLayer[layer].push(chain);
|
5993 | }
|
5994 | else {
|
5995 |
|
5996 | if (pathLength < opts.pointMatchingDistance / 5) {
|
5997 | if (!ignored[layer]) {
|
5998 | ignored[layer] = [];
|
5999 | }
|
6000 | ignored[layer].push(walkedPath);
|
6001 | return;
|
6002 | }
|
6003 |
|
6004 | var endPoints = MakerJs.point.fromPathEnds(walkedPath.pathContext, walkedPath.offset);
|
6005 | for (var i = 0; i < 2; i++) {
|
6006 | var link = {
|
6007 | walkedPath: walkedPath,
|
6008 | endPoints: endPoints,
|
6009 | reversed: i != 0,
|
6010 | pathLength: pathLength
|
6011 | };
|
6012 | var valueId = pointGraph.insertValue(link);
|
6013 | pointGraph.insertValueIdAtPoint(valueId, endPoints[i]);
|
6014 | }
|
6015 | }
|
6016 | }
|
6017 | };
|
6018 | if (opts.shallow) {
|
6019 | walkOptions.beforeChildWalk = function () { return false; };
|
6020 | }
|
6021 | var beziers;
|
6022 | if (opts.unifyBeziers) {
|
6023 | beziers = getBezierModels(modelContext);
|
6024 | swapBezierPathsWithSeeds(beziers, true);
|
6025 | }
|
6026 | model.walk(modelContext, walkOptions);
|
6027 | var _loop_3 = function (layer_2) {
|
6028 | var pointGraph = pointGraphsByLayer[layer_2];
|
6029 | pointGraph.mergeNearestSinglePoints(opts.pointMatchingDistance);
|
6030 | loose = [];
|
6031 | if (!chainsByLayer[layer_2]) {
|
6032 | chainsByLayer[layer_2] = [];
|
6033 | }
|
6034 |
|
6035 | followLinks(pointGraph, function (chain, checkEndless) {
|
6036 | if (checkEndless) {
|
6037 | chain.endless = MakerJs.measure.isPointEqual(linkEndpoint(chain.links[0], true), linkEndpoint(chain.links[chain.links.length - 1], false), opts.pointMatchingDistance);
|
6038 | }
|
6039 | else {
|
6040 | chain.endless = !!chain.endless;
|
6041 | }
|
6042 | chainsByLayer[layer_2].push(chain);
|
6043 | }, function (walkedPath) {
|
6044 | loose.push(walkedPath);
|
6045 | });
|
6046 |
|
6047 | chainsByLayer[layer_2].sort(function (a, b) { return b.pathLength - a.pathLength; });
|
6048 | if (opts.contain) {
|
6049 | containChainsOptions = MakerJs.isObject(opts.contain) ? opts.contain : { alternateDirection: false };
|
6050 | containedChains = getContainment(chainsByLayer[layer_2], containChainsOptions);
|
6051 | chainsByLayer[layer_2] = containedChains;
|
6052 | }
|
6053 | if (callback)
|
6054 | callback(chainsByLayer[layer_2], loose, layer_2, ignored[layer_2]);
|
6055 | };
|
6056 | var loose, containChainsOptions, containedChains;
|
6057 | for (var layer_2 in pointGraphsByLayer) {
|
6058 | _loop_3(layer_2);
|
6059 | }
|
6060 | if (beziers) {
|
6061 | swapBezierPathsWithSeeds(beziers, false);
|
6062 | }
|
6063 | if (opts.byLayers) {
|
6064 | return chainsByLayer;
|
6065 | }
|
6066 | else {
|
6067 | return chainsByLayer[''];
|
6068 | }
|
6069 | }
|
6070 | model.findChains = findChains;
|
6071 | |
6072 |
|
6073 |
|
6074 | function getContainment(allChains, opts) {
|
6075 | var chainsAsModels = allChains.map(function (c) { return MakerJs.chain.toNewModel(c); });
|
6076 | var parents = [];
|
6077 |
|
6078 | allChains.forEach(function (chainContext, i1) {
|
6079 | if (!chainContext.endless)
|
6080 | return;
|
6081 | var wp = chainContext.links[0].walkedPath;
|
6082 | var firstPath = MakerJs.path.clone(wp.pathContext, wp.offset);
|
6083 | allChains.forEach(function (otherChain, i2) {
|
6084 | if (chainContext === otherChain)
|
6085 | return;
|
6086 | if (!otherChain.endless)
|
6087 | return;
|
6088 | if (MakerJs.measure.isPointInsideModel(MakerJs.point.middle(firstPath), chainsAsModels[i2])) {
|
6089 |
|
6090 | parents[i1] = otherChain;
|
6091 | }
|
6092 | });
|
6093 | });
|
6094 |
|
6095 | var result = [];
|
6096 | allChains.forEach(function (chainContext, i) {
|
6097 | var parent = parents[i];
|
6098 | if (!parent) {
|
6099 | result.push(chainContext);
|
6100 | }
|
6101 | else {
|
6102 | if (!parent.contains) {
|
6103 | parent.contains = [];
|
6104 | }
|
6105 | parent.contains.push(chainContext);
|
6106 | }
|
6107 | });
|
6108 | if (opts.alternateDirection) {
|
6109 | function alternate(chains, shouldBeClockwise) {
|
6110 | chains.forEach(function (chainContext, i) {
|
6111 | var isClockwise = MakerJs.measure.isChainClockwise(chainContext);
|
6112 | if (isClockwise !== null) {
|
6113 | if (!isClockwise && shouldBeClockwise || isClockwise && !shouldBeClockwise) {
|
6114 | MakerJs.chain.reverse(chainContext);
|
6115 | }
|
6116 | }
|
6117 | if (chainContext.contains) {
|
6118 | alternate(chainContext.contains, !shouldBeClockwise);
|
6119 | }
|
6120 | });
|
6121 | }
|
6122 | alternate(result, true);
|
6123 | }
|
6124 | return result;
|
6125 | }
|
6126 | |
6127 |
|
6128 |
|
6129 | function getBezierModels(modelContext) {
|
6130 | var beziers = [];
|
6131 | function checkIsBezier(wm) {
|
6132 | if (wm.childModel.type === MakerJs.models.BezierCurve.typeName) {
|
6133 | beziers.push(wm);
|
6134 | }
|
6135 | }
|
6136 | var options = {
|
6137 | beforeChildWalk: function (walkedModel) {
|
6138 | checkIsBezier(walkedModel);
|
6139 | return true;
|
6140 | }
|
6141 | };
|
6142 | var rootModel = {
|
6143 | childId: '',
|
6144 | childModel: modelContext,
|
6145 | layer: modelContext.layer,
|
6146 | offset: modelContext.origin,
|
6147 | parentModel: null,
|
6148 | route: [],
|
6149 | routeKey: ''
|
6150 | };
|
6151 | checkIsBezier(rootModel);
|
6152 | model.walk(modelContext, options);
|
6153 | return beziers;
|
6154 | }
|
6155 | |
6156 |
|
6157 |
|
6158 | function swapBezierPathsWithSeeds(beziers, swap) {
|
6159 | var tempKey = 'tempPaths';
|
6160 | var tempLayerKey = 'tempLayer';
|
6161 | beziers.forEach(function (wm) {
|
6162 | var b = wm.childModel;
|
6163 | if (swap) {
|
6164 |
|
6165 | if (wm.layer != undefined && wm.layer !== '') {
|
6166 | b[tempLayerKey] = b.layer;
|
6167 | b.layer = wm.layer;
|
6168 | }
|
6169 |
|
6170 | var bezierPartsByLayer = MakerJs.models.BezierCurve.getBezierSeeds(b, { byLayers: true });
|
6171 | for (var layer in bezierPartsByLayer) {
|
6172 | var bezierSeeds = bezierPartsByLayer[layer];
|
6173 | if (bezierSeeds.length > 0) {
|
6174 | b[tempKey] = b.paths;
|
6175 | var newPaths = {};
|
6176 | bezierSeeds.forEach(function (seed, i) {
|
6177 | seed.layer = layer;
|
6178 | newPaths['seed_' + i] = seed;
|
6179 | });
|
6180 | b.paths = newPaths;
|
6181 | }
|
6182 | }
|
6183 | }
|
6184 | else {
|
6185 |
|
6186 | if (tempKey in b) {
|
6187 | b.paths = b[tempKey];
|
6188 | delete b[tempKey];
|
6189 | }
|
6190 | if (tempLayerKey in b) {
|
6191 | if (b[tempLayerKey] == undefined) {
|
6192 | delete b.layer;
|
6193 | }
|
6194 | else {
|
6195 | b.layer = b[tempLayerKey];
|
6196 | }
|
6197 | delete b[tempLayerKey];
|
6198 | }
|
6199 | }
|
6200 | });
|
6201 | }
|
6202 | })(model = MakerJs.model || (MakerJs.model = {}));
|
6203 | })(MakerJs || (MakerJs = {}));
|
6204 | (function (MakerJs) {
|
6205 | var chain;
|
6206 | (function (chain) {
|
6207 | |
6208 |
|
6209 |
|
6210 |
|
6211 |
|
6212 |
|
6213 |
|
6214 | function cycle(chainContext, amount) {
|
6215 | if (amount === void 0) { amount = 1; }
|
6216 | if (!chainContext.endless)
|
6217 | return;
|
6218 | var n = Math.abs(amount);
|
6219 | for (var i = 0; i < n; i++) {
|
6220 | if (amount < 0) {
|
6221 |
|
6222 | chainContext.links.push(chainContext.links.shift());
|
6223 | }
|
6224 | else {
|
6225 |
|
6226 | chainContext.links.unshift(chainContext.links.pop());
|
6227 | }
|
6228 | }
|
6229 | return chainContext;
|
6230 | }
|
6231 | chain.cycle = cycle;
|
6232 | |
6233 |
|
6234 |
|
6235 |
|
6236 |
|
6237 |
|
6238 | function reverse(chainContext) {
|
6239 | chainContext.links.reverse();
|
6240 | chainContext.links.forEach(function (link) { return link.reversed = !link.reversed; });
|
6241 | return chainContext;
|
6242 | }
|
6243 | chain.reverse = reverse;
|
6244 | |
6245 |
|
6246 |
|
6247 |
|
6248 |
|
6249 |
|
6250 |
|
6251 | function startAt(chainContext, routeKey) {
|
6252 | if (!chainContext.endless)
|
6253 | return;
|
6254 | var index = -1;
|
6255 | for (var i = 0; i < chainContext.links.length; i++) {
|
6256 | if (chainContext.links[i].walkedPath.routeKey == routeKey) {
|
6257 | index = i;
|
6258 | break;
|
6259 | }
|
6260 | }
|
6261 | if (index > 0) {
|
6262 | cycle(chainContext, index);
|
6263 | }
|
6264 | return chainContext;
|
6265 | }
|
6266 | chain.startAt = startAt;
|
6267 | |
6268 |
|
6269 |
|
6270 |
|
6271 |
|
6272 |
|
6273 |
|
6274 | function toNewModel(chainContext, detachFromOldModel) {
|
6275 | if (detachFromOldModel === void 0) { detachFromOldModel = false; }
|
6276 | var result = { paths: {} };
|
6277 | for (var i = 0; i < chainContext.links.length; i++) {
|
6278 | var wp = chainContext.links[i].walkedPath;
|
6279 | if (wp.pathContext.type === MakerJs.pathType.BezierSeed) {
|
6280 | if (detachFromOldModel) {
|
6281 | delete wp.modelContext.paths[wp.pathId];
|
6282 | }
|
6283 | if (!result.models) {
|
6284 | result.models = {};
|
6285 | }
|
6286 | var modelId = MakerJs.model.getSimilarModelId(result, wp.pathId);
|
6287 | result.models[modelId] = MakerJs.model.moveRelative(new MakerJs.models.BezierCurve(wp.pathContext), wp.offset);
|
6288 | }
|
6289 | else {
|
6290 | var newPath;
|
6291 | if (detachFromOldModel) {
|
6292 | newPath = wp.pathContext;
|
6293 | delete wp.modelContext.paths[wp.pathId];
|
6294 | }
|
6295 | else {
|
6296 | newPath = MakerJs.path.clone(wp.pathContext);
|
6297 | }
|
6298 | var pathId = MakerJs.model.getSimilarPathId(result, wp.pathId);
|
6299 | result.paths[pathId] = MakerJs.path.moveRelative(newPath, wp.offset);
|
6300 | }
|
6301 | }
|
6302 | return result;
|
6303 | }
|
6304 | chain.toNewModel = toNewModel;
|
6305 | |
6306 |
|
6307 |
|
6308 | function removeDuplicateEnds(endless, points) {
|
6309 | if (!endless || points.length < 2)
|
6310 | return;
|
6311 | if (MakerJs.measure.isPointEqual(points[0], points[points.length - 1], .00001)) {
|
6312 | points.pop();
|
6313 | }
|
6314 | }
|
6315 | |
6316 |
|
6317 |
|
6318 |
|
6319 |
|
6320 |
|
6321 |
|
6322 |
|
6323 | function toPoints(chainContext, distanceOrDistances, maxPoints) {
|
6324 | var result = [];
|
6325 | var di = 0;
|
6326 | var t = 0;
|
6327 | var distanceArray;
|
6328 | if (Array.isArray(distanceOrDistances)) {
|
6329 | distanceArray = distanceOrDistances;
|
6330 | }
|
6331 | for (var i = 0; i < chainContext.links.length; i++) {
|
6332 | var link = chainContext.links[i];
|
6333 | var wp = link.walkedPath;
|
6334 | var len = link.pathLength;
|
6335 | while (MakerJs.round(len - t) > 0) {
|
6336 | var r = t / len;
|
6337 | if (link.reversed) {
|
6338 | r = 1 - r;
|
6339 | }
|
6340 | result.push(MakerJs.point.add(MakerJs.point.middle(wp.pathContext, r), wp.offset));
|
6341 | if (maxPoints && result.length >= maxPoints)
|
6342 | return result;
|
6343 | var distance;
|
6344 | if (distanceArray) {
|
6345 | distance = distanceArray[di];
|
6346 | di++;
|
6347 | if (di > distanceArray.length) {
|
6348 | return result;
|
6349 | }
|
6350 | }
|
6351 | else {
|
6352 | distance = distanceOrDistances;
|
6353 | }
|
6354 | t += distance;
|
6355 | }
|
6356 | t -= len;
|
6357 | }
|
6358 | removeDuplicateEnds(chainContext.endless, result);
|
6359 | return result;
|
6360 | }
|
6361 | chain.toPoints = toPoints;
|
6362 | |
6363 |
|
6364 |
|
6365 |
|
6366 |
|
6367 |
|
6368 |
|
6369 | function toKeyPoints(chainContext, maxArcFacet) {
|
6370 | var result = [];
|
6371 | for (var i = 0; i < chainContext.links.length; i++) {
|
6372 | var link = chainContext.links[i];
|
6373 | var wp = link.walkedPath;
|
6374 | var keyPoints = MakerJs.path.toKeyPoints(wp.pathContext, maxArcFacet);
|
6375 | if (keyPoints.length > 0) {
|
6376 | if (link.reversed) {
|
6377 | keyPoints.reverse();
|
6378 | }
|
6379 | if (i > 0) {
|
6380 | keyPoints.shift();
|
6381 | }
|
6382 | var offsetPathPoints = keyPoints.map(function (p) { return MakerJs.point.add(p, wp.offset); });
|
6383 | result.push.apply(result, offsetPathPoints);
|
6384 | }
|
6385 | }
|
6386 | removeDuplicateEnds(chainContext.endless, result);
|
6387 | return result;
|
6388 | }
|
6389 | chain.toKeyPoints = toKeyPoints;
|
6390 | })(chain = MakerJs.chain || (MakerJs.chain = {}));
|
6391 | })(MakerJs || (MakerJs = {}));
|
6392 | var MakerJs;
|
6393 | (function (MakerJs) {
|
6394 | var model;
|
6395 | (function (model) {
|
6396 | |
6397 |
|
6398 |
|
6399 | var DeadEndFinder = (function () {
|
6400 | function DeadEndFinder(modelContext, options) {
|
6401 | this.modelContext = modelContext;
|
6402 | this.options = options;
|
6403 | this.pointMap = new MakerJs.PointGraph();
|
6404 | this.list = [];
|
6405 | this.removed = [];
|
6406 | this.ordinals = {};
|
6407 | this.load();
|
6408 | }
|
6409 | DeadEndFinder.prototype.load = function () {
|
6410 | var _this = this;
|
6411 | var walkOptions = {
|
6412 | onPath: function (walkedPath) {
|
6413 | var endPoints = MakerJs.point.fromPathEnds(walkedPath.pathContext, walkedPath.offset);
|
6414 | if (!endPoints)
|
6415 | return;
|
6416 | var pathRef = walkedPath;
|
6417 | pathRef.endPoints = endPoints;
|
6418 | var valueId = _this.pointMap.insertValue(pathRef);
|
6419 | for (var i = 2; i--;) {
|
6420 | _this.pointMap.insertValueIdAtPoint(valueId, endPoints[i]);
|
6421 | }
|
6422 | }
|
6423 | };
|
6424 | model.walk(this.modelContext, walkOptions);
|
6425 | if (this.options.pointMatchingDistance) {
|
6426 | this.pointMap.mergePoints(this.options.pointMatchingDistance);
|
6427 | }
|
6428 | };
|
6429 | DeadEndFinder.prototype.findDeadEnds = function () {
|
6430 | var _this = this;
|
6431 | var i = 0;
|
6432 | this.pointMap.forEachPoint(function (p, values, pointId, el) {
|
6433 | _this.ordinals[pointId] = i++;
|
6434 | _this.list.push(el);
|
6435 | });
|
6436 | i = 0;
|
6437 | var _loop_4 = function () {
|
6438 | var el = this_2.list[i];
|
6439 | if (el.valueIds.length === 1) {
|
6440 | this_2.removePath(el, el.valueIds[0], i);
|
6441 | }
|
6442 | else if (this_2.options.keep && el.valueIds.length % 2) {
|
6443 | el.valueIds.forEach(function (valueId) {
|
6444 | var value = _this.pointMap.values[valueId];
|
6445 | if (!_this.options.keep(value)) {
|
6446 | _this.removePath(el, valueId, i);
|
6447 | }
|
6448 | });
|
6449 | }
|
6450 | i++;
|
6451 | };
|
6452 | var this_2 = this;
|
6453 | while (i < this.list.length) {
|
6454 | _loop_4();
|
6455 | }
|
6456 | return this.removed;
|
6457 | };
|
6458 | DeadEndFinder.prototype.removePath = function (el, valueId, current) {
|
6459 | var value = this.pointMap.values[valueId];
|
6460 | var otherPointId = this.getOtherPointId(value.endPoints, el.pointId);
|
6461 | var otherElement = this.pointMap.index[otherPointId];
|
6462 | this.removed.push(value);
|
6463 | this.removeValue(el, valueId);
|
6464 | this.removeValue(otherElement, valueId);
|
6465 | if (otherElement.valueIds.length > 0) {
|
6466 | this.appendQueue(otherElement, current);
|
6467 | }
|
6468 | };
|
6469 | DeadEndFinder.prototype.removeValue = function (el, valueId) {
|
6470 | var pos = el.valueIds.indexOf(valueId);
|
6471 | if (pos >= 0) {
|
6472 | el.valueIds.splice(pos, 1);
|
6473 | }
|
6474 | };
|
6475 | DeadEndFinder.prototype.appendQueue = function (el, current) {
|
6476 | var otherOrdinal = this.ordinals[el.pointId];
|
6477 | if (otherOrdinal < current) {
|
6478 | this.list[otherOrdinal] = null;
|
6479 | this.list.push(el);
|
6480 | this.ordinals[el.pointId] = this.list.length;
|
6481 | }
|
6482 | };
|
6483 | DeadEndFinder.prototype.getOtherPointId = function (endPoints, pointId) {
|
6484 | for (var i = 0; i < endPoints.length; i++) {
|
6485 | var id = this.pointMap.getIdOfPoint(endPoints[i]);
|
6486 | if (pointId !== id) {
|
6487 | return id;
|
6488 | }
|
6489 | }
|
6490 | };
|
6491 | return DeadEndFinder;
|
6492 | }());
|
6493 | |
6494 |
|
6495 |
|
6496 |
|
6497 |
|
6498 |
|
6499 |
|
6500 |
|
6501 |
|
6502 | function removeDeadEnds(modelContext, pointMatchingDistance, keep, trackDeleted) {
|
6503 | var options = {
|
6504 | pointMatchingDistance: pointMatchingDistance || .005,
|
6505 | keep: keep
|
6506 | };
|
6507 | var deadEndFinder = new DeadEndFinder(modelContext, options);
|
6508 | var removed = deadEndFinder.findDeadEnds();
|
6509 |
|
6510 | if (removed.length < deadEndFinder.pointMap.values.length) {
|
6511 | removed.forEach(function (wp) {
|
6512 | trackDeleted(wp, 'dead end');
|
6513 | delete wp.modelContext.paths[wp.pathId];
|
6514 | });
|
6515 | }
|
6516 | return modelContext;
|
6517 | }
|
6518 | model.removeDeadEnds = removeDeadEnds;
|
6519 | })(model = MakerJs.model || (MakerJs.model = {}));
|
6520 | })(MakerJs || (MakerJs = {}));
|
6521 | var MakerJs;
|
6522 | (function (MakerJs) {
|
6523 | var exporter;
|
6524 | (function (exporter) {
|
6525 | |
6526 |
|
6527 |
|
6528 |
|
6529 | var XmlTag = (function () {
|
6530 | |
6531 |
|
6532 |
|
6533 |
|
6534 | function XmlTag(name, attrs) {
|
6535 | this.name = name;
|
6536 | this.attrs = attrs;
|
6537 | |
6538 |
|
6539 |
|
6540 | this.innerText = '';
|
6541 | }
|
6542 | |
6543 |
|
6544 |
|
6545 |
|
6546 |
|
6547 | XmlTag.escapeString = function (value) {
|
6548 | var escape = {
|
6549 | '&': '&',
|
6550 | '<': '<',
|
6551 | '>': '>',
|
6552 | '"': '"'
|
6553 | };
|
6554 | for (var code in escape) {
|
6555 |
|
6556 | value = value.split(code).join(escape[code]);
|
6557 | }
|
6558 | return value;
|
6559 | };
|
6560 | |
6561 |
|
6562 |
|
6563 |
|
6564 |
|
6565 | XmlTag.prototype.getOpeningTag = function (selfClose) {
|
6566 | var attrs = '';
|
6567 | function outputAttr(attrName, attrValue) {
|
6568 | if (attrValue == null || typeof attrValue === 'undefined')
|
6569 | return;
|
6570 | if (Array.isArray(attrValue) || typeof attrValue === 'object') {
|
6571 | attrValue = JSON.stringify(attrValue);
|
6572 | }
|
6573 | if (typeof attrValue === 'string') {
|
6574 | attrValue = XmlTag.escapeString(attrValue);
|
6575 | }
|
6576 | attrs += ' ' + attrName + '="' + attrValue + '"';
|
6577 | }
|
6578 | for (var name in this.attrs) {
|
6579 | outputAttr(name, this.attrs[name]);
|
6580 | }
|
6581 | return '<' + this.name + attrs + (selfClose ? '/' : '') + '>';
|
6582 | };
|
6583 | |
6584 |
|
6585 |
|
6586 | XmlTag.prototype.getInnerText = function () {
|
6587 | if (this.innerTextEscaped) {
|
6588 | return this.innerText;
|
6589 | }
|
6590 | else {
|
6591 | return XmlTag.escapeString(this.innerText);
|
6592 | }
|
6593 | };
|
6594 | |
6595 |
|
6596 |
|
6597 | XmlTag.prototype.getClosingTag = function () {
|
6598 | return '</' + this.name + '>';
|
6599 | };
|
6600 | |
6601 |
|
6602 |
|
6603 | XmlTag.prototype.toString = function () {
|
6604 | var selfClose = !this.innerText;
|
6605 | if (selfClose && !this.closingTags) {
|
6606 | return this.getOpeningTag(true);
|
6607 | }
|
6608 | else {
|
6609 | return this.getOpeningTag(false) + this.getInnerText() + this.getClosingTag();
|
6610 | }
|
6611 | };
|
6612 | return XmlTag;
|
6613 | }());
|
6614 | exporter.XmlTag = XmlTag;
|
6615 | })(exporter = MakerJs.exporter || (MakerJs.exporter = {}));
|
6616 | })(MakerJs || (MakerJs = {}));
|
6617 | var MakerJs;
|
6618 | (function (MakerJs) {
|
6619 | var exporter;
|
6620 | (function (exporter) {
|
6621 | |
6622 |
|
6623 |
|
6624 | function wrap(prefix, content, condition) {
|
6625 | if (condition) {
|
6626 | return prefix + '(' + content + ')';
|
6627 | }
|
6628 | else {
|
6629 | return content;
|
6630 | }
|
6631 | }
|
6632 | |
6633 |
|
6634 |
|
6635 | function facetSizeToResolution(arcOrCircle, facetSize) {
|
6636 | if (!facetSize)
|
6637 | return;
|
6638 | var circle = new MakerJs.paths.Circle([0, 0], arcOrCircle.radius);
|
6639 | var length = MakerJs.measure.pathLength(circle);
|
6640 | if (!length)
|
6641 | return;
|
6642 | return Math.ceil(length / facetSize);
|
6643 | }
|
6644 | |
6645 |
|
6646 |
|
6647 | function chainToJscadScript(chainContext, facetSize, accuracy) {
|
6648 | var head = '';
|
6649 | var tail = '';
|
6650 | var first = true;
|
6651 | var exit = false;
|
6652 | var reverseTail = false;
|
6653 | var beginMap = {};
|
6654 | beginMap[MakerJs.pathType.Circle] = function (circle, link) {
|
6655 | var circleOptions = {
|
6656 | center: MakerJs.point.rounded(MakerJs.point.add(circle.origin, link.walkedPath.offset), accuracy),
|
6657 | radius: MakerJs.round(circle.radius, accuracy),
|
6658 | resolution: facetSizeToResolution(circle, facetSize)
|
6659 | };
|
6660 | head = wrap('CAG.circle', JSON.stringify(circleOptions), true);
|
6661 | exit = true;
|
6662 | };
|
6663 | beginMap[MakerJs.pathType.Line] = function (line, link) {
|
6664 | var points = link.endPoints.map(function (p) { return MakerJs.point.rounded(p, accuracy); });
|
6665 | if (link.reversed) {
|
6666 | points.reverse();
|
6667 | }
|
6668 | head = wrap('new CSG.Path2D', JSON.stringify(points), true);
|
6669 | };
|
6670 | beginMap[MakerJs.pathType.Arc] = function (arc, link) {
|
6671 | var endAngle = MakerJs.angle.ofArcEnd(arc);
|
6672 | if (link.reversed) {
|
6673 | reverseTail = true;
|
6674 | }
|
6675 | var arcOptions = {
|
6676 | center: MakerJs.point.rounded(MakerJs.point.add(arc.origin, link.walkedPath.offset), accuracy),
|
6677 | radius: MakerJs.round(arc.radius, accuracy),
|
6678 | startangle: MakerJs.round(arc.startAngle, accuracy),
|
6679 | endangle: MakerJs.round(endAngle, accuracy),
|
6680 | resolution: facetSizeToResolution(arc, facetSize)
|
6681 | };
|
6682 | head = wrap('new CSG.Path2D.arc', JSON.stringify(arcOptions), true);
|
6683 | };
|
6684 | var appendMap = {};
|
6685 | appendMap[MakerJs.pathType.Line] = function (line, link) {
|
6686 | var reverse = (reverseTail != link.reversed);
|
6687 | var endPoint = MakerJs.point.rounded(link.endPoints[reverse ? 0 : 1], accuracy);
|
6688 | append(wrap('.appendPoint', JSON.stringify(endPoint), true));
|
6689 | };
|
6690 | appendMap[MakerJs.pathType.Arc] = function (arc, link) {
|
6691 | var reverse = (reverseTail != link.reversed);
|
6692 | var endAngle = MakerJs.angle.ofArcEnd(arc);
|
6693 | var arcOptions = {
|
6694 | radius: MakerJs.round(arc.radius, accuracy),
|
6695 | clockwise: reverse,
|
6696 | large: Math.abs(endAngle - arc.startAngle) > 180,
|
6697 | resolution: facetSizeToResolution(arc, facetSize)
|
6698 | };
|
6699 | var endPoint = MakerJs.point.rounded(link.endPoints[reverse ? 0 : 1], accuracy);
|
6700 | append(wrap('.appendArc', JSON.stringify(endPoint) + ',' + JSON.stringify(arcOptions), true));
|
6701 | };
|
6702 | function append(s) {
|
6703 | if (reverseTail) {
|
6704 | tail = s + tail;
|
6705 | }
|
6706 | else {
|
6707 | tail += s;
|
6708 | }
|
6709 | }
|
6710 | for (var i = 0; i < chainContext.links.length; i++) {
|
6711 | var link = chainContext.links[i];
|
6712 | var pathContext = link.walkedPath.pathContext;
|
6713 | var fn = first ? beginMap[pathContext.type] : appendMap[pathContext.type];
|
6714 | if (fn) {
|
6715 | fn(pathContext, link);
|
6716 | }
|
6717 | if (exit) {
|
6718 | return head;
|
6719 | }
|
6720 | first = false;
|
6721 | }
|
6722 | return head + tail + '.close().innerToCAG()';
|
6723 | }
|
6724 | |
6725 |
|
6726 |
|
6727 | function makePhasedCallback(originalCb, phaseStart, phaseSpan) {
|
6728 | return function statusCallback(status) {
|
6729 | originalCb && originalCb({ progress: phaseStart + status.progress * phaseSpan / 100 });
|
6730 | };
|
6731 | }
|
6732 | |
6733 |
|
6734 |
|
6735 |
|
6736 |
|
6737 |
|
6738 |
|
6739 |
|
6740 |
|
6741 |
|
6742 |
|
6743 |
|
6744 |
|
6745 |
|
6746 |
|
6747 |
|
6748 |
|
6749 |
|
6750 |
|
6751 |
|
6752 |
|
6753 | function toJscadCAG(jscadCAG, modelToExport, jsCadCagOptions) {
|
6754 | function chainToJscadCag(c, maxArcFacet) {
|
6755 | var keyPoints = MakerJs.chain.toKeyPoints(c, maxArcFacet);
|
6756 | keyPoints.push(keyPoints[0]);
|
6757 | return jscadCAG.fromPoints(keyPoints);
|
6758 | }
|
6759 | function jscadCagUnion(augend, addend) {
|
6760 | return augend.union(addend);
|
6761 | }
|
6762 | function jscadCagSubtraction(minuend, subtrahend) {
|
6763 | return minuend.subtract(subtrahend);
|
6764 | }
|
6765 | return convertChainsTo2D(chainToJscadCag, jscadCagUnion, jscadCagSubtraction, modelToExport, jsCadCagOptions);
|
6766 | }
|
6767 | exporter.toJscadCAG = toJscadCAG;
|
6768 | |
6769 |
|
6770 |
|
6771 | function convertChainsTo2D(convertToT, union, subtraction, modelToExport, jsCadCagOptions) {
|
6772 | if (jsCadCagOptions === void 0) { jsCadCagOptions = {}; }
|
6773 | var adds = {};
|
6774 | var status = { total: 0, complete: 0 };
|
6775 | function unionize(phaseStart, phaseSpan, arr) {
|
6776 | var result = arr.shift();
|
6777 | arr.forEach(function (el) { return result = union(result, el); });
|
6778 | status.complete++;
|
6779 | jsCadCagOptions.statusCallback && jsCadCagOptions.statusCallback({ progress: phaseStart + phaseSpan * status.complete / status.total });
|
6780 | return result;
|
6781 | }
|
6782 | function subtractChains(layerId, cs) {
|
6783 | var subtracts = [];
|
6784 | cs.forEach(function (c) {
|
6785 | if (!c.endless)
|
6786 | return;
|
6787 | if (c.contains) {
|
6788 | addChains(layerId, c.contains);
|
6789 | }
|
6790 | status.total++;
|
6791 | subtracts.unshift(convertToT(c, jsCadCagOptions.maxArcFacet));
|
6792 | });
|
6793 | return subtracts;
|
6794 | }
|
6795 | function addChains(layerId, cs) {
|
6796 | cs.forEach(function (c) {
|
6797 | if (!c.endless)
|
6798 | return;
|
6799 | var add = { cag: convertToT(c, jsCadCagOptions.maxArcFacet), subtracts: [] };
|
6800 | if (c.contains) {
|
6801 | var subtracts = subtractChains(layerId, c.contains);
|
6802 | if (subtracts.length > 0) {
|
6803 | add.subtracts.push(subtracts);
|
6804 | }
|
6805 | }
|
6806 | status.total++;
|
6807 | if (!(layerId in adds)) {
|
6808 | adds[layerId] = [];
|
6809 | }
|
6810 | adds[layerId].unshift(add);
|
6811 | });
|
6812 | }
|
6813 | var options = {
|
6814 | pointMatchingDistance: jsCadCagOptions.pointMatchingDistance,
|
6815 | byLayers: jsCadCagOptions.byLayers,
|
6816 | contain: true
|
6817 | };
|
6818 | jsCadCagOptions.statusCallback && jsCadCagOptions.statusCallback({ progress: 25 });
|
6819 | var chainsResult = MakerJs.model.findChains(modelToExport, options);
|
6820 | if (Array.isArray(chainsResult)) {
|
6821 | addChains('', chainsResult);
|
6822 | }
|
6823 | else {
|
6824 | for (var layerId in chainsResult) {
|
6825 | addChains(layerId, chainsResult[layerId]);
|
6826 | }
|
6827 | }
|
6828 | jsCadCagOptions.statusCallback && jsCadCagOptions.statusCallback({ progress: 50 });
|
6829 | var closedCount = 0;
|
6830 | for (var layerId in adds) {
|
6831 | closedCount += adds[layerId].length;
|
6832 | }
|
6833 | if (closedCount === 0) {
|
6834 | jsCadCagOptions.statusCallback && jsCadCagOptions.statusCallback({ progress: 100 });
|
6835 | throw ('No closed geometries found.');
|
6836 | }
|
6837 | var resultMap = {};
|
6838 | for (var layerId in adds) {
|
6839 | var flatAdds = adds[layerId].map(function (add) {
|
6840 | var result = add.cag;
|
6841 | add.subtracts.forEach(function (subtract) {
|
6842 | var union = unionize(50, 50, subtract);
|
6843 | result = subtraction(result, union);
|
6844 | });
|
6845 | return result;
|
6846 | });
|
6847 | resultMap[layerId] = unionize(50, 50, flatAdds);
|
6848 | }
|
6849 | jsCadCagOptions.statusCallback && jsCadCagOptions.statusCallback({ progress: 100 });
|
6850 | return options.byLayers ? resultMap : resultMap[''];
|
6851 | }
|
6852 | |
6853 |
|
6854 |
|
6855 |
|
6856 |
|
6857 |
|
6858 |
|
6859 |
|
6860 |
|
6861 |
|
6862 |
|
6863 |
|
6864 |
|
6865 |
|
6866 |
|
6867 |
|
6868 |
|
6869 |
|
6870 |
|
6871 |
|
6872 |
|
6873 |
|
6874 |
|
6875 | function toJscadCSG(jscadCAG, modelToExport, options) {
|
6876 | function to2D(opts) {
|
6877 | return toJscadCAG(jscadCAG, modelToExport, opts);
|
6878 | }
|
6879 | function to3D(cag, extrude, z) {
|
6880 | var csg = cag.extrude({ offset: [0, 0, extrude] });
|
6881 | if (z) {
|
6882 | csg = csg.translate([0, 0, z]);
|
6883 | }
|
6884 | return csg;
|
6885 | }
|
6886 | function union3D(augend, addend) {
|
6887 | return augend.union(addend);
|
6888 | }
|
6889 | return convert2Dto3D(to2D, to3D, union3D, modelToExport, options);
|
6890 | }
|
6891 | exporter.toJscadCSG = toJscadCSG;
|
6892 | |
6893 |
|
6894 |
|
6895 | function convert2Dto3D(to2D, to3D, union3D, modelToExport, options) {
|
6896 | if (options === void 0) { options = {}; }
|
6897 | var originalCb = options.statusCallback;
|
6898 | function getDefinedNumber(a, b) {
|
6899 | if (MakerJs.isNumber(a))
|
6900 | return a;
|
6901 | return b;
|
6902 | }
|
6903 | if (modelToExport.exporterOptions) {
|
6904 | MakerJs.extendObject(options, modelToExport.exporterOptions['toJscadCSG']);
|
6905 | }
|
6906 | options.byLayers = options.byLayers || (options.layerOptions && true);
|
6907 | options.statusCallback = makePhasedCallback(originalCb, 0, 50);
|
6908 | var result2D = to2D(options);
|
6909 | var csgs = [];
|
6910 | if (options.byLayers) {
|
6911 | for (var layerId in result2D) {
|
6912 | var layerOptions = options.layerOptions[layerId];
|
6913 | var csg = to3D(result2D[layerId], layerOptions.extrude || options.extrude, getDefinedNumber(layerOptions.z, options.z));
|
6914 | csgs.push(csg);
|
6915 | }
|
6916 | }
|
6917 | else {
|
6918 | var csg = to3D(result2D, options.extrude, options.z);
|
6919 | csgs.push(csg);
|
6920 | }
|
6921 | options.statusCallback = makePhasedCallback(originalCb, 50, 100);
|
6922 | var status = { total: csgs.length - 1, complete: 0 };
|
6923 | var result = csgs.shift();
|
6924 | csgs.forEach(function (el, i) {
|
6925 | result = union3D(result, el);
|
6926 | status.complete++;
|
6927 | options.statusCallback({ progress: status.complete / status.total });
|
6928 | });
|
6929 | return result;
|
6930 | }
|
6931 | |
6932 |
|
6933 |
|
6934 |
|
6935 |
|
6936 |
|
6937 |
|
6938 |
|
6939 |
|
6940 |
|
6941 |
|
6942 |
|
6943 |
|
6944 | function toJscadScript(modelToExport, options) {
|
6945 | if (options === void 0) { options = {}; }
|
6946 | function _chainToJscadScript(c, maxArcFacet) {
|
6947 | return wrap(chainToJscadScript(c, maxArcFacet, options.accuracy));
|
6948 | }
|
6949 | function scriptUnion(augend, addend) {
|
6950 | return augend + (".union(" + addend + ")");
|
6951 | }
|
6952 | function scriptSubtraction(minuend, subtrahend) {
|
6953 | return minuend + (".subtract(" + subtrahend + ")");
|
6954 | }
|
6955 | function to2D(opts) {
|
6956 | return convertChainsTo2D(_chainToJscadScript, scriptUnion, scriptSubtraction, modelToExport, options);
|
6957 | }
|
6958 | function to3D(cag, extrude, z) {
|
6959 | var csg = cag + (".extrude({ offset: [0, 0, " + extrude + "] })");
|
6960 | if (z) {
|
6961 | csg = csg + (".translate([0, 0, " + z + "])");
|
6962 | }
|
6963 | return csg;
|
6964 | }
|
6965 | function wrap(s) {
|
6966 | return "" + nl + indent + s + nl;
|
6967 | }
|
6968 | var indent = new Array((options.indent || 0) + 1).join(' ');
|
6969 | var nl = options.indent ? '\n' : '';
|
6970 | var result = convert2Dto3D(to2D, to3D, scriptUnion, modelToExport, options).trim();
|
6971 | return "function " + (options.functionName || 'main') + "(){" + wrap("return " + result + ";") + "}" + nl;
|
6972 | }
|
6973 | exporter.toJscadScript = toJscadScript;
|
6974 | |
6975 |
|
6976 |
|
6977 |
|
6978 |
|
6979 |
|
6980 |
|
6981 |
|
6982 |
|
6983 |
|
6984 |
|
6985 |
|
6986 |
|
6987 |
|
6988 |
|
6989 | function toJscadSTL(CAG, stlSerializer, modelToExport, options) {
|
6990 | var originalCb = options.statusCallback;
|
6991 | options.statusCallback = makePhasedCallback(originalCb, 0, 50);
|
6992 | var csg = toJscadCSG(CAG, modelToExport, options);
|
6993 | return stlSerializer.serialize(csg, { binary: false, statusCallback: makePhasedCallback(originalCb, 50, 50) });
|
6994 | }
|
6995 | exporter.toJscadSTL = toJscadSTL;
|
6996 | })(exporter = MakerJs.exporter || (MakerJs.exporter = {}));
|
6997 | })(MakerJs || (MakerJs = {}));
|
6998 | var MakerJs;
|
6999 | (function (MakerJs) {
|
7000 | var exporter;
|
7001 | (function (exporter) {
|
7002 | |
7003 |
|
7004 |
|
7005 |
|
7006 |
|
7007 |
|
7008 |
|
7009 |
|
7010 | function toPDF(doc, modelToExport, options) {
|
7011 | if (!modelToExport)
|
7012 | return;
|
7013 |
|
7014 | var opts = {
|
7015 | fontName: 'Courier',
|
7016 | fontSize: 9,
|
7017 | origin: [0, 0],
|
7018 | stroke: "#000"
|
7019 | };
|
7020 | MakerJs.extendObject(opts, options);
|
7021 |
|
7022 | var scale = 1;
|
7023 | var exportUnits = opts.units || modelToExport.units;
|
7024 | if (exportUnits) {
|
7025 |
|
7026 | scale = MakerJs.units.conversionScale(exportUnits, MakerJs.unitType.Inch);
|
7027 | }
|
7028 | else {
|
7029 |
|
7030 | scale = 1 / 100;
|
7031 | }
|
7032 |
|
7033 | scale *= 72;
|
7034 |
|
7035 | var scaledModel = MakerJs.model.scale(MakerJs.cloneObject(modelToExport), scale);
|
7036 | var size = MakerJs.measure.modelExtents(scaledModel);
|
7037 | var left = -size.low[0];
|
7038 | var offset = [left, size.high[1]];
|
7039 | offset = MakerJs.point.add(offset, options.origin);
|
7040 | MakerJs.model.findChains(scaledModel, function (chains, loose, layer) {
|
7041 | function single(walkedPath) {
|
7042 | var pathData = exporter.pathToSVGPathData(walkedPath.pathContext, walkedPath.offset, offset);
|
7043 | doc.path(pathData).stroke(opts.stroke);
|
7044 | }
|
7045 | chains.map(function (chain) {
|
7046 | if (chain.links.length > 1) {
|
7047 | var pathData = exporter.chainToSVGPathData(chain, offset);
|
7048 | doc.path(pathData).stroke(opts.stroke);
|
7049 | }
|
7050 | else {
|
7051 | var walkedPath = chain.links[0].walkedPath;
|
7052 | if (walkedPath.pathContext.type === MakerJs.pathType.Circle) {
|
7053 | var fixedPath;
|
7054 | MakerJs.path.moveTemporary([walkedPath.pathContext], [walkedPath.offset], function () {
|
7055 | fixedPath = MakerJs.path.mirror(walkedPath.pathContext, false, true);
|
7056 | });
|
7057 | MakerJs.path.moveRelative(fixedPath, offset);
|
7058 |
|
7059 | doc.circle(fixedPath.origin[0], fixedPath.origin[1], walkedPath.pathContext.radius).stroke(opts.stroke);
|
7060 | }
|
7061 | else {
|
7062 | single(walkedPath);
|
7063 | }
|
7064 | }
|
7065 | });
|
7066 | loose.map(single);
|
7067 | }, { byLayers: false });
|
7068 | doc.font(opts.fontName).fontSize(opts.fontSize);
|
7069 | MakerJs.model.getAllCaptionsOffset(scaledModel).forEach(function (caption) {
|
7070 |
|
7071 | var a = MakerJs.angle.ofLineInDegrees(caption.anchor);
|
7072 |
|
7073 | var anchor = MakerJs.path.mirror(caption.anchor, false, true);
|
7074 |
|
7075 | MakerJs.path.moveRelative(anchor, offset);
|
7076 |
|
7077 | var text = caption.text;
|
7078 | var textCenter = [doc.widthOfString(text) / 2, doc.heightOfString(text) / 2];
|
7079 |
|
7080 | var center = MakerJs.point.middle(anchor);
|
7081 | var textOffset = MakerJs.point.subtract(center, textCenter);
|
7082 | doc.rotate(-a, { origin: center });
|
7083 | doc.text(text, textOffset[0], textOffset[1]);
|
7084 | doc.rotate(a, { origin: center });
|
7085 | });
|
7086 | }
|
7087 | exporter.toPDF = toPDF;
|
7088 | })(exporter = MakerJs.exporter || (MakerJs.exporter = {}));
|
7089 | })(MakerJs || (MakerJs = {}));
|
7090 | var MakerJs;
|
7091 | (function (MakerJs) {
|
7092 | var exporter;
|
7093 | (function (exporter) {
|
7094 | |
7095 |
|
7096 |
|
7097 | var chainLinkToPathDataMap = {};
|
7098 | chainLinkToPathDataMap[MakerJs.pathType.Arc] = function (arc, endPoint, reversed, d, accuracy) {
|
7099 | d.push('A');
|
7100 | svgArcData(d, arc.radius, endPoint, accuracy, MakerJs.angle.ofArcSpan(arc) > 180, reversed ? (arc.startAngle > arc.endAngle) : (arc.startAngle < arc.endAngle));
|
7101 | };
|
7102 | chainLinkToPathDataMap[MakerJs.pathType.Line] = function (line, endPoint, reversed, d, accuracy) {
|
7103 | d.push('L', MakerJs.round(endPoint[0], accuracy), MakerJs.round(endPoint[1], accuracy));
|
7104 | };
|
7105 | chainLinkToPathDataMap[MakerJs.pathType.BezierSeed] = function (seed, endPoint, reversed, d, accuracy) {
|
7106 | svgBezierData(d, seed, accuracy, reversed);
|
7107 | };
|
7108 | |
7109 |
|
7110 |
|
7111 | function svgCoords(p) {
|
7112 | return MakerJs.point.mirror(p, false, true);
|
7113 | }
|
7114 | |
7115 |
|
7116 |
|
7117 | function correctArc(arc) {
|
7118 | var arcSpan = MakerJs.angle.ofArcSpan(arc);
|
7119 | arc.startAngle = MakerJs.angle.noRevolutions(arc.startAngle);
|
7120 | arc.endAngle = arc.startAngle + arcSpan;
|
7121 | }
|
7122 | |
7123 |
|
7124 |
|
7125 |
|
7126 |
|
7127 |
|
7128 |
|
7129 |
|
7130 | function chainToSVGPathData(chain, offset, accuracy) {
|
7131 | function offsetPoint(p) {
|
7132 | return MakerJs.point.add(p, offset);
|
7133 | }
|
7134 | var first = chain.links[0];
|
7135 | var firstPoint = offsetPoint(svgCoords(first.endPoints[first.reversed ? 1 : 0]));
|
7136 | var d = ['M', MakerJs.round(firstPoint[0], accuracy), MakerJs.round(firstPoint[1], accuracy)];
|
7137 | for (var i = 0; i < chain.links.length; i++) {
|
7138 | var link = chain.links[i];
|
7139 | var pathContext = link.walkedPath.pathContext;
|
7140 | var fn = chainLinkToPathDataMap[pathContext.type];
|
7141 | if (fn) {
|
7142 | var fixedPath;
|
7143 | MakerJs.path.moveTemporary([pathContext], [link.walkedPath.offset], function () {
|
7144 | fixedPath = MakerJs.path.mirror(pathContext, false, true);
|
7145 | });
|
7146 | MakerJs.path.moveRelative(fixedPath, offset);
|
7147 | fn(fixedPath, offsetPoint(svgCoords(link.endPoints[link.reversed ? 0 : 1])), link.reversed, d, accuracy);
|
7148 | }
|
7149 | }
|
7150 | if (chain.endless) {
|
7151 | d.push('Z');
|
7152 | }
|
7153 | return d.join(' ');
|
7154 | }
|
7155 | exporter.chainToSVGPathData = chainToSVGPathData;
|
7156 | |
7157 |
|
7158 |
|
7159 | function startSvgPathData(start, d, accuracy) {
|
7160 | return ["M", MakerJs.round(start[0], accuracy), MakerJs.round(start[1], accuracy)].concat(d);
|
7161 | }
|
7162 | |
7163 |
|
7164 |
|
7165 | var svgPathDataMap = {};
|
7166 | svgPathDataMap[MakerJs.pathType.Line] = function (line, accuracy) {
|
7167 | return startSvgPathData(line.origin, MakerJs.point.rounded(line.end, accuracy), accuracy);
|
7168 | };
|
7169 | svgPathDataMap[MakerJs.pathType.Circle] = function (circle, accuracy, clockwiseCircle) {
|
7170 | return startSvgPathData(circle.origin, svgCircleData(circle.radius, accuracy, clockwiseCircle), accuracy);
|
7171 | };
|
7172 | svgPathDataMap[MakerJs.pathType.Arc] = function (arc, accuracy) {
|
7173 | correctArc(arc);
|
7174 | var arcPoints = MakerJs.point.fromArc(arc);
|
7175 | if (MakerJs.measure.isPointEqual(arcPoints[0], arcPoints[1])) {
|
7176 | return svgPathDataMap[MakerJs.pathType.Circle](arc, accuracy);
|
7177 | }
|
7178 | else {
|
7179 | var d = ['A'];
|
7180 | svgArcData(d, arc.radius, arcPoints[1], accuracy, MakerJs.angle.ofArcSpan(arc) > 180, arc.startAngle > arc.endAngle);
|
7181 | return startSvgPathData(arcPoints[0], d, accuracy);
|
7182 | }
|
7183 | };
|
7184 | svgPathDataMap[MakerJs.pathType.BezierSeed] = function (seed, accuracy) {
|
7185 | var d = [];
|
7186 | svgBezierData(d, seed, accuracy);
|
7187 | return startSvgPathData(seed.origin, d, accuracy);
|
7188 | };
|
7189 | |
7190 |
|
7191 |
|
7192 |
|
7193 |
|
7194 |
|
7195 |
|
7196 |
|
7197 |
|
7198 |
|
7199 | function pathToSVGPathData(pathToExport, pathOffset, exportOffset, accuracy, clockwiseCircle) {
|
7200 | var fn = svgPathDataMap[pathToExport.type];
|
7201 | if (fn) {
|
7202 | var fixedPath;
|
7203 | MakerJs.path.moveTemporary([pathToExport], [pathOffset], function () {
|
7204 | fixedPath = MakerJs.path.mirror(pathToExport, false, true);
|
7205 | });
|
7206 | MakerJs.path.moveRelative(fixedPath, exportOffset);
|
7207 | var d = fn(fixedPath, accuracy, clockwiseCircle);
|
7208 | return d.join(' ');
|
7209 | }
|
7210 | return '';
|
7211 | }
|
7212 | exporter.pathToSVGPathData = pathToSVGPathData;
|
7213 | |
7214 |
|
7215 |
|
7216 | function getPathDataByLayer(modelToExport, offset, options, accuracy) {
|
7217 | var pathDataByLayer = {};
|
7218 | options.unifyBeziers = true;
|
7219 | MakerJs.model.findChains(modelToExport, function (chains, loose, layer) {
|
7220 | function single(walkedPath, clockwise) {
|
7221 | var pathData = pathToSVGPathData(walkedPath.pathContext, walkedPath.offset, offset, accuracy, clockwise);
|
7222 | pathDataByLayer[layer].push(pathData);
|
7223 | }
|
7224 | pathDataByLayer[layer] = [];
|
7225 | function doChains(cs, clockwise) {
|
7226 | cs.forEach(function (chain) {
|
7227 | if (chain.links.length > 1) {
|
7228 | var pathData = chainToSVGPathData(chain, offset, accuracy);
|
7229 | pathDataByLayer[layer].push(pathData);
|
7230 | }
|
7231 | else {
|
7232 | single(chain.links[0].walkedPath, clockwise);
|
7233 | }
|
7234 | if (chain.contains) {
|
7235 | doChains(chain.contains, !clockwise);
|
7236 | }
|
7237 | });
|
7238 | }
|
7239 | doChains(chains, true);
|
7240 | loose.forEach(function (wp) { return single(wp); });
|
7241 | }, options);
|
7242 | return pathDataByLayer;
|
7243 | }
|
7244 | function toSVGPathData(modelToExport) {
|
7245 | var args = [];
|
7246 | for (var _i = 1; _i < arguments.length; _i++) {
|
7247 | args[_i - 1] = arguments[_i];
|
7248 | }
|
7249 | var options = {
|
7250 | fillRule: 'evenodd'
|
7251 | };
|
7252 | if (typeof args[0] === 'boolean') {
|
7253 | options.byLayers = args[0];
|
7254 | options.origin = args[1];
|
7255 | options.accuracy = args[2];
|
7256 | }
|
7257 | else if (MakerJs.isObject(args[0])) {
|
7258 | MakerJs.extendObject(options, args[0]);
|
7259 | }
|
7260 | var findChainsOptions = {
|
7261 | byLayers: options.byLayers,
|
7262 | contain: false
|
7263 | };
|
7264 | if (options.fillRule === 'nonzero') {
|
7265 | findChainsOptions.contain = {
|
7266 | alternateDirection: true
|
7267 | };
|
7268 | }
|
7269 | var size = MakerJs.measure.modelExtents(modelToExport);
|
7270 | if (!options.origin) {
|
7271 | options.origin = [-size.low[0], size.high[1]];
|
7272 | }
|
7273 | var pathDataArrayByLayer = getPathDataByLayer(modelToExport, options.origin, findChainsOptions, options.accuracy);
|
7274 | var pathDataStringByLayer = {};
|
7275 | for (var layer in pathDataArrayByLayer) {
|
7276 | pathDataStringByLayer[layer] = pathDataArrayByLayer[layer].join(' ');
|
7277 | }
|
7278 | return findChainsOptions.byLayers ? pathDataStringByLayer : pathDataStringByLayer[''];
|
7279 | }
|
7280 | exporter.toSVGPathData = toSVGPathData;
|
7281 | |
7282 |
|
7283 |
|
7284 |
|
7285 |
|
7286 |
|
7287 |
|
7288 |
|
7289 |
|
7290 |
|
7291 |
|
7292 |
|
7293 |
|
7294 |
|
7295 | function toSVG(itemToExport, options) {
|
7296 | function append(value, layer, forcePush) {
|
7297 | if (forcePush === void 0) { forcePush = false; }
|
7298 | if (!forcePush && typeof layer == "string" && layer.length > 0) {
|
7299 | if (!(layer in layers)) {
|
7300 | layers[layer] = [];
|
7301 | }
|
7302 | layers[layer].push(value);
|
7303 | }
|
7304 | else {
|
7305 | elements.push(value);
|
7306 | }
|
7307 | }
|
7308 | function cssStyle(elOpts) {
|
7309 | var a = [];
|
7310 | function push(name, val) {
|
7311 | if (val === undefined)
|
7312 | return;
|
7313 | a.push(name + ':' + val);
|
7314 | }
|
7315 | push('stroke', elOpts.stroke);
|
7316 | push('stroke-width', elOpts.strokeWidth);
|
7317 | push('fill', elOpts.fill);
|
7318 | return a.join(';');
|
7319 | }
|
7320 | function addSvgAttrs(attrs, elOpts) {
|
7321 | if (!elOpts)
|
7322 | return;
|
7323 | MakerJs.extendObject(attrs, {
|
7324 | "stroke": elOpts.stroke,
|
7325 | "stroke-width": elOpts.strokeWidth,
|
7326 | "fill": elOpts.fill,
|
7327 | "style": elOpts.cssStyle || cssStyle(elOpts)
|
7328 | });
|
7329 | }
|
7330 | function colorLayerOptions(layer) {
|
7331 | if (opts.layerOptions && opts.layerOptions[layer])
|
7332 | return opts.layerOptions[layer];
|
7333 | if (layer in exporter.colors) {
|
7334 | return {
|
7335 | stroke: layer
|
7336 | };
|
7337 | }
|
7338 | }
|
7339 | function createElement(tagname, attrs, layer, innerText, forcePush) {
|
7340 | if (innerText === void 0) { innerText = null; }
|
7341 | if (forcePush === void 0) { forcePush = false; }
|
7342 | if (tagname !== 'text') {
|
7343 | addSvgAttrs(attrs, colorLayerOptions(layer));
|
7344 | }
|
7345 | if (!opts.scalingStroke) {
|
7346 | attrs['vector-effect'] = 'non-scaling-stroke';
|
7347 | }
|
7348 | var tag = new exporter.XmlTag(tagname, attrs);
|
7349 | tag.closingTags = opts.closingTags;
|
7350 | if (innerText) {
|
7351 | tag.innerText = innerText;
|
7352 | }
|
7353 | append(tag.toString(), layer, forcePush);
|
7354 | }
|
7355 | function fixPoint(pointToFix) {
|
7356 |
|
7357 | var pointMirroredY = svgCoords(pointToFix);
|
7358 | return MakerJs.point.scale(pointMirroredY, opts.scale);
|
7359 | }
|
7360 | function fixPath(pathToFix, origin) {
|
7361 |
|
7362 | var mirrorY = MakerJs.path.mirror(pathToFix, false, true);
|
7363 | return MakerJs.path.moveRelative(MakerJs.path.scale(mirrorY, opts.scale), origin);
|
7364 | }
|
7365 |
|
7366 | var opts = {
|
7367 | accuracy: .001,
|
7368 | annotate: false,
|
7369 | origin: null,
|
7370 | scale: 1,
|
7371 | stroke: "#000",
|
7372 | strokeLineCap: "round",
|
7373 | strokeWidth: '0.25mm',
|
7374 | fill: "none",
|
7375 | fillRule: "evenodd",
|
7376 | fontSize: '9pt',
|
7377 | useSvgPathOnly: true,
|
7378 | viewBox: true
|
7379 | };
|
7380 | MakerJs.extendObject(opts, options);
|
7381 | var modelToExport;
|
7382 | var itemToExportIsModel = MakerJs.isModel(itemToExport);
|
7383 | if (itemToExportIsModel) {
|
7384 | modelToExport = itemToExport;
|
7385 | if (modelToExport.exporterOptions) {
|
7386 | MakerJs.extendObject(opts, modelToExport.exporterOptions['toSVG']);
|
7387 | }
|
7388 | }
|
7389 | var elements = [];
|
7390 | var layers = {};
|
7391 |
|
7392 | if (itemToExportIsModel) {
|
7393 | modelToExport = itemToExport;
|
7394 | }
|
7395 | else if (Array.isArray(itemToExport)) {
|
7396 |
|
7397 | var pathMap = {};
|
7398 | itemToExport.forEach(function (p, i) { pathMap[i] = p; });
|
7399 | modelToExport = { paths: pathMap };
|
7400 | }
|
7401 | else if (MakerJs.isPath(itemToExport)) {
|
7402 | modelToExport = { paths: { modelToMeasure: itemToExport } };
|
7403 | }
|
7404 | var size = MakerJs.measure.modelExtents(modelToExport);
|
7405 |
|
7406 | var captions = MakerJs.model.getAllCaptionsOffset(modelToExport);
|
7407 | captions.forEach(function (caption) {
|
7408 | MakerJs.measure.increase(size, MakerJs.measure.pathExtents(caption.anchor), true);
|
7409 | });
|
7410 |
|
7411 | if (!opts.units) {
|
7412 | var unitSystem = exporter.tryGetModelUnits(itemToExport);
|
7413 | if (unitSystem) {
|
7414 | opts.units = unitSystem;
|
7415 | }
|
7416 | }
|
7417 |
|
7418 | var useSvgUnit = exporter.svgUnit[opts.units];
|
7419 | if (useSvgUnit && opts.viewBox) {
|
7420 | opts.scale *= useSvgUnit.scaleConversion;
|
7421 | }
|
7422 | if (size && !opts.origin) {
|
7423 | var left = -size.low[0] * opts.scale;
|
7424 | opts.origin = [left, size.high[1] * opts.scale];
|
7425 | }
|
7426 |
|
7427 | MakerJs.extendObject(options, opts);
|
7428 |
|
7429 | var svgAttrs;
|
7430 | if (size && opts.viewBox) {
|
7431 | var width = MakerJs.round(size.width * opts.scale, opts.accuracy);
|
7432 | var height = MakerJs.round(size.height * opts.scale, opts.accuracy);
|
7433 | var viewBox = [0, 0, width, height];
|
7434 | var unit = useSvgUnit ? useSvgUnit.svgUnitType : '';
|
7435 | svgAttrs = {
|
7436 | width: width + unit,
|
7437 | height: height + unit,
|
7438 | viewBox: viewBox.join(' ')
|
7439 | };
|
7440 | }
|
7441 | var svgTag = new exporter.XmlTag('svg', MakerJs.extendObject(svgAttrs || {}, opts.svgAttrs));
|
7442 | append(svgTag.getOpeningTag(false));
|
7443 | var groupAttrs = {
|
7444 | id: 'svgGroup',
|
7445 | "stroke-linecap": opts.strokeLineCap,
|
7446 | "fill-rule": opts.fillRule,
|
7447 | "font-size": opts.fontSize
|
7448 | };
|
7449 | addSvgAttrs(groupAttrs, opts);
|
7450 | var svgGroup = new exporter.XmlTag('g', groupAttrs);
|
7451 | append(svgGroup.getOpeningTag(false));
|
7452 | if (opts.useSvgPathOnly) {
|
7453 | var findChainsOptions = {
|
7454 | byLayers: true
|
7455 | };
|
7456 | if (opts.fillRule === 'nonzero') {
|
7457 | findChainsOptions.contain = {
|
7458 | alternateDirection: true
|
7459 | };
|
7460 | }
|
7461 | var pathDataByLayer = getPathDataByLayer(modelToExport, opts.origin, findChainsOptions, opts.accuracy);
|
7462 | for (var layerId1 in pathDataByLayer) {
|
7463 | var pathData = pathDataByLayer[layerId1].join(' ');
|
7464 | var attrs = { "d": pathData };
|
7465 | if (layerId1.length > 0) {
|
7466 | attrs["id"] = layerId1;
|
7467 | }
|
7468 | createElement("path", attrs, layerId1, null, true);
|
7469 | }
|
7470 | }
|
7471 | else {
|
7472 | function drawText(id, textPoint, layer) {
|
7473 | createElement("text", {
|
7474 | "id": id + "_text",
|
7475 | "x": MakerJs.round(textPoint[0], opts.accuracy),
|
7476 | "y": MakerJs.round(textPoint[1], opts.accuracy)
|
7477 | }, layer, id);
|
7478 | }
|
7479 | function drawPath(id, x, y, d, layer, route, textPoint, annotate, flow) {
|
7480 | createElement("path", {
|
7481 | "id": id,
|
7482 | "data-route": route,
|
7483 | "d": ["M", MakerJs.round(x, opts.accuracy), MakerJs.round(y, opts.accuracy)].concat(d).join(" ")
|
7484 | }, layer);
|
7485 | if (annotate) {
|
7486 | drawText(id, textPoint, layer);
|
7487 | }
|
7488 | }
|
7489 | function circleInPaths(id, center, radius, layer, route, annotate, flow) {
|
7490 | var d = svgCircleData(radius, opts.accuracy);
|
7491 | drawPath(id, center[0], center[1], d, layer, route, center, annotate, flow);
|
7492 | }
|
7493 | var map = {};
|
7494 | map[MakerJs.pathType.Line] = function (id, line, layer, className, route, annotate, flow) {
|
7495 | var start = line.origin;
|
7496 | var end = line.end;
|
7497 | createElement("line", {
|
7498 | "id": id,
|
7499 | "class": className,
|
7500 | "data-route": route,
|
7501 | "x1": MakerJs.round(start[0], opts.accuracy),
|
7502 | "y1": MakerJs.round(start[1], opts.accuracy),
|
7503 | "x2": MakerJs.round(end[0], opts.accuracy),
|
7504 | "y2": MakerJs.round(end[1], opts.accuracy)
|
7505 | }, layer);
|
7506 | if (annotate) {
|
7507 | drawText(id, MakerJs.point.middle(line), layer);
|
7508 | }
|
7509 | if (flow) {
|
7510 | addFlowMarks(flow, layer, line.origin, line.end, MakerJs.angle.ofLineInDegrees(line));
|
7511 | }
|
7512 | };
|
7513 | map[MakerJs.pathType.Circle] = function (id, circle, layer, className, route, annotate, flow) {
|
7514 | var center = circle.origin;
|
7515 | createElement("circle", {
|
7516 | "id": id,
|
7517 | "class": className,
|
7518 | "data-route": route,
|
7519 | "r": circle.radius,
|
7520 | "cx": MakerJs.round(center[0], opts.accuracy),
|
7521 | "cy": MakerJs.round(center[1], opts.accuracy)
|
7522 | }, layer);
|
7523 | if (annotate) {
|
7524 | drawText(id, center, layer);
|
7525 | }
|
7526 | };
|
7527 | map[MakerJs.pathType.Arc] = function (id, arc, layer, className, route, annotate, flow) {
|
7528 | correctArc(arc);
|
7529 | var arcPoints = MakerJs.point.fromArc(arc);
|
7530 | if (MakerJs.measure.isPointEqual(arcPoints[0], arcPoints[1])) {
|
7531 | circleInPaths(id, arc.origin, arc.radius, layer, route, annotate, flow);
|
7532 | }
|
7533 | else {
|
7534 | var d = ['A'];
|
7535 | svgArcData(d, arc.radius, arcPoints[1], opts.accuracy, MakerJs.angle.ofArcSpan(arc) > 180, arc.startAngle > arc.endAngle);
|
7536 | drawPath(id, arcPoints[0][0], arcPoints[0][1], d, layer, route, MakerJs.point.middle(arc), annotate, flow);
|
7537 | if (flow) {
|
7538 | addFlowMarks(flow, layer, arcPoints[1], arcPoints[0], MakerJs.angle.noRevolutions(arc.startAngle - 90));
|
7539 | }
|
7540 | }
|
7541 | };
|
7542 | map[MakerJs.pathType.BezierSeed] = function (id, seed, layer, className, route, annotate, flow) {
|
7543 | var d = [];
|
7544 | svgBezierData(d, seed, opts.accuracy);
|
7545 | drawPath(id, seed.origin[0], seed.origin[1], d, layer, route, MakerJs.point.middle(seed), annotate, flow);
|
7546 | };
|
7547 | function addFlowMarks(flow, layer, origin, end, endAngle) {
|
7548 | var className = 'flow';
|
7549 |
|
7550 | map[MakerJs.pathType.Circle]('', new MakerJs.paths.Circle(origin, flow.size / 2), layer, className, null, false, null);
|
7551 |
|
7552 | var arrowEnd = [-1 * flow.size, flow.size / 2];
|
7553 | var arrowLines = [arrowEnd, MakerJs.point.mirror(arrowEnd, false, true)].map(function (p) { return new MakerJs.paths.Line(MakerJs.point.add(MakerJs.point.rotate(p, endAngle), end), end); });
|
7554 | arrowLines.forEach(function (a) { return map[MakerJs.pathType.Line]('', a, layer, className, null, false, null); });
|
7555 | }
|
7556 | function beginModel(id, modelContext) {
|
7557 | modelGroup.attrs = { id: id };
|
7558 | append(modelGroup.getOpeningTag(false), modelContext.layer);
|
7559 | }
|
7560 | function endModel(modelContext) {
|
7561 | append(modelGroup.getClosingTag(), modelContext.layer);
|
7562 | }
|
7563 | var modelGroup = new exporter.XmlTag('g');
|
7564 | var walkOptions = {
|
7565 | beforeChildWalk: function (walkedModel) {
|
7566 | beginModel(walkedModel.childId, walkedModel.childModel);
|
7567 | return true;
|
7568 | },
|
7569 | onPath: function (walkedPath) {
|
7570 | var fn = map[walkedPath.pathContext.type];
|
7571 | if (fn) {
|
7572 | var offset = MakerJs.point.add(fixPoint(walkedPath.offset), opts.origin);
|
7573 | fn(walkedPath.pathId, fixPath(walkedPath.pathContext, offset), walkedPath.layer, null, walkedPath.route, opts.annotate, opts.flow);
|
7574 | }
|
7575 | },
|
7576 | afterChildWalk: function (walkedModel) {
|
7577 | endModel(walkedModel.childModel);
|
7578 | }
|
7579 | };
|
7580 | beginModel('0', modelToExport);
|
7581 | MakerJs.model.walk(modelToExport, walkOptions);
|
7582 |
|
7583 | for (var layerId2 in layers) {
|
7584 | var layerGroup = new exporter.XmlTag('g', { id: layerId2 });
|
7585 | addSvgAttrs(layerGroup.attrs, colorLayerOptions(layerId2));
|
7586 | for (var i = 0; i < layers[layerId2].length; i++) {
|
7587 | layerGroup.innerText += layers[layerId2][i];
|
7588 | }
|
7589 | layerGroup.innerTextEscaped = true;
|
7590 | append(layerGroup.toString());
|
7591 | }
|
7592 | }
|
7593 | var captionTags = captions.map(function (caption) {
|
7594 | var anchor = fixPath(caption.anchor, opts.origin);
|
7595 | var center = MakerJs.point.rounded(MakerJs.point.middle(anchor), opts.accuracy);
|
7596 | var tag = new exporter.XmlTag('text', {
|
7597 | "alignment-baseline": "middle",
|
7598 | "text-anchor": "middle",
|
7599 | "transform": "rotate(" + MakerJs.angle.ofLineInDegrees(anchor) + "," + center[0] + "," + center[1] + ")",
|
7600 | "x": center[0],
|
7601 | "y": center[1]
|
7602 | });
|
7603 | tag.innerText = caption.text;
|
7604 | return tag.toString();
|
7605 | });
|
7606 | if (captionTags.length) {
|
7607 | var captionGroup = new exporter.XmlTag('g', { "id": "captions" });
|
7608 | captionGroup.innerText = captionTags.join('');
|
7609 | captionGroup.innerTextEscaped = true;
|
7610 | append(captionGroup.toString());
|
7611 | }
|
7612 | append(svgGroup.getClosingTag());
|
7613 | append(svgTag.getClosingTag());
|
7614 | return elements.join('');
|
7615 | }
|
7616 | exporter.toSVG = toSVG;
|
7617 | |
7618 |
|
7619 |
|
7620 | function svgCircleData(radius, accuracy, clockwiseCircle) {
|
7621 | var r = MakerJs.round(radius, accuracy);
|
7622 | var d = ['m', -r, 0];
|
7623 | function halfCircle(sign) {
|
7624 | d.push('a');
|
7625 | svgArcData(d, r, [2 * r * sign, 0], accuracy, false, !clockwiseCircle);
|
7626 | }
|
7627 | halfCircle(1);
|
7628 | halfCircle(-1);
|
7629 | d.push('z');
|
7630 | return d;
|
7631 | }
|
7632 | |
7633 |
|
7634 |
|
7635 | function svgBezierData(d, seed, accuracy, reversed) {
|
7636 | if (seed.controls.length === 1) {
|
7637 | d.push('Q', MakerJs.round(seed.controls[0][0], accuracy), MakerJs.round(seed.controls[0][1], accuracy));
|
7638 | }
|
7639 | else {
|
7640 | var controls = reversed ? [seed.controls[1], seed.controls[0]] : seed.controls;
|
7641 | d.push('C', MakerJs.round(controls[0][0], accuracy), MakerJs.round(controls[0][1], accuracy), MakerJs.round(controls[1][0], accuracy), MakerJs.round(controls[1][1], accuracy));
|
7642 | }
|
7643 | var final = reversed ? seed.origin : seed.end;
|
7644 | d.push(MakerJs.round(final[0], accuracy), MakerJs.round(final[1], accuracy));
|
7645 | }
|
7646 | |
7647 |
|
7648 |
|
7649 | function svgArcData(d, radius, endPoint, accuracy, largeArc, increasing) {
|
7650 | var r = MakerJs.round(radius, accuracy);
|
7651 | var end = endPoint;
|
7652 | d.push(r, r);
|
7653 | d.push(0);
|
7654 | d.push(largeArc ? 1 : 0);
|
7655 | d.push(increasing ? 0 : 1);
|
7656 | d.push(MakerJs.round(end[0], accuracy), MakerJs.round(end[1], accuracy));
|
7657 | }
|
7658 | |
7659 |
|
7660 |
|
7661 | exporter.svgUnit = {};
|
7662 |
|
7663 |
|
7664 |
|
7665 | exporter.svgUnit[MakerJs.unitType.Inch] = { svgUnitType: "in", scaleConversion: 1 };
|
7666 | exporter.svgUnit[MakerJs.unitType.Millimeter] = { svgUnitType: "mm", scaleConversion: 1 };
|
7667 | exporter.svgUnit[MakerJs.unitType.Centimeter] = { svgUnitType: "cm", scaleConversion: 1 };
|
7668 |
|
7669 | exporter.svgUnit[MakerJs.unitType.Foot] = { svgUnitType: "in", scaleConversion: 12 };
|
7670 | exporter.svgUnit[MakerJs.unitType.Meter] = { svgUnitType: "cm", scaleConversion: 100 };
|
7671 | })(exporter = MakerJs.exporter || (MakerJs.exporter = {}));
|
7672 | })(MakerJs || (MakerJs = {}));
|
7673 | (function (MakerJs) {
|
7674 | var importer;
|
7675 | (function (importer) {
|
7676 | |
7677 |
|
7678 |
|
7679 |
|
7680 |
|
7681 |
|
7682 |
|
7683 |
|
7684 | function fromSVGPathData(pathData, options) {
|
7685 | if (options === void 0) { options = {}; }
|
7686 | var result = {};
|
7687 | function addPath(p) {
|
7688 | if (!result.paths) {
|
7689 | result.paths = {};
|
7690 | }
|
7691 | result.paths['p_' + ++pathCount] = p;
|
7692 | }
|
7693 | function addModel(m) {
|
7694 | if (!result.models) {
|
7695 | result.models = {};
|
7696 | }
|
7697 | result.models['p_' + ++pathCount] = m;
|
7698 | }
|
7699 | function getPoint(cmd, offset) {
|
7700 | if (offset === void 0) { offset = 0; }
|
7701 | var p = MakerJs.point.mirror([cmd.data[0 + offset], cmd.data[1 + offset]], false, true);
|
7702 | if (cmd.absolute) {
|
7703 | return p;
|
7704 | }
|
7705 | else {
|
7706 | return MakerJs.point.add(p, cmd.from);
|
7707 | }
|
7708 | }
|
7709 | function lineTo(cmd, end) {
|
7710 | if (!MakerJs.measure.isPointEqual(cmd.from, end)) {
|
7711 | addPath(new MakerJs.paths.Line(cmd.from, end));
|
7712 | }
|
7713 | return end;
|
7714 | }
|
7715 | var map = {};
|
7716 | map['M'] = function (cmd) {
|
7717 | firstPoint = getPoint(cmd);
|
7718 | return firstPoint;
|
7719 | };
|
7720 | map['Z'] = function (cmd) {
|
7721 | return lineTo(cmd, firstPoint);
|
7722 | };
|
7723 | map['H'] = function (cmd) {
|
7724 | var end = MakerJs.point.clone(cmd.from);
|
7725 | if (cmd.absolute) {
|
7726 | end[0] = cmd.data[0];
|
7727 | }
|
7728 | else {
|
7729 | end[0] += cmd.data[0];
|
7730 | }
|
7731 | return lineTo(cmd, end);
|
7732 | };
|
7733 | map['V'] = function (cmd) {
|
7734 | var end = MakerJs.point.clone(cmd.from);
|
7735 |
|
7736 | if (cmd.absolute) {
|
7737 | end[1] = -cmd.data[0];
|
7738 | }
|
7739 | else {
|
7740 | end[1] -= cmd.data[0];
|
7741 | }
|
7742 | return lineTo(cmd, end);
|
7743 | };
|
7744 | map['L'] = function (cmd) {
|
7745 | var end = getPoint(cmd);
|
7746 | return lineTo(cmd, end);
|
7747 | };
|
7748 | map['A'] = function (cmd) {
|
7749 | var rx = cmd.data[0];
|
7750 | var ry = cmd.data[1];
|
7751 | var rotation = cmd.data[2];
|
7752 | var large = cmd.data[3] === 1;
|
7753 | var decreasing = cmd.data[4] === 1;
|
7754 | var end = getPoint(cmd, 5);
|
7755 | var elliptic = rx !== ry;
|
7756 |
|
7757 | var xAxis = new MakerJs.paths.Line(cmd.from, MakerJs.point.rotate(end, rotation, cmd.from));
|
7758 |
|
7759 | if (elliptic) {
|
7760 | xAxis = MakerJs.path.distort(xAxis, 1, rx / ry);
|
7761 | }
|
7762 |
|
7763 | var arc = new MakerJs.paths.Arc(xAxis.origin, xAxis.end, rx, large, decreasing);
|
7764 | if (elliptic) {
|
7765 |
|
7766 | if (rx < arc.radius) {
|
7767 | var scaleUp = arc.radius / rx;
|
7768 | rx *= scaleUp;
|
7769 | ry *= scaleUp;
|
7770 | }
|
7771 |
|
7772 | var e = new MakerJs.models.EllipticArc(arc, 1, ry / rx, options.bezierAccuracy);
|
7773 |
|
7774 | MakerJs.model.rotate(e, -rotation, cmd.from);
|
7775 | addModel(e);
|
7776 | }
|
7777 | else {
|
7778 |
|
7779 |
|
7780 | MakerJs.path.rotate(arc, -rotation, cmd.from);
|
7781 | addPath(arc);
|
7782 | }
|
7783 | return end;
|
7784 | };
|
7785 | map['C'] = function (cmd) {
|
7786 | var control1 = getPoint(cmd, 0);
|
7787 | var control2 = getPoint(cmd, 2);
|
7788 | var end = getPoint(cmd, 4);
|
7789 | addModel(new MakerJs.models.BezierCurve(cmd.from, control1, control2, end, options.bezierAccuracy));
|
7790 | return end;
|
7791 | };
|
7792 | map['S'] = function (cmd) {
|
7793 | var control1;
|
7794 | var prevControl2;
|
7795 | if (cmd.prev.command === 'C') {
|
7796 | prevControl2 = getPoint(cmd.prev, 2);
|
7797 | control1 = MakerJs.point.rotate(prevControl2, 180, cmd.from);
|
7798 | }
|
7799 | else if (cmd.prev.command === 'S') {
|
7800 | prevControl2 = getPoint(cmd.prev, 0);
|
7801 | control1 = MakerJs.point.rotate(prevControl2, 180, cmd.from);
|
7802 | }
|
7803 | else {
|
7804 | control1 = cmd.from;
|
7805 | }
|
7806 | var control2 = getPoint(cmd, 0);
|
7807 | var end = getPoint(cmd, 2);
|
7808 | addModel(new MakerJs.models.BezierCurve(cmd.from, control1, control2, end, options.bezierAccuracy));
|
7809 | return end;
|
7810 | };
|
7811 | map['Q'] = function (cmd) {
|
7812 | var control = getPoint(cmd, 0);
|
7813 | var end = getPoint(cmd, 2);
|
7814 | addModel(new MakerJs.models.BezierCurve(cmd.from, control, end, options.bezierAccuracy));
|
7815 | return end;
|
7816 | };
|
7817 | map['T'] = function (cmd) {
|
7818 | var control;
|
7819 | var prevControl;
|
7820 | if (cmd.prev.command === 'Q') {
|
7821 | prevControl = getPoint(cmd.prev, 0);
|
7822 | control = MakerJs.point.rotate(prevControl, 180, cmd.from);
|
7823 | }
|
7824 | else if (cmd.prev.command === 'T') {
|
7825 | prevControl = getPoint(cmd.prev, 2);
|
7826 | control = MakerJs.point.rotate(prevControl, 180, cmd.from);
|
7827 | }
|
7828 | else {
|
7829 | control = cmd.from;
|
7830 | }
|
7831 |
|
7832 | var p = MakerJs.point.mirror(control, false, true);
|
7833 | cmd.data.push.apply(cmd.data, p);
|
7834 | var end = getPoint(cmd, 0);
|
7835 | addModel(new MakerJs.models.BezierCurve(cmd.from, control, end, options.bezierAccuracy));
|
7836 | return end;
|
7837 | };
|
7838 | var firstPoint = [0, 0];
|
7839 | var currPoint = [0, 0];
|
7840 | var pathCount = 0;
|
7841 | var prevCommand;
|
7842 | var regexpCommands = /([achlmqstvz])([0-9e\.,\+-\s]*)/ig;
|
7843 | var commandMatches;
|
7844 | while ((commandMatches = regexpCommands.exec(pathData)) !== null) {
|
7845 | if (commandMatches.index === regexpCommands.lastIndex) {
|
7846 | regexpCommands.lastIndex++;
|
7847 | }
|
7848 | var command = commandMatches[1];
|
7849 | var dataString = commandMatches[2];
|
7850 | var currCmd = {
|
7851 | command: command.toUpperCase(),
|
7852 | data: [],
|
7853 | from: currPoint,
|
7854 | prev: prevCommand
|
7855 | };
|
7856 | if (command === currCmd.command) {
|
7857 | currCmd.absolute = true;
|
7858 | }
|
7859 | currCmd.data = importer.parseNumericList(dataString);
|
7860 | var fn = map[currCmd.command];
|
7861 | if (fn) {
|
7862 | currPoint = fn(currCmd);
|
7863 | }
|
7864 | prevCommand = currCmd;
|
7865 | }
|
7866 | return result;
|
7867 | }
|
7868 | importer.fromSVGPathData = fromSVGPathData;
|
7869 | })(importer = MakerJs.importer || (MakerJs.importer = {}));
|
7870 | })(MakerJs || (MakerJs = {}));
|
7871 | var MakerJs;
|
7872 | (function (MakerJs) {
|
7873 | var layout;
|
7874 | (function (layout) {
|
7875 | |
7876 |
|
7877 |
|
7878 | function getChildPlacement(parentModel, baseline) {
|
7879 |
|
7880 | var atlas = new MakerJs.measure.Atlas(parentModel);
|
7881 | var measureParent = MakerJs.measure.modelExtents(parentModel, atlas);
|
7882 |
|
7883 | var parentTop = measureParent.high[1];
|
7884 | var cpa = [];
|
7885 | var xMap = {};
|
7886 | var walkOptions = {
|
7887 | beforeChildWalk: function (context) {
|
7888 | var child = context.childModel;
|
7889 |
|
7890 | var m = atlas.modelMap[context.routeKey];
|
7891 | if (!m)
|
7892 | return;
|
7893 | var childMeasure = MakerJs.measure.augment(m);
|
7894 |
|
7895 | MakerJs.model.originate(child, [childMeasure.center[0], parentTop * baseline]);
|
7896 |
|
7897 | var x = child.origin[0] - measureParent.low[0];
|
7898 | xMap[context.childId] = x;
|
7899 |
|
7900 | var xRatio = x / measureParent.width;
|
7901 | cpa.push({ childId: context.childId, xRatio: xRatio });
|
7902 |
|
7903 | return false;
|
7904 | }
|
7905 | };
|
7906 | MakerJs.model.walk(parentModel, walkOptions);
|
7907 | cpa.sort(function (a, b) { return a.xRatio - b.xRatio; });
|
7908 | var first = cpa[0];
|
7909 | var last = cpa[cpa.length - 1];
|
7910 | var min = first.xRatio;
|
7911 | var max = last.xRatio;
|
7912 | var span = max - min;
|
7913 | cpa.forEach(function (cp) { return cp.xRatio = (cp.xRatio - min) / span; });
|
7914 | return {
|
7915 | cpa: cpa,
|
7916 | firstX: xMap[first.childId],
|
7917 | lastX: measureParent.width - xMap[last.childId]
|
7918 | };
|
7919 | }
|
7920 | |
7921 |
|
7922 |
|
7923 | function moveAndRotate(parentModel, cpa, rotate) {
|
7924 | cpa.forEach(function (cp) {
|
7925 | var child = parentModel.models[cp.childId];
|
7926 |
|
7927 | child.origin = cp.origin;
|
7928 |
|
7929 | if (rotate)
|
7930 | MakerJs.model.rotate(child, cp.angle, cp.origin);
|
7931 | });
|
7932 | }
|
7933 | |
7934 |
|
7935 |
|
7936 | var onPathMap = {};
|
7937 | onPathMap[MakerJs.pathType.Arc] = function (arc, reversed, cpa) {
|
7938 | var arcSpan = MakerJs.angle.ofArcSpan(arc);
|
7939 | cpa.forEach(function (p) { return p.angle = reversed ? arc.endAngle - p.xRatio * arcSpan - 90 : arc.startAngle + p.xRatio * arcSpan + 90; });
|
7940 | };
|
7941 | onPathMap[MakerJs.pathType.Line] = function (line, reversed, cpa) {
|
7942 | var lineAngle = MakerJs.angle.ofLineInDegrees(line);
|
7943 | cpa.forEach(function (p) { return p.angle = lineAngle; });
|
7944 | };
|
7945 | |
7946 |
|
7947 |
|
7948 |
|
7949 |
|
7950 |
|
7951 |
|
7952 |
|
7953 |
|
7954 |
|
7955 |
|
7956 |
|
7957 |
|
7958 | function childrenOnPath(parentModel, onPath, baseline, reversed, contain, rotate) {
|
7959 | if (baseline === void 0) { baseline = 0; }
|
7960 | if (reversed === void 0) { reversed = false; }
|
7961 | if (contain === void 0) { contain = false; }
|
7962 | if (rotate === void 0) { rotate = true; }
|
7963 | var result = getChildPlacement(parentModel, baseline);
|
7964 | var cpa = result.cpa;
|
7965 | var chosenPath = onPath;
|
7966 | if (contain) {
|
7967 |
|
7968 | var onPathLength = MakerJs.measure.pathLength(onPath);
|
7969 | if (result.firstX + result.lastX < onPathLength) {
|
7970 | chosenPath = MakerJs.path.clone(onPath);
|
7971 | MakerJs.path.alterLength(chosenPath, -result.firstX, true);
|
7972 | MakerJs.path.alterLength(chosenPath, -result.lastX);
|
7973 | }
|
7974 | }
|
7975 | cpa.forEach(function (p) { return p.origin = MakerJs.point.middle(chosenPath, reversed ? 1 - p.xRatio : p.xRatio); });
|
7976 | var fn = onPathMap[chosenPath.type];
|
7977 | if (fn) {
|
7978 | fn(chosenPath, reversed, cpa);
|
7979 | }
|
7980 | moveAndRotate(parentModel, cpa, rotate);
|
7981 | return parentModel;
|
7982 | }
|
7983 | layout.childrenOnPath = childrenOnPath;
|
7984 | |
7985 |
|
7986 |
|
7987 | function miterAngles(points, offsetAngle) {
|
7988 | var arc = new MakerJs.paths.Arc([0, 0], 0, 0, 0);
|
7989 | return points.map(function (p, i) {
|
7990 | var a;
|
7991 | if (i === 0) {
|
7992 | a = MakerJs.angle.ofPointInDegrees(p, points[i + 1]) + 90;
|
7993 | }
|
7994 | else if (i === points.length - 1) {
|
7995 | a = MakerJs.angle.ofPointInDegrees(points[i - 1], p) + 90;
|
7996 | }
|
7997 | else {
|
7998 | arc.origin = p;
|
7999 | arc.startAngle = MakerJs.angle.ofPointInDegrees(p, points[i + 1]);
|
8000 | arc.endAngle = MakerJs.angle.ofPointInDegrees(p, points[i - 1]);
|
8001 | a = MakerJs.angle.ofArcMiddle(arc);
|
8002 | }
|
8003 | return a + offsetAngle;
|
8004 | });
|
8005 | }
|
8006 | |
8007 |
|
8008 |
|
8009 |
|
8010 |
|
8011 |
|
8012 |
|
8013 |
|
8014 |
|
8015 |
|
8016 |
|
8017 |
|
8018 |
|
8019 |
|
8020 | function childrenOnChain(parentModel, onChain, baseline, reversed, contain, rotated) {
|
8021 | if (baseline === void 0) { baseline = 0; }
|
8022 | if (reversed === void 0) { reversed = false; }
|
8023 | if (contain === void 0) { contain = false; }
|
8024 | if (rotated === void 0) { rotated = true; }
|
8025 | var result = getChildPlacement(parentModel, baseline);
|
8026 | var cpa = result.cpa;
|
8027 | var chainLength = onChain.pathLength;
|
8028 | if (contain)
|
8029 | chainLength -= result.firstX + result.lastX;
|
8030 | var absolutes = cpa.map(function (cp) { return (reversed ? 1 - cp.xRatio : cp.xRatio) * chainLength; });
|
8031 | var relatives;
|
8032 | if (reversed)
|
8033 | absolutes.reverse();
|
8034 | relatives = absolutes.map(function (ab, i) { return Math.abs(ab - (i == 0 ? 0 : absolutes[i - 1])); });
|
8035 | if (contain) {
|
8036 | relatives[0] += reversed ? result.lastX : result.firstX;
|
8037 | }
|
8038 | else {
|
8039 | relatives.shift();
|
8040 | }
|
8041 |
|
8042 | var points = MakerJs.chain.toPoints(onChain, relatives);
|
8043 | if (points.length < cpa.length) {
|
8044 |
|
8045 | var endLink = onChain.links[onChain.links.length - 1];
|
8046 | points.push(endLink.endPoints[endLink.reversed ? 0 : 1]);
|
8047 | }
|
8048 | if (contain)
|
8049 | points.shift();
|
8050 | if (reversed)
|
8051 | points.reverse();
|
8052 | var angles = miterAngles(points, -90);
|
8053 | cpa.forEach(function (cp, i) {
|
8054 | cp.angle = angles[i];
|
8055 | cp.origin = points[i];
|
8056 | });
|
8057 | moveAndRotate(parentModel, cpa, rotated);
|
8058 | return parentModel;
|
8059 | }
|
8060 | layout.childrenOnChain = childrenOnChain;
|
8061 | |
8062 |
|
8063 |
|
8064 |
|
8065 |
|
8066 |
|
8067 |
|
8068 |
|
8069 |
|
8070 |
|
8071 |
|
8072 |
|
8073 |
|
8074 |
|
8075 |
|
8076 |
|
8077 |
|
8078 |
|
8079 |
|
8080 |
|
8081 |
|
8082 |
|
8083 | function cloneToRadial(itemToClone, count, angleInDegrees, rotationOrigin) {
|
8084 | var result = {};
|
8085 | var add;
|
8086 | var rotateFn;
|
8087 | if (MakerJs.isModel(itemToClone)) {
|
8088 | add = result.models = {};
|
8089 | rotateFn = MakerJs.model.rotate;
|
8090 | }
|
8091 | else {
|
8092 | add = result.paths = {};
|
8093 | rotateFn = MakerJs.path.rotate;
|
8094 | }
|
8095 | for (var i = 0; i < count; i++) {
|
8096 | add[i] = rotateFn(MakerJs.cloneObject(itemToClone), i * angleInDegrees, rotationOrigin);
|
8097 | }
|
8098 | return result;
|
8099 | }
|
8100 | layout.cloneToRadial = cloneToRadial;
|
8101 | |
8102 |
|
8103 |
|
8104 | function cloneTo(dimension, itemToClone, count, margin) {
|
8105 | var result = {};
|
8106 | var add;
|
8107 | var measureFn;
|
8108 | var moveFn;
|
8109 | if (MakerJs.isModel(itemToClone)) {
|
8110 | measureFn = MakerJs.measure.modelExtents;
|
8111 | add = result.models = {};
|
8112 | moveFn = MakerJs.model.move;
|
8113 | }
|
8114 | else {
|
8115 | measureFn = MakerJs.measure.pathExtents;
|
8116 | add = result.paths = {};
|
8117 | moveFn = MakerJs.path.move;
|
8118 | }
|
8119 | var m = measureFn(itemToClone);
|
8120 | var size = m.high[dimension] - m.low[dimension];
|
8121 | for (var i = 0; i < count; i++) {
|
8122 | var origin = [0, 0];
|
8123 | origin[dimension] = i * (size + margin);
|
8124 | add[i] = moveFn(MakerJs.cloneObject(itemToClone), origin);
|
8125 | }
|
8126 | return result;
|
8127 | }
|
8128 | |
8129 |
|
8130 |
|
8131 |
|
8132 |
|
8133 |
|
8134 |
|
8135 |
|
8136 |
|
8137 |
|
8138 |
|
8139 |
|
8140 |
|
8141 |
|
8142 |
|
8143 |
|
8144 |
|
8145 |
|
8146 |
|
8147 |
|
8148 | function cloneToColumn(itemToClone, count, margin) {
|
8149 | if (margin === void 0) { margin = 0; }
|
8150 | return cloneTo(1, itemToClone, count, margin);
|
8151 | }
|
8152 | layout.cloneToColumn = cloneToColumn;
|
8153 | |
8154 |
|
8155 |
|
8156 |
|
8157 |
|
8158 |
|
8159 |
|
8160 |
|
8161 |
|
8162 |
|
8163 |
|
8164 |
|
8165 |
|
8166 |
|
8167 |
|
8168 |
|
8169 |
|
8170 |
|
8171 |
|
8172 |
|
8173 |
|
8174 |
|
8175 |
|
8176 |
|
8177 |
|
8178 | function cloneToRow(itemToClone, count, margin) {
|
8179 | if (margin === void 0) { margin = 0; }
|
8180 | return cloneTo(0, itemToClone, count, margin);
|
8181 | }
|
8182 | layout.cloneToRow = cloneToRow;
|
8183 | |
8184 |
|
8185 |
|
8186 |
|
8187 |
|
8188 |
|
8189 |
|
8190 |
|
8191 |
|
8192 |
|
8193 |
|
8194 |
|
8195 |
|
8196 |
|
8197 |
|
8198 |
|
8199 |
|
8200 |
|
8201 | function cloneToGrid(itemToClone, xCount, yCount, margin) {
|
8202 | var margins = getMargins(margin);
|
8203 | return cloneToColumn(cloneToRow(itemToClone, xCount, margins[0]), yCount, margins[1]);
|
8204 | }
|
8205 | layout.cloneToGrid = cloneToGrid;
|
8206 | |
8207 |
|
8208 |
|
8209 | function getMargins(margin) {
|
8210 | if (Array.isArray(margin)) {
|
8211 | return margin;
|
8212 | }
|
8213 | else {
|
8214 | return [margin, margin];
|
8215 | }
|
8216 | }
|
8217 | |
8218 |
|
8219 |
|
8220 | function cloneToAlternatingRows(itemToClone, xCount, yCount, spacingFn) {
|
8221 | var modelToMeasure;
|
8222 | if (MakerJs.isModel(itemToClone)) {
|
8223 | modelToMeasure = itemToClone;
|
8224 | }
|
8225 | else {
|
8226 | modelToMeasure = { paths: { "0": itemToClone } };
|
8227 | }
|
8228 | var spacing = spacingFn(modelToMeasure);
|
8229 | var result = { models: {} };
|
8230 | for (var i = 0; i < yCount; i++) {
|
8231 | var i2 = i % 2;
|
8232 | result.models[i] = MakerJs.model.move(cloneToRow(itemToClone, xCount + i2, spacing.xMargin), [i2 * spacing.x, i * spacing.y]);
|
8233 | }
|
8234 | return result;
|
8235 | }
|
8236 | |
8237 |
|
8238 |
|
8239 |
|
8240 |
|
8241 |
|
8242 |
|
8243 |
|
8244 |
|
8245 |
|
8246 |
|
8247 |
|
8248 |
|
8249 |
|
8250 |
|
8251 |
|
8252 |
|
8253 |
|
8254 |
|
8255 |
|
8256 |
|
8257 |
|
8258 |
|
8259 |
|
8260 |
|
8261 |
|
8262 | function cloneToBrick(itemToClone, xCount, yCount, margin) {
|
8263 | var margins = getMargins(margin);
|
8264 | function spacing(modelToMeasure) {
|
8265 | var m = MakerJs.measure.modelExtents(modelToMeasure);
|
8266 | var xMargin = margins[0] || 0;
|
8267 | var yMargin = margins[1] || 0;
|
8268 | return { x: (m.width + xMargin) / -2, y: m.height + yMargin, xMargin: xMargin };
|
8269 | }
|
8270 | return cloneToAlternatingRows(itemToClone, xCount, yCount, spacing);
|
8271 | }
|
8272 | layout.cloneToBrick = cloneToBrick;
|
8273 | |
8274 |
|
8275 |
|
8276 |
|
8277 |
|
8278 |
|
8279 |
|
8280 |
|
8281 |
|
8282 |
|
8283 |
|
8284 |
|
8285 |
|
8286 |
|
8287 |
|
8288 |
|
8289 |
|
8290 |
|
8291 | function cloneToHoneycomb(itemToClone, xCount, yCount, margin) {
|
8292 | if (margin === void 0) { margin = 0; }
|
8293 | function spacing(modelToMeasure) {
|
8294 | var hex = MakerJs.measure.boundingHexagon(modelToMeasure);
|
8295 | var width = 2 * MakerJs.solvers.equilateralAltitude(hex.radius);
|
8296 | var s = width + margin;
|
8297 | return { x: s / -2, y: MakerJs.solvers.equilateralAltitude(s), xMargin: margin };
|
8298 | }
|
8299 | return cloneToAlternatingRows(itemToClone, xCount, yCount, spacing);
|
8300 | }
|
8301 | layout.cloneToHoneycomb = cloneToHoneycomb;
|
8302 | })(layout = MakerJs.layout || (MakerJs.layout = {}));
|
8303 | })(MakerJs || (MakerJs = {}));
|
8304 | var MakerJs;
|
8305 | (function (MakerJs) {
|
8306 | var models;
|
8307 | (function (models) {
|
8308 | |
8309 |
|
8310 |
|
8311 | var hasLib = false;
|
8312 | |
8313 |
|
8314 |
|
8315 | function ensureBezierLib() {
|
8316 | if (hasLib)
|
8317 | return;
|
8318 | try {
|
8319 | var lib = Bezier.prototype;
|
8320 | hasLib = true;
|
8321 | }
|
8322 | catch (e) {
|
8323 | throw "Bezier library not found. If you are using Node, try running 'npm install' or if you are in the browser, download http://pomax.github.io/bezierjs/bezier.js to your website and add a script tag.";
|
8324 | }
|
8325 | }
|
8326 | |
8327 |
|
8328 |
|
8329 | var scratch;
|
8330 | |
8331 |
|
8332 |
|
8333 | function getScratch(seed) {
|
8334 | var points = [seed.origin];
|
8335 | points.push.apply(points, seed.controls);
|
8336 | points.push(seed.end);
|
8337 | var bezierJsPoints = points.map(function (p) {
|
8338 | var bp = {
|
8339 | x: p[0], y: p[1]
|
8340 | };
|
8341 | return bp;
|
8342 | });
|
8343 | if (!scratch) {
|
8344 | ensureBezierLib();
|
8345 | scratch = new Bezier(bezierJsPoints);
|
8346 | }
|
8347 | else {
|
8348 |
|
8349 | Bezier.apply(scratch, bezierJsPoints);
|
8350 | }
|
8351 | return scratch;
|
8352 | }
|
8353 | |
8354 |
|
8355 |
|
8356 | function BezierToSeed(b, range) {
|
8357 | var points = b.points.map(getIPoint);
|
8358 | var seed = new BezierSeed(points);
|
8359 | if (range) {
|
8360 | seed.parentRange = range;
|
8361 | }
|
8362 | return seed;
|
8363 | }
|
8364 | |
8365 |
|
8366 |
|
8367 | function seedToBezier(seed) {
|
8368 | var coords = [];
|
8369 | coords.push.apply(coords, seed.origin);
|
8370 | coords.push.apply(coords, seed.controls[0]);
|
8371 | if (seed.controls.length > 1) {
|
8372 | coords.push.apply(coords, seed.controls[1]);
|
8373 | }
|
8374 | coords.push.apply(coords, seed.end);
|
8375 | ensureBezierLib();
|
8376 | return new Bezier(coords);
|
8377 | }
|
8378 | |
8379 |
|
8380 |
|
8381 | function getExtrema(b) {
|
8382 | var extrema = b.extrema().values
|
8383 |
|
8384 | .map(function (m) { return MakerJs.round(m); })
|
8385 |
|
8386 | .filter(function (value, index, self) { return self.indexOf(value) === index; })
|
8387 |
|
8388 | .sort();
|
8389 | if (extrema.length === 0)
|
8390 | return [0, 1];
|
8391 |
|
8392 | if (extrema[0] !== 0) {
|
8393 | extrema.unshift(0);
|
8394 | }
|
8395 |
|
8396 | if (extrema[extrema.length - 1] !== 1) {
|
8397 | extrema.push(1);
|
8398 | }
|
8399 | return extrema;
|
8400 | }
|
8401 | |
8402 |
|
8403 |
|
8404 | function getIPoint(p) {
|
8405 | return [p.x, p.y];
|
8406 | }
|
8407 | |
8408 |
|
8409 |
|
8410 | var TPoint = (function () {
|
8411 | function TPoint(b, t, offset) {
|
8412 | this.t = t;
|
8413 | this.point = MakerJs.point.add(getIPoint(b.get(t)), offset);
|
8414 | }
|
8415 | return TPoint;
|
8416 | }());
|
8417 | |
8418 |
|
8419 |
|
8420 | function getError(b, startT, endT, arc, arcReversed) {
|
8421 | var tSpan = endT - startT;
|
8422 | function m(ratio) {
|
8423 | var t = startT + tSpan * ratio;
|
8424 | var bp = getIPoint(b.get(t));
|
8425 | var ap = MakerJs.point.middle(arc, arcReversed ? 1 - ratio : ratio);
|
8426 | return MakerJs.measure.pointDistance(ap, bp);
|
8427 | }
|
8428 | return m(0.25) + m(0.75);
|
8429 | }
|
8430 | |
8431 |
|
8432 |
|
8433 | function getLargestArc(b, startT, endT, accuracy) {
|
8434 | var arc, lastGoodArc;
|
8435 | var start = new TPoint(b, startT);
|
8436 | var end = new TPoint(b, endT);
|
8437 | var upper = end;
|
8438 | var lower = start;
|
8439 | var count = 0;
|
8440 | var test = upper;
|
8441 | var reversed;
|
8442 | while (count < 100) {
|
8443 | var middle = getIPoint(b.get((start.t + test.t) / 2));
|
8444 |
|
8445 | try {
|
8446 | arc = new MakerJs.paths.Arc(start.point, middle, test.point);
|
8447 | }
|
8448 | catch (e) {
|
8449 | if (lastGoodArc) {
|
8450 | return lastGoodArc;
|
8451 | }
|
8452 | else {
|
8453 | break;
|
8454 | }
|
8455 | }
|
8456 |
|
8457 | if (reversed === undefined) {
|
8458 | reversed = MakerJs.measure.isPointEqual(start.point, MakerJs.point.fromAngleOnCircle(arc.endAngle, arc));
|
8459 | }
|
8460 |
|
8461 | var error = getError(b, startT, test.t, arc, reversed);
|
8462 |
|
8463 | if (error <= accuracy) {
|
8464 | arc.bezierData = {
|
8465 | startT: startT,
|
8466 | endT: test.t
|
8467 | };
|
8468 | lower = test;
|
8469 | lastGoodArc = arc;
|
8470 | }
|
8471 | else {
|
8472 | upper = test;
|
8473 | }
|
8474 |
|
8475 | if (lower.t === upper.t || (lastGoodArc && (lastGoodArc !== arc) && (MakerJs.angle.ofArcSpan(arc) - MakerJs.angle.ofArcSpan(lastGoodArc)) < .5)) {
|
8476 | return lastGoodArc;
|
8477 | }
|
8478 | count++;
|
8479 | test = new TPoint(b, (lower.t + upper.t) / 2);
|
8480 | }
|
8481 |
|
8482 | var line = new MakerJs.paths.Line(start.point, test.point);
|
8483 | line.bezierData = {
|
8484 | startT: startT,
|
8485 | endT: test.t
|
8486 | };
|
8487 | return line;
|
8488 | }
|
8489 | |
8490 |
|
8491 |
|
8492 | function getArcs(bc, b, accuracy, startT, endT, base) {
|
8493 | var added = 0;
|
8494 | var arc;
|
8495 | while (startT < endT) {
|
8496 | arc = getLargestArc(b, startT, endT, accuracy);
|
8497 |
|
8498 | startT = arc.bezierData.endT;
|
8499 | var len = MakerJs.measure.pathLength(arc);
|
8500 | if (len < .0001) {
|
8501 | continue;
|
8502 | }
|
8503 | bc.paths[arc.type + '_' + (base + added)] = arc;
|
8504 | added++;
|
8505 | }
|
8506 | return added;
|
8507 | }
|
8508 | |
8509 |
|
8510 |
|
8511 | function getActualBezierRange(curve, arc, endpoints, offset) {
|
8512 | var b = getScratch(curve.seed);
|
8513 | var tPoints = [arc.bezierData.startT, arc.bezierData.endT].map(function (t) { return new TPoint(b, t, offset); });
|
8514 | var ends = endpoints.slice();
|
8515 |
|
8516 | var endpointDistancetoStart = ends.map(function (e) { return MakerJs.measure.pointDistance(e, tPoints[0].point); });
|
8517 | if (endpointDistancetoStart[0] > endpointDistancetoStart[1])
|
8518 | ends.reverse();
|
8519 | for (var i = 2; i--;) {
|
8520 | if (!MakerJs.measure.isPointEqual(ends[i], tPoints[i].point)) {
|
8521 | return null;
|
8522 | }
|
8523 | }
|
8524 | return arc.bezierData;
|
8525 | }
|
8526 | |
8527 |
|
8528 |
|
8529 | function getChainBezierRange(curve, c, layer, addToLayer) {
|
8530 | var endLinks = [c.links[0], c.links[c.links.length - 1]];
|
8531 | if (endLinks[0].walkedPath.pathContext.bezierData.startT > endLinks[1].walkedPath.pathContext.bezierData.startT) {
|
8532 | MakerJs.chain.reverse(c);
|
8533 | endLinks.reverse();
|
8534 | }
|
8535 | var actualBezierRanges = endLinks.map(function (endLink) { return getActualBezierRange(curve, endLink.walkedPath.pathContext, endLink.endPoints, endLink.walkedPath.offset); });
|
8536 | var result = {
|
8537 | startT: actualBezierRanges[0] ? actualBezierRanges[0].startT : null,
|
8538 | endT: actualBezierRanges[1] ? actualBezierRanges[1].endT : null
|
8539 | };
|
8540 | if (result.startT !== null && result.endT !== null) {
|
8541 | return result;
|
8542 | }
|
8543 | else if (c.links.length > 2) {
|
8544 | if (result.startT === null) {
|
8545 |
|
8546 | addToLayer(c.links[0].walkedPath.pathContext, layer, true);
|
8547 | result.startT = c.links[1].walkedPath.pathContext.bezierData.startT;
|
8548 | }
|
8549 | if (result.endT === null) {
|
8550 |
|
8551 | addToLayer(c.links[c.links.length - 1].walkedPath.pathContext, layer, true);
|
8552 | result.endT = c.links[c.links.length - 2].walkedPath.pathContext.bezierData.endT;
|
8553 | }
|
8554 | return result;
|
8555 | }
|
8556 | return null;
|
8557 | }
|
8558 | |
8559 |
|
8560 |
|
8561 |
|
8562 | var BezierSeed = (function () {
|
8563 | function BezierSeed() {
|
8564 | var args = [];
|
8565 | for (var _i = 0; _i < arguments.length; _i++) {
|
8566 | args[_i] = arguments[_i];
|
8567 | }
|
8568 | this.type = MakerJs.pathType.BezierSeed;
|
8569 | switch (args.length) {
|
8570 | case 1:
|
8571 | var points = args[0];
|
8572 | this.origin = points[0];
|
8573 | if (points.length === 3) {
|
8574 | this.controls = [points[1]];
|
8575 | this.end = points[2];
|
8576 | }
|
8577 | else if (points.length === 4) {
|
8578 | this.controls = [points[1], points[2]];
|
8579 | this.end = points[3];
|
8580 | }
|
8581 | else {
|
8582 | this.end = points[1];
|
8583 | }
|
8584 | break;
|
8585 | case 3:
|
8586 | if (Array.isArray(args[1])) {
|
8587 | this.controls = args[1];
|
8588 | }
|
8589 | else {
|
8590 | this.controls = [args[1]];
|
8591 | }
|
8592 | this.end = args[2];
|
8593 | break;
|
8594 | case 4:
|
8595 | this.controls = [args[1], args[2]];
|
8596 | this.end = args[3];
|
8597 | break;
|
8598 | }
|
8599 | }
|
8600 | return BezierSeed;
|
8601 | }());
|
8602 | var BezierCurve = (function () {
|
8603 | function BezierCurve() {
|
8604 | var args = [];
|
8605 | for (var _i = 0; _i < arguments.length; _i++) {
|
8606 | args[_i] = arguments[_i];
|
8607 | }
|
8608 | this.type = BezierCurve.typeName;
|
8609 | var isArrayArg0 = Array.isArray(args[0]);
|
8610 | switch (args.length) {
|
8611 | case 2:
|
8612 | if (isArrayArg0) {
|
8613 | this.accuracy = args[1];
|
8614 | }
|
8615 | else {
|
8616 |
|
8617 | this.seed = args[0];
|
8618 | this.accuracy = args[1];
|
8619 | break;
|
8620 | }
|
8621 |
|
8622 | case 1:
|
8623 | if (isArrayArg0) {
|
8624 | var points = args[0];
|
8625 | this.seed = new BezierSeed(points);
|
8626 | }
|
8627 | else {
|
8628 | this.seed = args[0];
|
8629 | }
|
8630 | break;
|
8631 | default:
|
8632 | switch (args.length) {
|
8633 | case 4:
|
8634 | if (MakerJs.isPoint(args[3])) {
|
8635 | this.seed = new BezierSeed(args);
|
8636 | break;
|
8637 | }
|
8638 | else {
|
8639 | this.accuracy = args[3];
|
8640 |
|
8641 | }
|
8642 | case 3:
|
8643 | if (isArrayArg0) {
|
8644 | this.seed = new BezierSeed(args.slice(0, 3));
|
8645 | }
|
8646 | break;
|
8647 | case 5:
|
8648 | this.accuracy = args[4];
|
8649 | this.seed = new BezierSeed(args.slice(0, 4));
|
8650 | break;
|
8651 | }
|
8652 | break;
|
8653 | }
|
8654 | this.paths = {};
|
8655 | if (MakerJs.measure.isBezierSeedLinear(this.seed)) {
|
8656 |
|
8657 | var line = new MakerJs.paths.Line(MakerJs.point.clone(this.seed.origin), MakerJs.point.clone(this.seed.end));
|
8658 | line.bezierData = {
|
8659 | startT: 0,
|
8660 | endT: 1
|
8661 | };
|
8662 | this.paths = {
|
8663 | "0": line
|
8664 | };
|
8665 | return;
|
8666 | }
|
8667 | var b = seedToBezier(this.seed);
|
8668 | var extrema = getExtrema(b);
|
8669 | this.paths = {};
|
8670 |
|
8671 | if (!this.accuracy) {
|
8672 |
|
8673 | var len = b.length();
|
8674 |
|
8675 | this.accuracy = len / 100;
|
8676 | }
|
8677 | var count = 0;
|
8678 | for (var i = 1; i < extrema.length; i++) {
|
8679 | var extremaSpan = extrema[i] - extrema[i - 1];
|
8680 | count += getArcs(this, b, this.accuracy * extremaSpan, extrema[i - 1], extrema[i], count);
|
8681 | }
|
8682 | }
|
8683 | BezierCurve.getBezierSeeds = function (curve, options) {
|
8684 | if (options === void 0) { options = {}; }
|
8685 | options.shallow = true;
|
8686 | options.unifyBeziers = false;
|
8687 | var seedsByLayer = {};
|
8688 | var addToLayer = function (pathToAdd, layer, clone) {
|
8689 | if (clone === void 0) { clone = false; }
|
8690 | if (!seedsByLayer[layer]) {
|
8691 | seedsByLayer[layer] = [];
|
8692 | }
|
8693 | seedsByLayer[layer].push(clone ? MakerJs.path.clone(pathToAdd) : pathToAdd);
|
8694 | };
|
8695 | MakerJs.model.findChains(curve, function (chains, loose, layer) {
|
8696 | chains.forEach(function (c) {
|
8697 | var range = getChainBezierRange(curve, c, layer, addToLayer);
|
8698 | if (range) {
|
8699 | var b = getScratch(curve.seed);
|
8700 | var piece = b.split(range.startT, range.endT);
|
8701 | addToLayer(BezierToSeed(piece), layer);
|
8702 | }
|
8703 | else {
|
8704 | c.links.forEach(function (link) { return addToLayer(link.walkedPath.pathContext, layer, true); });
|
8705 | }
|
8706 | });
|
8707 | loose.forEach(function (wp) {
|
8708 | if (wp.pathContext.type === MakerJs.pathType.Line) {
|
8709 |
|
8710 | return addToLayer(wp.pathContext, layer, true);
|
8711 | }
|
8712 | var range = getActualBezierRange(curve, wp.pathContext, MakerJs.point.fromPathEnds(wp.pathContext), wp.offset);
|
8713 | if (range) {
|
8714 | var b = getScratch(curve.seed);
|
8715 | var piece = b.split(range.startT, range.endT);
|
8716 | addToLayer(BezierToSeed(piece), layer);
|
8717 | }
|
8718 | else {
|
8719 | addToLayer(wp.pathContext, layer, true);
|
8720 | }
|
8721 | });
|
8722 | }, options);
|
8723 | if (options.byLayers) {
|
8724 | return seedsByLayer;
|
8725 | }
|
8726 | else {
|
8727 | return seedsByLayer[''];
|
8728 | }
|
8729 | };
|
8730 | BezierCurve.computeLength = function (seed) {
|
8731 | var b = seedToBezier(seed);
|
8732 | return b.length();
|
8733 | };
|
8734 | BezierCurve.computePoint = function (seed, t) {
|
8735 | var s = getScratch(seed);
|
8736 | var computedPoint = s.compute(t);
|
8737 | return getIPoint(computedPoint);
|
8738 | };
|
8739 | BezierCurve.typeName = 'BezierCurve';
|
8740 | return BezierCurve;
|
8741 | }());
|
8742 | models.BezierCurve = BezierCurve;
|
8743 | BezierCurve.metaParameters = [
|
8744 | {
|
8745 | title: "points", type: "select", value: [
|
8746 | [[100, 0], [-80, -60], [100, 220], [100, 60]],
|
8747 | [[0, 0], [100, 0], [100, 100]],
|
8748 | [[0, 0], [20, 0], [80, 100], [100, 100]]
|
8749 | ]
|
8750 | }
|
8751 | ];
|
8752 | })(models = MakerJs.models || (MakerJs.models = {}));
|
8753 | })(MakerJs || (MakerJs = {}));
|
8754 | var MakerJs;
|
8755 | (function (MakerJs) {
|
8756 | var models;
|
8757 | (function (models) {
|
8758 | |
8759 |
|
8760 |
|
8761 |
|
8762 | var maxBezierArcspan = 45;
|
8763 | |
8764 |
|
8765 |
|
8766 | function controlYForCircularCubic(arcSpanInRadians) {
|
8767 |
|
8768 | return 4 * (Math.tan(arcSpanInRadians / 4) / 3);
|
8769 | }
|
8770 | |
8771 |
|
8772 |
|
8773 | function controlPointsForCircularCubic(arc) {
|
8774 | var arcSpan = MakerJs.angle.ofArcSpan(arc);
|
8775 |
|
8776 | var y = controlYForCircularCubic(MakerJs.angle.toRadians(arcSpan));
|
8777 |
|
8778 | var c1 = [arc.radius, arc.radius * y];
|
8779 |
|
8780 | var c2 = MakerJs.point.rotate(MakerJs.point.mirror(c1, false, true), arcSpan, [0, 0]);
|
8781 |
|
8782 | return [c1, c2].map(function (p) { return MakerJs.point.add(arc.origin, MakerJs.point.rotate(p, arc.startAngle, [0, 0])); });
|
8783 | }
|
8784 | |
8785 |
|
8786 |
|
8787 | function bezierSeedFromArc(arc) {
|
8788 | var span = MakerJs.angle.ofArcSpan(arc);
|
8789 | if (span <= 90) {
|
8790 | var endPoints = MakerJs.point.fromPathEnds(arc);
|
8791 | var controls = controlPointsForCircularCubic(arc);
|
8792 | return {
|
8793 | type: MakerJs.pathType.BezierSeed,
|
8794 | origin: endPoints[0],
|
8795 | controls: controls,
|
8796 | end: endPoints[1]
|
8797 | };
|
8798 | }
|
8799 | return null;
|
8800 | }
|
8801 | var Ellipse = (function () {
|
8802 | function Ellipse() {
|
8803 | var args = [];
|
8804 | for (var _i = 0; _i < arguments.length; _i++) {
|
8805 | args[_i] = arguments[_i];
|
8806 | }
|
8807 | var _this = this;
|
8808 | this.models = {};
|
8809 | var n = 360 / maxBezierArcspan;
|
8810 | var accuracy;
|
8811 | var isPointArgs0 = MakerJs.isPoint(args[0]);
|
8812 | var realArgs = function (numArgs) {
|
8813 | switch (numArgs) {
|
8814 | case 2:
|
8815 | if (isPointArgs0) {
|
8816 |
|
8817 | _this.origin = args[0];
|
8818 | }
|
8819 | break;
|
8820 | case 3:
|
8821 |
|
8822 | _this.origin = args[0];
|
8823 | break;
|
8824 | case 4:
|
8825 |
|
8826 | _this.origin = [args[0], args[1]];
|
8827 | break;
|
8828 | }
|
8829 |
|
8830 | var a = 360 / n;
|
8831 | var arc = new MakerJs.paths.Arc([0, 0], 1, 0, a);
|
8832 |
|
8833 | for (var i = 0; i < n; i++) {
|
8834 | var seed = bezierSeedFromArc(arc);
|
8835 | switch (numArgs) {
|
8836 | case 1:
|
8837 |
|
8838 | seed = MakerJs.path.scale(seed, args[0]);
|
8839 | break;
|
8840 | case 2:
|
8841 | if (isPointArgs0) {
|
8842 |
|
8843 | seed = MakerJs.path.scale(seed, args[1]);
|
8844 | }
|
8845 | else {
|
8846 |
|
8847 | seed = MakerJs.path.distort(seed, args[0], args[1]);
|
8848 | }
|
8849 | break;
|
8850 | case 3:
|
8851 |
|
8852 | seed = MakerJs.path.distort(seed, args[1], args[2]);
|
8853 | break;
|
8854 | case 4:
|
8855 |
|
8856 | seed = MakerJs.path.distort(seed, args[2], args[3]);
|
8857 | break;
|
8858 | }
|
8859 | _this.models['Curve_' + (1 + i)] = new models.BezierCurve(seed, accuracy);
|
8860 | arc.startAngle += a;
|
8861 | arc.endAngle += a;
|
8862 | }
|
8863 | };
|
8864 | switch (args.length) {
|
8865 | case 2:
|
8866 | realArgs(2);
|
8867 | break;
|
8868 | case 3:
|
8869 | if (isPointArgs0) {
|
8870 | realArgs(3);
|
8871 | }
|
8872 | else {
|
8873 | accuracy = args[2];
|
8874 | realArgs(2);
|
8875 | }
|
8876 | break;
|
8877 | case 4:
|
8878 | if (isPointArgs0) {
|
8879 | accuracy = args[3];
|
8880 | realArgs(3);
|
8881 | }
|
8882 | else {
|
8883 | realArgs(4);
|
8884 | }
|
8885 | break;
|
8886 | case 5:
|
8887 | accuracy = args[4];
|
8888 | realArgs(4);
|
8889 | break;
|
8890 | }
|
8891 | }
|
8892 | return Ellipse;
|
8893 | }());
|
8894 | models.Ellipse = Ellipse;
|
8895 | Ellipse.metaParameters = [
|
8896 | { title: "radiusX", type: "range", min: 1, max: 50, value: 50 },
|
8897 | { title: "radiusY", type: "range", min: 1, max: 50, value: 25 }
|
8898 | ];
|
8899 | var EllipticArc = (function () {
|
8900 | function EllipticArc() {
|
8901 | var args = [];
|
8902 | for (var _i = 0; _i < arguments.length; _i++) {
|
8903 | args[_i] = arguments[_i];
|
8904 | }
|
8905 | this.models = {};
|
8906 | var arc;
|
8907 | var accuracy;
|
8908 | var distortX;
|
8909 | var distortY;
|
8910 | if (MakerJs.isPathArc(args[0])) {
|
8911 | arc = args[0];
|
8912 | distortX = args[1];
|
8913 | distortY = args[2];
|
8914 | accuracy = args[3];
|
8915 | }
|
8916 | else {
|
8917 | arc = new MakerJs.paths.Arc([0, 0], 1, args[0], args[1]);
|
8918 | distortX = args[2];
|
8919 | distortY = args[3];
|
8920 | accuracy = args[4];
|
8921 | }
|
8922 | var span = MakerJs.angle.ofArcSpan(arc);
|
8923 |
|
8924 | var count = Math.ceil(span / maxBezierArcspan);
|
8925 | var subSpan = span / count;
|
8926 | var subArc = MakerJs.path.clone(arc);
|
8927 | for (var i = 0; i < count; i++) {
|
8928 | subArc.startAngle = arc.startAngle + (i * subSpan);
|
8929 | subArc.endAngle = subArc.startAngle + subSpan;
|
8930 | var seed = bezierSeedFromArc(subArc);
|
8931 | seed = MakerJs.path.distort(seed, distortX, distortY);
|
8932 | this.models['Curve_' + (1 + i)] = new models.BezierCurve(seed, accuracy);
|
8933 | }
|
8934 | }
|
8935 | return EllipticArc;
|
8936 | }());
|
8937 | models.EllipticArc = EllipticArc;
|
8938 | EllipticArc.metaParameters = [
|
8939 | { title: "startAngle", type: "range", min: 0, max: 90, value: 0 },
|
8940 | { title: "endAngle", type: "range", min: 90, max: 360, value: 180 },
|
8941 | { title: "radiusX", type: "range", min: 1, max: 50, value: 50 },
|
8942 | { title: "radiusY", type: "range", min: 1, max: 50, value: 25 }
|
8943 | ];
|
8944 | })(models = MakerJs.models || (MakerJs.models = {}));
|
8945 | })(MakerJs || (MakerJs = {}));
|
8946 | var MakerJs;
|
8947 | (function (MakerJs) {
|
8948 | var models;
|
8949 | (function (models) {
|
8950 | |
8951 |
|
8952 |
|
8953 | function getPoints(arg) {
|
8954 | var coords;
|
8955 | if (Array.isArray(arg)) {
|
8956 | if (MakerJs.isPoint(arg[0])) {
|
8957 | return arg;
|
8958 | }
|
8959 | coords = arg;
|
8960 | }
|
8961 | else {
|
8962 | coords = MakerJs.importer.parseNumericList(arg);
|
8963 | }
|
8964 | var points = [];
|
8965 | for (var i = 0; i < coords.length; i += 2) {
|
8966 | points.push([coords[i], coords[i + 1]]);
|
8967 | }
|
8968 | return points;
|
8969 | }
|
8970 | var ConnectTheDots = (function () {
|
8971 | function ConnectTheDots() {
|
8972 | var args = [];
|
8973 | for (var _i = 0; _i < arguments.length; _i++) {
|
8974 | args[_i] = arguments[_i];
|
8975 | }
|
8976 | var _this = this;
|
8977 | this.paths = {};
|
8978 | var isClosed;
|
8979 | var points;
|
8980 | switch (args.length) {
|
8981 | case 1:
|
8982 | isClosed = true;
|
8983 | points = getPoints(args[0]);
|
8984 | break;
|
8985 | case 2:
|
8986 | isClosed = args[0];
|
8987 | points = getPoints(args[1]);
|
8988 | break;
|
8989 | }
|
8990 | var connect = function (a, b, skipZeroDistance) {
|
8991 | if (skipZeroDistance === void 0) { skipZeroDistance = false; }
|
8992 | if (skipZeroDistance && MakerJs.measure.pointDistance(points[a], points[b]) == 0)
|
8993 | return;
|
8994 | _this.paths["ShapeLine" + i] = new MakerJs.paths.Line(points[a], points[b]);
|
8995 | };
|
8996 | for (var i = 1; i < points.length; i++) {
|
8997 | connect(i - 1, i);
|
8998 | }
|
8999 | if (isClosed && points.length > 2) {
|
9000 | connect(points.length - 1, 0, true);
|
9001 | }
|
9002 | }
|
9003 | return ConnectTheDots;
|
9004 | }());
|
9005 | models.ConnectTheDots = ConnectTheDots;
|
9006 | ConnectTheDots.metaParameters = [
|
9007 | { title: "closed", type: "bool", value: true },
|
9008 | {
|
9009 | title: "points", type: "select", value: [
|
9010 | [[0, 0], [40, 40], [60, 20], [100, 100], [60, 60], [40, 80]],
|
9011 | [[0, 0], [100, 0], [50, 87]],
|
9012 | [-10, 0, 10, 0, 0, 20],
|
9013 | '-10 0 10 0 0 20',
|
9014 | ]
|
9015 | }
|
9016 | ];
|
9017 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9018 | })(MakerJs || (MakerJs = {}));
|
9019 | var MakerJs;
|
9020 | (function (MakerJs) {
|
9021 | var models;
|
9022 | (function (models) {
|
9023 | var Polygon = (function () {
|
9024 | function Polygon(numberOfSides, radius, firstCornerAngleInDegrees, circumscribed) {
|
9025 | this.paths = {};
|
9026 | this.paths = new models.ConnectTheDots(true, Polygon.getPoints(numberOfSides, radius, firstCornerAngleInDegrees, circumscribed)).paths;
|
9027 | }
|
9028 | Polygon.circumscribedRadius = function (radius, angleInRadians) {
|
9029 | return radius / Math.cos(angleInRadians / 2);
|
9030 | };
|
9031 | Polygon.getPoints = function (numberOfSides, radius, firstCornerAngleInDegrees, circumscribed) {
|
9032 | if (firstCornerAngleInDegrees === void 0) { firstCornerAngleInDegrees = 0; }
|
9033 | if (circumscribed === void 0) { circumscribed = false; }
|
9034 | var points = [];
|
9035 | var a1 = MakerJs.angle.toRadians(firstCornerAngleInDegrees);
|
9036 | var a = 2 * Math.PI / numberOfSides;
|
9037 | if (circumscribed) {
|
9038 | radius = Polygon.circumscribedRadius(radius, a);
|
9039 | }
|
9040 | for (var i = 0; i < numberOfSides; i++) {
|
9041 | points.push(MakerJs.point.fromPolar(a * i + a1, radius));
|
9042 | }
|
9043 | return points;
|
9044 | };
|
9045 | return Polygon;
|
9046 | }());
|
9047 | models.Polygon = Polygon;
|
9048 | Polygon.metaParameters = [
|
9049 | { title: "number of sides", type: "range", min: 3, max: 24, value: 6 },
|
9050 | { title: "radius", type: "range", min: 1, max: 100, value: 50 },
|
9051 | { title: "offset angle", type: "range", min: 0, max: 180, value: 0 },
|
9052 | { title: "radius on flats (vs radius on vertexes)", type: "bool", value: false }
|
9053 | ];
|
9054 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9055 | })(MakerJs || (MakerJs = {}));
|
9056 | var MakerJs;
|
9057 | (function (MakerJs) {
|
9058 | var models;
|
9059 | (function (models) {
|
9060 | var Holes = (function () {
|
9061 | |
9062 |
|
9063 |
|
9064 |
|
9065 |
|
9066 |
|
9067 |
|
9068 |
|
9069 |
|
9070 |
|
9071 |
|
9072 |
|
9073 |
|
9074 |
|
9075 |
|
9076 |
|
9077 | function Holes(holeRadius, points, ids) {
|
9078 | this.paths = {};
|
9079 | for (var i = 0; i < points.length; i++) {
|
9080 | var id = ids ? ids[i] : i.toString();
|
9081 | this.paths[id] = new MakerJs.paths.Circle(points[i], holeRadius);
|
9082 | }
|
9083 | }
|
9084 | return Holes;
|
9085 | }());
|
9086 | models.Holes = Holes;
|
9087 | Holes.metaParameters = [
|
9088 | { title: "holeRadius", type: "range", min: .1, max: 10, step: .1, value: 1 },
|
9089 | {
|
9090 | title: "points", type: "select", value: [
|
9091 | [[0, 0], [10, 10], [20, 20], [30, 30], [40, 40], [50, 50], [60, 60], [70, 70], [80, 80]],
|
9092 | [[0, 0], [0, 25], [0, 50], [0, 75], [0, 100], [25, 50], [50, 50], [75, 50], [100, 100], [100, 75], [100, 50], [100, 25], [100, 0]]
|
9093 | ]
|
9094 | }
|
9095 | ];
|
9096 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9097 | })(MakerJs || (MakerJs = {}));
|
9098 | var MakerJs;
|
9099 | (function (MakerJs) {
|
9100 | var models;
|
9101 | (function (models) {
|
9102 | var BoltCircle = (function () {
|
9103 | function BoltCircle(boltRadius, holeRadius, boltCount, firstBoltAngleInDegrees) {
|
9104 | if (firstBoltAngleInDegrees === void 0) { firstBoltAngleInDegrees = 0; }
|
9105 | this.paths = {};
|
9106 | var points = models.Polygon.getPoints(boltCount, boltRadius, firstBoltAngleInDegrees);
|
9107 | var ids = points.map(function (p, i) { return "bolt " + i; });
|
9108 | this.paths = new models.Holes(holeRadius, points, ids).paths;
|
9109 | }
|
9110 | return BoltCircle;
|
9111 | }());
|
9112 | models.BoltCircle = BoltCircle;
|
9113 | BoltCircle.metaParameters = [
|
9114 | { title: "bolt circle radius", type: "range", min: 1, max: 100, value: 50 },
|
9115 | { title: "hole radius", type: "range", min: 1, max: 50, value: 5 },
|
9116 | { title: "bolt count", type: "range", min: 3, max: 24, value: 12 },
|
9117 | { title: "offset angle", type: "range", min: 0, max: 180, value: 0 }
|
9118 | ];
|
9119 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9120 | })(MakerJs || (MakerJs = {}));
|
9121 | var MakerJs;
|
9122 | (function (MakerJs) {
|
9123 | var models;
|
9124 | (function (models) {
|
9125 | var BoltRectangle = (function () {
|
9126 | function BoltRectangle(width, height, holeRadius) {
|
9127 | this.paths = {};
|
9128 | var points = [[0, 0], [width, 0], [width, height], [0, height]];
|
9129 | var ids = ["BottomLeft_bolt", "BottomRight_bolt", "TopRight_bolt", "TopLeft_bolt"];
|
9130 | this.paths = new models.Holes(holeRadius, points, ids).paths;
|
9131 | }
|
9132 | return BoltRectangle;
|
9133 | }());
|
9134 | models.BoltRectangle = BoltRectangle;
|
9135 | BoltRectangle.metaParameters = [
|
9136 | { title: "width", type: "range", min: 1, max: 100, value: 100 },
|
9137 | { title: "height", type: "range", min: 1, max: 100, value: 50 },
|
9138 | { title: "hole radius", type: "range", min: 1, max: 50, value: 5 }
|
9139 | ];
|
9140 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9141 | })(MakerJs || (MakerJs = {}));
|
9142 | var MakerJs;
|
9143 | (function (MakerJs) {
|
9144 | var models;
|
9145 | (function (models) {
|
9146 | var Dogbone = (function () {
|
9147 | |
9148 |
|
9149 |
|
9150 |
|
9151 |
|
9152 |
|
9153 |
|
9154 |
|
9155 |
|
9156 |
|
9157 |
|
9158 |
|
9159 |
|
9160 |
|
9161 | function Dogbone(width, height, radius, style, bottomless) {
|
9162 | if (style === void 0) { style = 0; }
|
9163 | if (bottomless === void 0) { bottomless = false; }
|
9164 | this.paths = {};
|
9165 | var maxSide = Math.min(height, width) / 2;
|
9166 | var maxRadius;
|
9167 | switch (style) {
|
9168 | case -1:
|
9169 | case 1:
|
9170 | maxRadius = maxSide / 2;
|
9171 | break;
|
9172 | case 0:
|
9173 | default:
|
9174 | maxRadius = maxSide * Math.SQRT2 / 2;
|
9175 | break;
|
9176 | }
|
9177 | radius = Math.min(radius, maxRadius);
|
9178 | var ax;
|
9179 | var ay;
|
9180 | var lx;
|
9181 | var ly;
|
9182 | var apexes;
|
9183 | switch (style) {
|
9184 | case -1:
|
9185 | ax = 0;
|
9186 | ay = radius;
|
9187 | lx = 0;
|
9188 | ly = radius * 2;
|
9189 | apexes = [180, 0, 0, 180];
|
9190 | break;
|
9191 | case 1:
|
9192 | ax = radius;
|
9193 | ay = 0;
|
9194 | lx = radius * 2;
|
9195 | ly = 0;
|
9196 | apexes = [270, 270, 90, 90];
|
9197 | break;
|
9198 | case 0:
|
9199 | default:
|
9200 | ax = ay = radius / Math.SQRT2;
|
9201 | lx = ly = ax * 2;
|
9202 | apexes = [225, 315, 45, 135];
|
9203 | break;
|
9204 | }
|
9205 | if (bottomless) {
|
9206 | this.paths['Left'] = new MakerJs.paths.Line([0, 0], [0, height - ly]);
|
9207 | this.paths['Right'] = new MakerJs.paths.Line([width, 0], [width, height - ly]);
|
9208 | }
|
9209 | else {
|
9210 | this.paths['Left'] = new MakerJs.paths.Line([0, ly], [0, height - ly]);
|
9211 | this.paths['Right'] = new MakerJs.paths.Line([width, ly], [width, height - ly]);
|
9212 | this.paths['Bottom'] = new MakerJs.paths.Line([lx, 0], [width - lx, 0]);
|
9213 | this.paths["BottomLeft"] = new MakerJs.paths.Arc([ax, ay], radius, apexes[0] - 90, apexes[0] + 90);
|
9214 | this.paths["BottomRight"] = new MakerJs.paths.Arc([width - ax, ay], radius, apexes[1] - 90, apexes[1] + 90);
|
9215 | }
|
9216 | this.paths["TopRight"] = new MakerJs.paths.Arc([width - ax, height - ay], radius, apexes[2] - 90, apexes[2] + 90);
|
9217 | this.paths["TopLeft"] = new MakerJs.paths.Arc([ax, height - ay], radius, apexes[3] - 90, apexes[3] + 90);
|
9218 | this.paths['Top'] = new MakerJs.paths.Line([lx, height], [width - lx, height]);
|
9219 | }
|
9220 | return Dogbone;
|
9221 | }());
|
9222 | models.Dogbone = Dogbone;
|
9223 | Dogbone.metaParameters = [
|
9224 | { title: "width", type: "range", min: 1, max: 100, value: 50 },
|
9225 | { title: "height", type: "range", min: 1, max: 100, value: 100 },
|
9226 | { title: "radius", type: "range", min: 0, max: 50, value: 5 },
|
9227 | { title: "style", type: "select", value: [0, 1, -1] },
|
9228 | { title: "bottomless", type: "bool", value: false }
|
9229 | ];
|
9230 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9231 | })(MakerJs || (MakerJs = {}));
|
9232 | var MakerJs;
|
9233 | (function (MakerJs) {
|
9234 | var models;
|
9235 | (function (models) {
|
9236 | var Dome = (function () {
|
9237 | function Dome(width, height, radius, bottomless) {
|
9238 | this.paths = {};
|
9239 | var w2 = width / 2;
|
9240 | if (radius < 0)
|
9241 | radius = 0;
|
9242 | if (radius === void 0)
|
9243 | radius = w2;
|
9244 | radius = Math.min(radius, w2);
|
9245 | radius = Math.min(radius, height);
|
9246 | var wt = Math.max(w2 - radius, 0);
|
9247 | var hr = Math.max(height - radius, 0);
|
9248 | if (!bottomless) {
|
9249 | this.paths["Bottom"] = new MakerJs.paths.Line([-w2, 0], [w2, 0]);
|
9250 | }
|
9251 | if (hr) {
|
9252 | this.paths["Left"] = new MakerJs.paths.Line([-w2, 0], [-w2, hr]);
|
9253 | this.paths["Right"] = new MakerJs.paths.Line([w2, 0], [w2, hr]);
|
9254 | }
|
9255 | if (radius > 0) {
|
9256 | this.paths["TopLeft"] = new MakerJs.paths.Arc([-wt, hr], radius, 90, 180);
|
9257 | this.paths["TopRight"] = new MakerJs.paths.Arc([wt, hr], radius, 0, 90);
|
9258 | }
|
9259 | if (wt) {
|
9260 | this.paths["Top"] = new MakerJs.paths.Line([-wt, height], [wt, height]);
|
9261 | }
|
9262 | }
|
9263 | return Dome;
|
9264 | }());
|
9265 | models.Dome = Dome;
|
9266 | Dome.metaParameters = [
|
9267 | { title: "width", type: "range", min: 1, max: 100, value: 50 },
|
9268 | { title: "height", type: "range", min: 1, max: 100, value: 100 },
|
9269 | { title: "radius", type: "range", min: 0, max: 50, value: 25 },
|
9270 | { title: "bottomless", type: "bool", value: false }
|
9271 | ];
|
9272 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9273 | })(MakerJs || (MakerJs = {}));
|
9274 | var MakerJs;
|
9275 | (function (MakerJs) {
|
9276 | var models;
|
9277 | (function (models) {
|
9278 | var RoundRectangle = (function () {
|
9279 | function RoundRectangle() {
|
9280 | var args = [];
|
9281 | for (var _i = 0; _i < arguments.length; _i++) {
|
9282 | args[_i] = arguments[_i];
|
9283 | }
|
9284 | this.paths = {};
|
9285 | var width;
|
9286 | var height;
|
9287 | var radius = 0;
|
9288 | switch (args.length) {
|
9289 | case 3:
|
9290 | width = args[0];
|
9291 | height = args[1];
|
9292 | radius = args[2];
|
9293 | break;
|
9294 | case 2:
|
9295 | radius = args[1];
|
9296 |
|
9297 | case 1:
|
9298 | var m = MakerJs.measure.modelExtents(args[0]);
|
9299 | this.origin = MakerJs.point.subtract(m.low, [radius, radius]);
|
9300 | width = m.high[0] - m.low[0] + 2 * radius;
|
9301 | height = m.high[1] - m.low[1] + 2 * radius;
|
9302 | break;
|
9303 | }
|
9304 | var maxRadius = Math.min(height, width) / 2;
|
9305 | radius = Math.min(radius, maxRadius);
|
9306 | var wr = width - radius;
|
9307 | var hr = height - radius;
|
9308 | if (radius > 0) {
|
9309 | this.paths["BottomLeft"] = new MakerJs.paths.Arc([radius, radius], radius, 180, 270);
|
9310 | this.paths["BottomRight"] = new MakerJs.paths.Arc([wr, radius], radius, 270, 0);
|
9311 | this.paths["TopRight"] = new MakerJs.paths.Arc([wr, hr], radius, 0, 90);
|
9312 | this.paths["TopLeft"] = new MakerJs.paths.Arc([radius, hr], radius, 90, 180);
|
9313 | }
|
9314 | if (wr - radius > 0) {
|
9315 | this.paths["Bottom"] = new MakerJs.paths.Line([radius, 0], [wr, 0]);
|
9316 | this.paths["Top"] = new MakerJs.paths.Line([wr, height], [radius, height]);
|
9317 | }
|
9318 | if (hr - radius > 0) {
|
9319 | this.paths["Right"] = new MakerJs.paths.Line([width, radius], [width, hr]);
|
9320 | this.paths["Left"] = new MakerJs.paths.Line([0, hr], [0, radius]);
|
9321 | }
|
9322 | }
|
9323 | return RoundRectangle;
|
9324 | }());
|
9325 | models.RoundRectangle = RoundRectangle;
|
9326 | RoundRectangle.metaParameters = [
|
9327 | { title: "width", type: "range", min: 1, max: 100, value: 50 },
|
9328 | { title: "height", type: "range", min: 1, max: 100, value: 100 },
|
9329 | { title: "radius", type: "range", min: 0, max: 50, value: 11 }
|
9330 | ];
|
9331 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9332 | })(MakerJs || (MakerJs = {}));
|
9333 | var MakerJs;
|
9334 | (function (MakerJs) {
|
9335 | var models;
|
9336 | (function (models) {
|
9337 | var Oval = (function () {
|
9338 | function Oval(width, height) {
|
9339 | this.paths = {};
|
9340 | this.paths = new models.RoundRectangle(width, height, Math.min(height / 2, width / 2)).paths;
|
9341 | }
|
9342 | return Oval;
|
9343 | }());
|
9344 | models.Oval = Oval;
|
9345 | Oval.metaParameters = [
|
9346 | { title: "width", type: "range", min: 1, max: 100, value: 50 },
|
9347 | { title: "height", type: "range", min: 1, max: 100, value: 100 }
|
9348 | ];
|
9349 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9350 | })(MakerJs || (MakerJs = {}));
|
9351 | var MakerJs;
|
9352 | (function (MakerJs) {
|
9353 | var models;
|
9354 | (function (models) {
|
9355 | var OvalArc = (function () {
|
9356 | function OvalArc(startAngle, endAngle, sweepRadius, slotRadius, selfIntersect, isolateCaps) {
|
9357 | if (selfIntersect === void 0) { selfIntersect = false; }
|
9358 | if (isolateCaps === void 0) { isolateCaps = false; }
|
9359 | var _this = this;
|
9360 | this.paths = {};
|
9361 | var capRoot;
|
9362 | if (isolateCaps) {
|
9363 | capRoot = { models: {} };
|
9364 | this.models = { 'Caps': capRoot };
|
9365 | }
|
9366 | if (slotRadius <= 0 || sweepRadius <= 0)
|
9367 | return;
|
9368 | startAngle = MakerJs.angle.noRevolutions(startAngle);
|
9369 | endAngle = MakerJs.angle.noRevolutions(endAngle);
|
9370 | if (MakerJs.round(startAngle - endAngle) == 0)
|
9371 | return;
|
9372 | if (endAngle < startAngle)
|
9373 | endAngle += 360;
|
9374 | var addCap = function (id, tiltAngle, offsetStartAngle, offsetEndAngle) {
|
9375 | var capModel;
|
9376 | if (isolateCaps) {
|
9377 | capModel = { paths: {} };
|
9378 | capRoot.models[id] = capModel;
|
9379 | }
|
9380 | else {
|
9381 | capModel = _this;
|
9382 | }
|
9383 | return capModel.paths[id] = new MakerJs.paths.Arc(MakerJs.point.fromPolar(MakerJs.angle.toRadians(tiltAngle), sweepRadius), slotRadius, tiltAngle + offsetStartAngle, tiltAngle + offsetEndAngle);
|
9384 | };
|
9385 | var addSweep = function (id, offsetRadius) {
|
9386 | return _this.paths[id] = new MakerJs.paths.Arc([0, 0], sweepRadius + offsetRadius, startAngle, endAngle);
|
9387 | };
|
9388 | addSweep("Outer", slotRadius);
|
9389 | var hasInner = (sweepRadius - slotRadius) > 0;
|
9390 | if (hasInner) {
|
9391 | addSweep("Inner", -slotRadius);
|
9392 | }
|
9393 | var caps = [];
|
9394 | caps.push(addCap("StartCap", startAngle, 180, 0));
|
9395 | caps.push(addCap("EndCap", endAngle, 0, 180));
|
9396 |
|
9397 | var d = MakerJs.measure.pointDistance(caps[0].origin, caps[1].origin);
|
9398 | if ((d / 2) < slotRadius) {
|
9399 |
|
9400 | var int = MakerJs.path.intersection(caps[0], caps[1]);
|
9401 | if (int) {
|
9402 | if (!hasInner || !selfIntersect) {
|
9403 | caps[0].startAngle = int.path1Angles[0];
|
9404 | caps[1].endAngle = int.path2Angles[0];
|
9405 | }
|
9406 | if (!selfIntersect && hasInner && int.intersectionPoints.length == 2) {
|
9407 | addCap("StartCap2", startAngle, 180, 0).endAngle = int.path1Angles[1];
|
9408 | addCap("EndCap2", endAngle, 0, 180).startAngle = int.path2Angles[1] + 360;
|
9409 | }
|
9410 | }
|
9411 | }
|
9412 | }
|
9413 | return OvalArc;
|
9414 | }());
|
9415 | models.OvalArc = OvalArc;
|
9416 | OvalArc.metaParameters = [
|
9417 | { title: "start angle", type: "range", min: -360, max: 360, step: 1, value: 180 },
|
9418 | { title: "end angle", type: "range", min: -360, max: 360, step: 1, value: 0 },
|
9419 | { title: "sweep", type: "range", min: 0, max: 100, step: 1, value: 50 },
|
9420 | { title: "radius", type: "range", min: 0, max: 100, step: 1, value: 15 },
|
9421 | { title: "self intersect", type: "bool", value: false }
|
9422 | ];
|
9423 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9424 | })(MakerJs || (MakerJs = {}));
|
9425 | var MakerJs;
|
9426 | (function (MakerJs) {
|
9427 | var models;
|
9428 | (function (models) {
|
9429 | var Rectangle = (function () {
|
9430 | function Rectangle() {
|
9431 | var args = [];
|
9432 | for (var _i = 0; _i < arguments.length; _i++) {
|
9433 | args[_i] = arguments[_i];
|
9434 | }
|
9435 | this.paths = {};
|
9436 | var width;
|
9437 | var height;
|
9438 | if (args.length === 2 && !MakerJs.isObject(args[0])) {
|
9439 | width = args[0];
|
9440 | height = args[1];
|
9441 | }
|
9442 | else {
|
9443 | var margin = 0;
|
9444 | var m;
|
9445 | if (MakerJs.isModel(args[0])) {
|
9446 | m = MakerJs.measure.modelExtents(args[0]);
|
9447 | if (args.length === 2) {
|
9448 | margin = args[1];
|
9449 | }
|
9450 | }
|
9451 | else {
|
9452 |
|
9453 | m = args[0];
|
9454 | }
|
9455 | this.origin = MakerJs.point.subtract(m.low, [margin, margin]);
|
9456 | width = m.high[0] - m.low[0] + 2 * margin;
|
9457 | height = m.high[1] - m.low[1] + 2 * margin;
|
9458 | }
|
9459 | this.paths = new models.ConnectTheDots(true, [[0, 0], [width, 0], [width, height], [0, height]]).paths;
|
9460 | }
|
9461 | return Rectangle;
|
9462 | }());
|
9463 | models.Rectangle = Rectangle;
|
9464 | Rectangle.metaParameters = [
|
9465 | { title: "width", type: "range", min: 1, max: 100, value: 50 },
|
9466 | { title: "height", type: "range", min: 1, max: 100, value: 100 }
|
9467 | ];
|
9468 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9469 | })(MakerJs || (MakerJs = {}));
|
9470 | var MakerJs;
|
9471 | (function (MakerJs) {
|
9472 | var models;
|
9473 | (function (models) {
|
9474 | var Ring = (function () {
|
9475 | function Ring(outerRadius, innerRadius) {
|
9476 | this.paths = {};
|
9477 | var radii = {
|
9478 | "Ring_outer": outerRadius,
|
9479 | "Ring_inner": innerRadius
|
9480 | };
|
9481 | for (var id in radii) {
|
9482 | if (radii[id] === void 0)
|
9483 | continue;
|
9484 | this.paths[id] = new MakerJs.paths.Circle(MakerJs.point.zero(), radii[id]);
|
9485 | }
|
9486 | }
|
9487 | return Ring;
|
9488 | }());
|
9489 | models.Ring = Ring;
|
9490 | Ring.metaParameters = [
|
9491 | { title: "outer radius", type: "range", min: 0, max: 100, step: 1, value: 50 },
|
9492 | { title: "inner radius", type: "range", min: 0, max: 100, step: 1, value: 20 }
|
9493 | ];
|
9494 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9495 | })(MakerJs || (MakerJs = {}));
|
9496 | var MakerJs;
|
9497 | (function (MakerJs) {
|
9498 | var models;
|
9499 | (function (models) {
|
9500 | var Belt = (function () {
|
9501 | function Belt(leftRadius, distance, rightRadius) {
|
9502 | this.paths = {};
|
9503 | var left = new MakerJs.paths.Arc([0, 0], leftRadius, 0, 360);
|
9504 | var right = new MakerJs.paths.Arc([distance, 0], rightRadius, 0, 360);
|
9505 | var angles = MakerJs.solvers.circleTangentAngles(left, right);
|
9506 | if (!angles) {
|
9507 | this.paths["Belt"] = new MakerJs.paths.Circle(Math.max(leftRadius, rightRadius));
|
9508 | }
|
9509 | else {
|
9510 | angles = angles.sort(function (a, b) { return a - b; });
|
9511 | left.startAngle = angles[0];
|
9512 | left.endAngle = angles[1];
|
9513 | right.startAngle = angles[1];
|
9514 | right.endAngle = angles[0];
|
9515 | this.paths["Left"] = left;
|
9516 | this.paths["Right"] = right;
|
9517 | this.paths["Top"] = new MakerJs.paths.Line(MakerJs.point.fromAngleOnCircle(angles[0], left), MakerJs.point.fromAngleOnCircle(angles[0], right));
|
9518 | this.paths["Bottom"] = new MakerJs.paths.Line(MakerJs.point.fromAngleOnCircle(angles[1], left), MakerJs.point.fromAngleOnCircle(angles[1], right));
|
9519 | }
|
9520 | }
|
9521 | return Belt;
|
9522 | }());
|
9523 | models.Belt = Belt;
|
9524 | Belt.metaParameters = [
|
9525 | { title: "left radius", type: "range", min: 0, max: 100, value: 30 },
|
9526 | { title: "distance between centers", type: "range", min: 0, max: 100, value: 50 },
|
9527 | { title: "right radius", type: "range", min: 0, max: 100, value: 15 }
|
9528 | ];
|
9529 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9530 | })(MakerJs || (MakerJs = {}));
|
9531 | var MakerJs;
|
9532 | (function (MakerJs) {
|
9533 | var models;
|
9534 | (function (models) {
|
9535 | var SCurve = (function () {
|
9536 | function SCurve(width, height) {
|
9537 | this.paths = {};
|
9538 | function findRadius(x, y) {
|
9539 | return x + (y * y - x * x) / (2 * x);
|
9540 | }
|
9541 | var h2 = height / 2;
|
9542 | var w2 = width / 2;
|
9543 | var radius;
|
9544 | var startAngle;
|
9545 | var endAngle;
|
9546 | var arcOrigin;
|
9547 | if (width > height) {
|
9548 | radius = findRadius(h2, w2);
|
9549 | startAngle = 270;
|
9550 | endAngle = 360 - MakerJs.angle.toDegrees(Math.acos(w2 / radius));
|
9551 | arcOrigin = [0, radius];
|
9552 | }
|
9553 | else {
|
9554 | radius = findRadius(w2, h2);
|
9555 | startAngle = 180 - MakerJs.angle.toDegrees(Math.asin(h2 / radius));
|
9556 | endAngle = 180;
|
9557 | arcOrigin = [radius, 0];
|
9558 | }
|
9559 | var curve = new MakerJs.paths.Arc(arcOrigin, radius, startAngle, endAngle);
|
9560 | this.paths['curve_start'] = curve;
|
9561 | this.paths['curve_end'] = MakerJs.path.moveRelative(MakerJs.path.mirror(curve, true, true), [width, height]);
|
9562 | }
|
9563 | return SCurve;
|
9564 | }());
|
9565 | models.SCurve = SCurve;
|
9566 | SCurve.metaParameters = [
|
9567 | { title: "width", type: "range", min: 1, max: 100, value: 50 },
|
9568 | { title: "height", type: "range", min: 1, max: 100, value: 100 }
|
9569 | ];
|
9570 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9571 | })(MakerJs || (MakerJs = {}));
|
9572 | var MakerJs;
|
9573 | (function (MakerJs) {
|
9574 | var models;
|
9575 | (function (models) {
|
9576 | var Slot = (function () {
|
9577 | function Slot(origin, endPoint, radius, isolateCaps) {
|
9578 | if (isolateCaps === void 0) { isolateCaps = false; }
|
9579 | var _this = this;
|
9580 | this.paths = {};
|
9581 | var capRoot;
|
9582 | if (isolateCaps) {
|
9583 | capRoot = { models: {} };
|
9584 | this.models = { 'Caps': capRoot };
|
9585 | }
|
9586 | var addCap = function (id, capPath) {
|
9587 | var capModel;
|
9588 | if (isolateCaps) {
|
9589 | capModel = { paths: {} };
|
9590 | capRoot.models[id] = capModel;
|
9591 | }
|
9592 | else {
|
9593 | capModel = _this;
|
9594 | }
|
9595 | capModel.paths[id] = capPath;
|
9596 | };
|
9597 | var a = MakerJs.angle.ofPointInDegrees(origin, endPoint);
|
9598 | var len = MakerJs.measure.pointDistance(origin, endPoint);
|
9599 | this.paths['Top'] = new MakerJs.paths.Line([0, radius], [len, radius]);
|
9600 | this.paths['Bottom'] = new MakerJs.paths.Line([0, -radius], [len, -radius]);
|
9601 | addCap('StartCap', new MakerJs.paths.Arc([0, 0], radius, 90, 270));
|
9602 | addCap('EndCap', new MakerJs.paths.Arc([len, 0], radius, 270, 90));
|
9603 | MakerJs.model.rotate(this, a, [0, 0]);
|
9604 | this.origin = origin;
|
9605 | }
|
9606 | return Slot;
|
9607 | }());
|
9608 | models.Slot = Slot;
|
9609 | Slot.metaParameters = [
|
9610 | {
|
9611 | title: "origin", type: "select", value: [
|
9612 | [0, 0],
|
9613 | [10, 0],
|
9614 | [10, 10]
|
9615 | ]
|
9616 | },
|
9617 | {
|
9618 | title: "end", type: "select", value: [
|
9619 | [80, 0],
|
9620 | [0, 30],
|
9621 | [10, 30]
|
9622 | ]
|
9623 | },
|
9624 | { title: "radius", type: "range", min: 1, max: 50, value: 10 }
|
9625 | ];
|
9626 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9627 | })(MakerJs || (MakerJs = {}));
|
9628 | var MakerJs;
|
9629 | (function (MakerJs) {
|
9630 | var models;
|
9631 | (function (models) {
|
9632 | var Square = (function () {
|
9633 | function Square(side) {
|
9634 | this.paths = {};
|
9635 | this.paths = new models.Rectangle(side, side).paths;
|
9636 | }
|
9637 | return Square;
|
9638 | }());
|
9639 | models.Square = Square;
|
9640 | Square.metaParameters = [
|
9641 | { title: "side", type: "range", min: 1, max: 100, value: 100 }
|
9642 | ];
|
9643 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9644 | })(MakerJs || (MakerJs = {}));
|
9645 | var MakerJs;
|
9646 | (function (MakerJs) {
|
9647 | var models;
|
9648 | (function (models) {
|
9649 | var Star = (function () {
|
9650 | function Star(numberOfPoints, outerRadius, innerRadius, skipPoints) {
|
9651 | if (skipPoints === void 0) { skipPoints = 2; }
|
9652 | this.paths = {};
|
9653 | if (!innerRadius) {
|
9654 | innerRadius = outerRadius * Star.InnerRadiusRatio(numberOfPoints, skipPoints);
|
9655 | }
|
9656 | var outerPoints = models.Polygon.getPoints(numberOfPoints, outerRadius);
|
9657 | var innerPoints = models.Polygon.getPoints(numberOfPoints, innerRadius, 180 / numberOfPoints);
|
9658 | var allPoints = [];
|
9659 | for (var i = 0; i < numberOfPoints; i++) {
|
9660 | allPoints.push(outerPoints[i]);
|
9661 | allPoints.push(innerPoints[i]);
|
9662 | }
|
9663 | var model = new models.ConnectTheDots(true, allPoints);
|
9664 | this.paths = model.paths;
|
9665 | delete model.paths;
|
9666 | }
|
9667 | Star.InnerRadiusRatio = function (numberOfPoints, skipPoints) {
|
9668 |
|
9669 |
|
9670 | if (numberOfPoints > 0 && skipPoints > 1 && skipPoints < numberOfPoints / 2) {
|
9671 | return Math.cos(Math.PI * skipPoints / numberOfPoints) / Math.cos(Math.PI * (skipPoints - 1) / numberOfPoints);
|
9672 | }
|
9673 | return 0;
|
9674 | };
|
9675 | return Star;
|
9676 | }());
|
9677 | models.Star = Star;
|
9678 | Star.metaParameters = [
|
9679 | { title: "number of sides", type: "range", min: 3, max: 24, value: 8 },
|
9680 | { title: "outer radius", type: "range", min: 1, max: 100, value: 50 },
|
9681 | { title: "inner radius", type: "range", min: 0, max: 100, value: 15 },
|
9682 | { title: "skip points (when inner radius is zero)", type: "range", min: 0, max: 12, value: 2 }
|
9683 | ];
|
9684 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9685 | })(MakerJs || (MakerJs = {}));
|
9686 | var MakerJs;
|
9687 | (function (MakerJs) {
|
9688 | var models;
|
9689 | (function (models) {
|
9690 | var Text = (function () {
|
9691 | |
9692 |
|
9693 |
|
9694 |
|
9695 |
|
9696 |
|
9697 |
|
9698 |
|
9699 |
|
9700 |
|
9701 |
|
9702 | function Text(font, text, fontSize, combine, centerCharacterOrigin, bezierAccuracy, opentypeOptions) {
|
9703 | if (combine === void 0) { combine = false; }
|
9704 | if (centerCharacterOrigin === void 0) { centerCharacterOrigin = false; }
|
9705 | var _this = this;
|
9706 | this.models = {};
|
9707 | var charIndex = 0;
|
9708 | var prevDeleted;
|
9709 | var prevChar;
|
9710 | var cb = function (glyph, x, y, _fontSize, options) {
|
9711 | var charModel = Text.glyphToModel(glyph, _fontSize, bezierAccuracy);
|
9712 | charModel.origin = [x, 0];
|
9713 | if (centerCharacterOrigin && (charModel.paths || charModel.models)) {
|
9714 | var m = MakerJs.measure.modelExtents(charModel);
|
9715 | if (m) {
|
9716 | var w = m.high[0] - m.low[0];
|
9717 | MakerJs.model.originate(charModel, [m.low[0] + w / 2, 0]);
|
9718 | }
|
9719 | }
|
9720 | if (combine && charIndex > 0) {
|
9721 | var combineOptions = {};
|
9722 | var prev;
|
9723 | if (prevDeleted) {
|
9724 |
|
9725 | prev = {
|
9726 | models: {
|
9727 | deleted: prevDeleted,
|
9728 | char: prevChar
|
9729 | }
|
9730 | };
|
9731 | }
|
9732 | else {
|
9733 | prev = prevChar;
|
9734 | }
|
9735 | MakerJs.model.combine(prev, charModel, false, true, false, true, combineOptions);
|
9736 |
|
9737 | prevDeleted = combineOptions.out_deleted[1];
|
9738 | }
|
9739 | _this.models[charIndex] = charModel;
|
9740 | charIndex++;
|
9741 | prevChar = charModel;
|
9742 | };
|
9743 | font.forEachGlyph(text, 0, 0, fontSize, opentypeOptions, cb);
|
9744 | }
|
9745 | |
9746 |
|
9747 |
|
9748 |
|
9749 |
|
9750 |
|
9751 |
|
9752 | Text.glyphToModel = function (glyph, fontSize, bezierAccuracy) {
|
9753 | var charModel = {};
|
9754 | var firstPoint;
|
9755 | var currPoint;
|
9756 | var pathCount = 0;
|
9757 | function addPath(p) {
|
9758 | if (!charModel.paths) {
|
9759 | charModel.paths = {};
|
9760 | }
|
9761 | charModel.paths['p_' + ++pathCount] = p;
|
9762 | }
|
9763 | function addModel(m) {
|
9764 | if (!charModel.models) {
|
9765 | charModel.models = {};
|
9766 | }
|
9767 | charModel.models['p_' + ++pathCount] = m;
|
9768 | }
|
9769 | var p = glyph.getPath(0, 0, fontSize);
|
9770 | p.commands.map(function (command, i) {
|
9771 | var points = [[command.x, command.y], [command.x1, command.y1], [command.x2, command.y2]].map(function (p) {
|
9772 | if (p[0] !== void 0) {
|
9773 | return MakerJs.point.mirror(p, false, true);
|
9774 | }
|
9775 | });
|
9776 | switch (command.type) {
|
9777 | case 'M':
|
9778 | firstPoint = points[0];
|
9779 | break;
|
9780 | case 'Z':
|
9781 | points[0] = firstPoint;
|
9782 |
|
9783 | case 'L':
|
9784 | if (!MakerJs.measure.isPointEqual(currPoint, points[0])) {
|
9785 | addPath(new MakerJs.paths.Line(currPoint, points[0]));
|
9786 | }
|
9787 | break;
|
9788 | case 'C':
|
9789 | addModel(new models.BezierCurve(currPoint, points[1], points[2], points[0], bezierAccuracy));
|
9790 | break;
|
9791 | case 'Q':
|
9792 | addModel(new models.BezierCurve(currPoint, points[1], points[0], bezierAccuracy));
|
9793 | break;
|
9794 | }
|
9795 | currPoint = points[0];
|
9796 | });
|
9797 | return charModel;
|
9798 | };
|
9799 | return Text;
|
9800 | }());
|
9801 | models.Text = Text;
|
9802 | Text.metaParameters = [
|
9803 | { title: "font", type: "font", value: '*' },
|
9804 | { title: "text", type: "text", value: 'Hello' },
|
9805 | { title: "font size", type: "range", min: 10, max: 200, value: 72 },
|
9806 | { title: "combine", type: "bool", value: false },
|
9807 | { title: "center character origin", type: "bool", value: false }
|
9808 | ];
|
9809 | })(models = MakerJs.models || (MakerJs.models = {}));
|
9810 | })(MakerJs || (MakerJs = {}));
|
9811 | MakerJs.version = "0.14.0";
|
9812 | var Bezier = require('bezier-js');
|