将带孔的SVG路径转换为three.js中的挤出形状

Converting SVG paths with holes to extruded shapes in three.js

我有一个由4个多边形组成的形状:2个非孔和2个孔。这只是一个例子。实际上,可以有一个由50个多边形组成的形状,其中20个是非孔,30个是孔。在SVG路径中,这种类似的多边形可以通过moveto:s和lineto:s组合来轻松表示。路径字符串中的每个子多边形(孔或非孔)都以moveto命令开始,以z(结束)命令结束,而非孔具有连续缠绕顺序和孔ccw。非常简单直观。

SVG中的形状以这种方式表示(http://jsbin.com/osoxev/1/edit):

1
2
3
4
5
6
7
<path d="M305.08,241.97 L306,251.51 L308.18,256.39 L311.72,259.09 L317.31,260.01 L324.71,259.01 L332.45,255.86 L335.57,257.53 L337.6,260.44 L336.94,262.33 L328.27,268.74 L317.89,273.41 L307.94,275.49 L296.26,275.23 L286.64,272.99 L279.78,269.31 L274.14,263.55 L271.65,260.21 L269.2,261.06 L254.83,268.51 L242.11,272.97 L227.59,275.23 L209.91,275.48 L197.47,273.63 L187.91,270.13 L180.48,265.09 L175.32,258.88 L172.2,251.44 L171.1,242.23 L172.24,233.63 L175.49,226.24 L181,219.54 L189.42,213.3 L201.36,207.73 L217.23,203.25 L238.28,200.1 L265.24,198.78 L269.37,198.47 L269.98,182.93 L268.74,171.32 L266.05,163.7 L261.58,157.72 L255.24,153.24 L247.06,150.32 L235.44,149.13 L224.71,150.05 L215.91,153 L210.23,156.86 L207.64,160.85 L207.19,165.28 L209.34,169.86 L212.01,174.15 L212.14,177.99 L209.8,181.78 L204.22,185.79 L197.62,187.68 L188.65,187.43 L182.41,185.39 L178.45,181.77 L176.2,176.9 L176.03,170.64 L178.2,164.13 L183.09,157.69 L191.04,151.36 L202.01,145.82 L216.09,141.57 L232.08,139.24 L250.07,139.18 L266.13,141.23 L279.05,145.06 L289.15,150.3 L295.91,156.19 L300.73,163.41 L303.85,172.47 L305.07,183.78 L305.07,241.97 L305.08,241.97Z

M243.99,64.95 L255.92,66.06 L266.21,69.28 L274.98,74.44 L280.64,80.19 L284.02,86.85 L285.26,94.52 L284.27,102.84 L281.24,109.66 L276.03,115.43 L267.89,120.46 L257.68,123.93 L245.79,125.33 L232.93,124.53 L222.21,121.74 L213.14,117.11 L207.36,111.92 L203.7,105.75 L201.94,98.18 L202.34,90.12 L204.86,83.4 L210.01,76.81 L217.49,71.33 L227.17,67.31 L238.35,65.2 L243.75,64.95 L243.99,64.95Z

M269.99,212.88 L269.48,208.76 L266.59,208.36 L245.76,210.86 L230.95,214.67 L220.9,219.34 L213.82,224.85 L209.69,230.71 L207.92,237.03 L208.4,244.49 L210.86,250.57 L215.2,255.08 L221.69,258.13 L230.57,259.43 L242.52,258.58 L255.27,255.23 L266.07,250.04 L269.34,247.02 L269.99,244.81 L269.99,212.88 L269.99,212.88Z

M243.63,73.34 L235.93,74.4 L230.07,77.36 L225.65,82.21 L223.05,88.57 L222.41,96.92 L223.94,104.53 L227.23,110.22 L231.99,114.29 L238.44,116.65 L246.81,116.94 L253.73,115.1 L258.87,111.5 L262.63,106.12 L264.64,98.93 L264.59,90.25 L262.47,83.41 L258.65,78.43 L253.37,75.08 L246.08,73.43 L243.68,73.34 L243.63,73.34Z"/>

当我尝试在three.js中遵循相同的逻辑时,我遇到了问题。下面是这张图片:

enter image description here

3.js似乎不明白moveto的意思。它应该在上一个点和moveto命令点之间绘制"pen up"和"nothing"。但是"笔不上",形状就断了。

代码部分如下(不要混淆变量名,它们来自其他示例):

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
// Create glyph shape (sorry the confusing name):
var starPoints2 = new THREE.Shape();

// Add first polygon
starPoints2.moveTo(307.94,275.49);
starPoints2.lineTo(296.26,275.23);
// .....
starPoints2.lineTo(286.64,272.99);
starPoints2.lineTo(307.94,275.49);

// Add second polygon
starPoints2.moveTo(245.79,125.33);
starPoints2.lineTo(232.93,124.53);
// .....
starPoints2.lineTo(257.68,123.93);
starPoints2.lineTo(245.79,125.33);

// Create path for holes
var smileyEye1Path = new THREE.Path();

// First hole
smileyEye1Path.moveTo(221.69,258.13);
smileyEye1Path.lineTo(215.2,255.08);
// .....
smileyEye1Path.lineTo(230.57,259.43);
smileyEye1Path.lineTo(221.69,258.13);

// Second hole
smileyEye1Path.moveTo(238.44,116.65);
smileyEye1Path.lineTo(231.99,114.29);
// .....
smileyEye1Path.lineTo(246.81,116.94);
smileyEye1Path.lineTo(238.44,116.65);

// Add holes to shape
var starShape = starPoints2;
starShape.holes.push( smileyEye1Path );

// Extrude after that. See the full code here:
// http://jsfiddle.net/pHn2B/33/

function(){}http://jsfiddle.net/phn2b/33/

我在代码中做错了什么,或者在three.js中有bug吗?


形状定义中间不能有moveTo。你必须有两个不同的形状。你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var object = new THREE.Object3D();

var shape1 = new THREE.Shape();
var shape2 = new THREE.Shape();

var hole1 = new THREE.Path();
var hole2 = new THREE.Path();

shape1.holes.push( hole1 );
shape2.holes.push( hole2 );

. . .

object.add( mesh1 );
object.add( mesh2 );

scene.add( object );

小提琴:http://jsfiddle.net/phn2b/34/

J.R.58

P.S.友好提示:将来,最好让人们更容易帮助您——编辑变量名并从示例中删除不相关的代码。