-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
124 lines (106 loc) · 2.94 KB
/
index.js
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
var parseSVG = require('parse-svg-path')
var getContours = require('svg-path-contours')
var cdt2d = require('cdt2d')
var cleanPSLG = require('clean-pslg')
var getBounds = require('bound-points')
var normalize = require('normalize-path-scale')
var random = require('random-float')
var assign = require('object-assign')
var simplify = require('simplify-path')
module.exports = svgMesh3d
function svgMesh3d (svgPath, opt) {
if (typeof svgPath !== 'string') {
throw new TypeError('must provide a string as first parameter')
}
opt = assign({
delaunay: true,
clean: true,
exterior: false,
randomization: 0,
simplify: 0,
scale: 1
}, opt)
var i
// parse string as a list of operations
var svg = parseSVG(svgPath)
// convert curves into discrete points
var contours = getContours(svg, opt.scale)
// optionally simplify the path for faster triangulation and/or aesthetics
if (opt.simplify > 0 && typeof opt.simplify === 'number') {
for (i = 0; i < contours.length; i++) {
contours[i] = simplify(contours[i], opt.simplify)
}
}
// prepare for triangulation
var polyline = denestPolyline(contours)
var positions = polyline.positions
var bounds = getBounds(positions)
// optionally add random points for aesthetics
var randomization = opt.randomization
if (typeof randomization === 'number' && randomization > 0) {
addRandomPoints(positions, bounds, randomization)
}
var loops = polyline.edges
var edges = []
for (i = 0; i < loops.length; ++i) {
var loop = loops[i]
for (var j = 0; j < loop.length; ++j) {
edges.push([loop[j], loop[(j + 1) % loop.length]])
}
}
// this updates points/edges so that they now form a valid PSLG
if (opt.clean !== false) {
cleanPSLG(positions, edges)
}
// triangulate mesh
var cells = cdt2d(positions, edges, opt)
// rescale to [-1 ... 1]
if (opt.normalize !== false) {
normalize(positions, bounds)
}
// convert to 3D representation and flip on Y axis for convenience w/ OpenGL
to3D(positions)
return {
positions: positions,
cells: cells
}
}
function to3D (positions) {
for (var i = 0; i < positions.length; i++) {
var xy = positions[i]
xy[1] *= -1
xy[2] = xy[2] || 0
}
}
function addRandomPoints (positions, bounds, count) {
var min = bounds[0]
var max = bounds[1]
for (var i = 0; i < count; i++) {
positions.push([ // random [ x, y ]
random(min[0], max[0]),
random(min[1], max[1])
])
}
}
function denestPolyline (nested) {
var positions = []
var edges = []
for (var i = 0; i < nested.length; i++) {
var path = nested[i]
var loop = []
for (var j = 0; j < path.length; j++) {
var pos = path[j]
var idx = positions.indexOf(pos)
if (idx === -1) {
positions.push(pos)
idx = positions.length - 1
}
loop.push(idx)
}
edges.push(loop)
}
return {
positions: positions,
edges: edges
}
}