拉伸具有多个孔的多个多边形并纹理化组合的形状 [英] Extruding multiple polygons with multiple holes and texturing the combined shape

查看:84
本文介绍了拉伸具有多个孔的多个多边形并纹理化组合的形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题与此问题有关. answer 显示了一种很好的方法来拉伸具有孔的多边形(请参见

This question is related to this question. The answer shows very nice way to extrude polygons that have holes (see the excellent live example). The main learning of the answer was that paths in three.js (r58) cannot have more than one moveTo command and it have to be in the start of the path, which means that path have to be broken by moveTos, so that moveTo start always a new path.

在three.js中挤出表示使用可能的倒角将2D路径转换为3D形状.它适合于挤压文本以制作3D字母和单词,但也可以用来挤压自定义路径.

Extruding in three.js means that 2D paths are converted to 3D shapes using possible beveling. It is suitable for extruding texts to make 3D letters and words, but can be used also to extrude custom paths.

现在出现两个问题:

  • 如何处理具有多个孔多边形和多个非孔多边形的多边形?
  • 如何在整个生成的形状中添加纹理?

我在 http://jsbin.com/oqomuj/1/中将其作为SVG的示例编辑:

使用以下路径生成图像:

The image is produced using this path:


<path d="
 M57.11,271.77 L57.11,218.33 L41.99,218.63 L105.49,165.77 L138.41,193.18 L138.41,172.2 L152.53,172.2 L152.53,204.93 L168.99,218.63 L153.21,218.63 L153.21,271.77Z
 M74.14,264.13 L105.49,264.13 L105.49,232.8 L74.14,232.8Z
 M115.35,250.7 L135.96,250.7 L135.96,232.61 L115.35,232.61Z
 M56.11,145.77 L56.11,92.33 L40.99,92.63 L104.49,39.77 L137.41,67.18 L137.41,46.2 L151.53,46.2 L151.53,78.93 L152.53,79.76 L155.55,77.23 L159.5,74.52 L168.65,69.81 L176.46,66.93 L188.04,64.16 L200.63,62.7 L213.65,62.7 L226.05,64.09 L234.83,66.06 L245.65,69.73 L252.87,73.27 L259.12,77.34 L262.63,80.33 L265.6,83.47 L268.01,86.76 L269.83,90.17 L271.08,93.68 L271.76,99.08 L271.04,104.64 L269.75,108.2 L267.87,111.63 L265.42,114.91 L262.44,118.01 L258.95,120.92 L255.02,123.63 L245.86,128.34 L238.06,131.22 L226.48,133.99 L213.88,135.44 L200.63,135.44 L188.04,133.99 L176.46,131.22 L168.65,128.34 L159.5,123.63 L155.55,120.92 L152.21,118.12 L152.21,145.77Z
 M73.14,138.13 L104.49,138.13 L104.49,106.8 L73.14,106.8Z
 M114.35,124.7 L134.96,124.7 L134.96,106.61 L114.35,106.61Z
 M207.26,117.33 L210.57,117.26 L216.87,116.53 L222.66,115.15 L227.8,113.18 L233.11,110 L236.34,106.99 L238.51,103.64 L239.42,100.48 L239.42,97.67 L238.51,94.51 L236.34,91.16 L233.11,88.15 L227.8,84.97 L222.66,83 L216.87,81.62 L210.57,80.89 L203.94,80.89 L197.65,81.62 L191.86,83 L186.71,84.97 L181.41,88.15 L178.18,91.16 L176.01,94.51 L175.1,97.67 L175.1,100.48 L176.01,103.64 L178.18,106.99 L181.41,110 L186.71,113.18 L191.86,115.15 L197.65,116.53 L203.94,117.26Z
"></path>

并将此路径转换为各个顶点数组:

and this path converted to individual arrays of vertices:


var lower_house_material = [{x:57.11,y:271.77},{x:57.11,y:218.33},{x:41.99,y:218.63},{x:105.49,y:165.77},{x:138.42,y:193.18},{x:138.42,y:172.2},{x:152.53,y:172.2},{x:152.53,y:204.93},{x:168.99,y:218.63},{x:153.21,y:218.63},{x:153.21,y:271.77}];
var lower_house_hole_1 = [{x:74.14,y:264.13},{x:105.49,y:264.13},{x:105.49,y:232.8},{x:74.14,y:232.8}];
var lower_house_hole_2 = [{x:115.35,y:250.7},{x:135.96,y:250.7},{x:135.96,y:232.61},{x:115.35,y:232.61}];

var upper_house_material = [{x:56.11,y:145.77},{x:56.11,y:92.33},{x:40.99,y:92.63},{x:104.49,y:39.77},{x:137.42,y:67.18},{x:137.42,y:46.2},{x:151.53,y:46.2},{x:151.53,y:78.93},{x:152.53,y:79.76},{x:155.55,y:77.23},{x:159.5,y:74.52},{x:168.65,y:69.81},{x:176.46,y:66.93},{x:188.04,y:64.16},{x:200.63,y:62.7},{x:213.65,y:62.7},{x:226.05,y:64.1},{x:234.83,y:66.06},{x:245.65,y:69.73},{x:252.87,y:73.27},{x:259.12,y:77.35},{x:262.63,y:80.33},{x:265.6,y:83.47},{x:268.01,y:86.76},{x:269.84,y:90.17},{x:271.08,y:93.68},{x:271.76,y:99.08},{x:271.04,y:104.64},{x:269.75,y:108.2},{x:267.87,y:111.63},{x:265.42,y:114.91},{x:262.44,y:118.01},{x:258.96,y:120.92},{x:255.02,y:123.63},{x:245.86,y:128.34},{x:238.06,y:131.22},{x:226.48,y:133.99},{x:213.88,y:135.45},{x:200.63,y:135.45},{x:188.04,y:133.99},{x:176.46,y:131.22},{x:168.65,y:128.34},{x:159.5,y:123.63},{x:155.55,y:120.92},{x:152.21,y:118.12},{x:152.21,y:145.77}];
var upper_house_hole_1 = [{x:73.14,y:138.13},{x:104.49,y:138.13},{x:104.49,y:106.8},{x:73.14,y:106.8}];
var upper_house_hole_2 = [{x:114.35,y:124.7},{x:134.96,y:124.7},{x:134.96,y:106.61},{x:114.35,y:106.61}];
var upper_house_hole_3 = [{x:207.26,y:117.33},{x:210.57,y:117.26},{x:216.87,y:116.53},{x:222.66,y:115.15},{x:227.8,y:113.18},{x:233.11,y:110},{x:236.34,y:106.99},{x:238.51,y:103.64},{x:239.42,y:100.48},{x:239.42,y:97.67},{x:238.51,y:94.51},{x:236.34,y:91.16},{x:233.11,y:88.15},{x:227.8,y:84.97},{x:222.66,y:83},{x:216.87,y:81.62},{x:210.57,y:80.89},{x:203.94,y:80.89},{x:197.65,y:81.62},{x:191.86,y:83},{x:186.71,y:84.97},{x:181.41,y:88.15},{x:178.18,y:91.16},{x:176.01,y:94.51},{x:175.1,y:97.67},{x:175.1,y:100.48},{x:176.01,y:103.64},{x:178.18,y:106.99},{x:181.41,y:110},{x:186.71,y:113.18},{x:191.86,y:115.15},{x:197.65,y:116.53},{x:203.94,y:117.26}];

问题是,如何将这种结构转换为three.js中的3D对象,以便可以使用THREE.ExtrudeGeometry( shape, extrusionSettings )对其进行拉伸,然后将其整体纹理化?

The question is, how this like structure can be converted to 3D object in three.js so that it can be extruded using THREE.ExtrudeGeometry( shape, extrusionSettings ) and after that textured as a whole?

我可以检查路径数据以了解哪个孔属于哪个多边形并将其全部处理为单独的形状,但是由于我想在所有形状上使用一个纹理图像,所以我认为首选方式是将所有材料多边形作为一种形状处理,将孔多边形作为另一种形状处理,并使用以下方法:

I can examine the path data to know what hole belongs to what polygon and handle all as separate shapes, but because I want to use one texture image across all the shapes, I think the preferred way is to handle all material-polygons as one shape, and hole-polygons as other shape and use something like:


var shape = [lower_house_material, upper_house_material];
shape.holes = [lower_house_hole_1, lower_house_hole_2, upper_house_hole_1, upper_house_hole_2, upper_house_hole_3];
var 3d_geometry = THREE.ExtrudeGeometry( shape, extrusionSettings );

因此,3d_geometry应该位于一个网格的末尾,我可以通过这种方式向其附加纹理:

So the 3d_geometry should be at the end one mesh to which I can append a texture this way:


var textureFront = new THREE.ImageUtils.loadTexture( 'textureFront.png');
var textureSide = new THREE.ImageUtils.loadTexture( 'textureSide.png');
var materialFront = new THREE.MeshBasicMaterial( { map: textureFront } );
var materialSide = new THREE.MeshBasicMaterial( { map: textureSide } );
var materialArray = [ materialFront, materialSide ];
var faceMaterial = new THREE.MeshFaceMaterial(materialArray);
var final_mesh = new THREE.Mesh(3d_geometry, faceMaterial );

其中一种纹理可能是这样的(256x256px):

And one of the textures could be something like this (256x256px):

并应用纹理:

由于网格是挤压的,因​​此上面也有3D厚度,但是您有了纹理的想法.

And because the mesh is extruded, there is also 3D thickness on the above, but you got the idea of texturing.

我知道y坐标必须翻转,但这是一项微不足道的任务,而不是我的问题的重点,但是如果three.js具有现成的用于裁剪y的功能,那将是有帮助的.

I know that y-coordinates have to be flipped but it is a trivial task and not the point of my question, but if three.js has ready-made function for clipping y, it would be helpful.

我已经花费了数小时来研究three.js源代码,示例和文档,但是因为最常出现的单词是"todo",所以它没有太大帮助.而且我是three.js的新手,我认为对于某些有经验的Three.js用户而言,这可能是微不足道的任务.

I have spent hours to examine the three.js source code, examples and documentation, but because the most frequent word there is "todo", it cannot help much. And I'm very newbie to three.js, I would think that this may be trivial task for some experienced three.js user.

更新:为确保确定,孔多边形始终表现良好,这意味着孔多边形始终完全位于材料多边形内部,并且在材料多边形或孔-中没有重复的顶点或自相交多边形和所有材料多边形的CW缠绕顺序和孔均为CCW.

UPDATE: And just to make sure, the hole polygons are always well-behaved, which means that hole polygons are always fully inside material-polygons and there are no duplicate vertices or self-intersections either in material-polygons or hole-polygons and all material-polygons have CW winding order and holes CCW.

更新:合并几何不是一种用于纹理化由一个纹理设置的整个拉伸多边形的解决方案: http://jsfiddle. net/C5dga .在所有单个形状上都会重复纹理,因此在这种情况下合并几何形状没有实际意义.可能会在形状融合之前找到解决方案,但尚未找到解决方案.

UPDATE: Merging geometries was not a solution for texturing the whole extruded polygon set by one texture: http://jsfiddle.net/C5dga. The texture is repeated on all individual shapes, so merging geometries in this case has no real meaning. The solution could be possibly found on merging shapes before they are extruded, but not found solution for this yet.

推荐答案

您可以按照以下代码段合并几何,从而仅生成一个网格.从先前的问题中,您已经知道如何对单个几何图形进行纹理处理.

You can merge geometries as in the following snippet, resulting in just a single mesh. From your prior questions, you already know how to texture a single geometry.

var geometry1 = new THREE.ExtrudeGeometry( shape1, extrusionSettings );
var geometry2 = new THREE.ExtrudeGeometry( shape2, extrusionSettings );

geometry1.merge( geometry2 );

. . .

var mesh = new THREE.Mesh( geometry1, material );

scene.add( mesh );

小提琴: http://jsfiddle.net/pHn2B/88/

提琴: http://jsfiddle.net/C5dga/13/(带有纹理)

作为创建单独的几何图形和使用merge实用程序的替代方法,您可以使用以下模式来创建单个几何图形:

As an alternative to creating separate geometries and using the merge utility, you can create a single geometry using the following pattern, instead:

var geometry1 = new THREE.ExtrudeGeometry( [ shape1, shape2 ], extrusionSettings );

已更新为three.js r.70

updated to three.js r.70

这篇关于拉伸具有多个孔的多个多边形并纹理化组合的形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆