我的程序读入ASCII编码的.stl文件并将其解析为TriangleMesh,以便在屏幕上显示它。只要我只需要整个几何体的单一颜色,它就可以正常工作。但现在我希望能够为网格上的不同多边形分配不同的颜色。接下来,我们将知道哪个面将被赋予什么颜色,但现在概念的证明就足够了。不幸的是我无法让它发挥作用。 以下是我到目前为止的情况:
public static MeshView parseSTLwithColor(String stlString){
TriangleMesh mesh = new TriangleMesh();
PhongMaterial textureMaterial = new PhongMaterial();
Image texture = new Image("http://nikijacob.com/wp-content/uploads/2011/01/Mosaic.jpg");
textureMaterial.setDiffuseMap(texture);
只需设置一个不同颜色的快速测试纹理。
String withoutHeader = stlString.substring(12);
String[] facetsArray = withoutHeader.split("endfacet");
for(int h=0;h<facetsArray.length;h++){
if(facetsArray[h].contains("endloop")){
facetsArray[h] = facetsArray[h].substring(0,facetsArray[h].indexOf("endloop"));
}
}
for(int i= 0 ; i<facetsArray.length;i++){
int facetOffset = i*3;
String[] verticesArray = facetsArray[i].split("vertex");
if(verticesArray.length != 4) break;
for(int j=1;j<4;j++){
String[] vectorArray = verticesArray[j].split(" ");
for(int k=1;k<4;k++) mesh.getPoints().addAll(Float.parseFloat(vectorArray[k]));
是的,这不是一个好方法,但这只是第一次尝试。基本上,ASCII编码的网格数据串被分割成网格的面,然后每个面被分成3个点,然后每个点被分成3个向量,就像我们在3d中一样。每个都被解析为Float并添加到TriangleMesh的点数组中。
mesh.getTexCoords().addAll(1/(100+j),1/(100+j));
}
接下来,我为每个点指定一个纹理坐标。我尝试给每个点稍微不同的坐标,因为我认为这可能会有所帮助。 (但事实并非如此。)
mesh.getFaces().addAll((facetOffset), (facetOffset),(1+facetOffset), (1+facetOffset),(2+facetOffset), (2+facetOffset));
}
MeshView meshView = new MeshView(mesh);
meshView.setMaterial(textureMaterial);
return meshView;
}
只是一点家务。从点和纹理坐标构建面,实例化MeshView并为其提供纹理,以便可以返回纹理化的网格视图。
现在,问题在于,不是为面部分配不同的颜色,而是3d对象的整个表面似乎被赋予了整个纹理的混合。当我用一半的红色和一半的蓝色纹理进行测试时,整个几何体呈现为紫色。
答案 0 :(得分:1)
呃...当我使用位于我的计算机上的.png而不是来自互联网的.gif时,它会起作用。
答案 1 :(得分:0)
在这里回答一个非常古老的问题,但我自己就摔倒了这个兔子洞。
它的长短是:使用外部程序在STL文件周围包裹纹理是不可行的。
原因是因为STL文件没有提供正确的纹理坐标映射(例如.getTexCoords()
)。
也就是说,法线贴图是独一无二的,所以我确实做了一些黑客攻击,从小平面剥离法线向量(例如[1]),计算小平面的数量和平方根数(假设我们将填充方形图像):
int facets = (int)Math.sqrt((lines.size() - 2) / 7);
其中:lines
是文件长度的String[]
,STL的页眉和页脚是2行,有7行描述每个方面。
然后取正常的矢量并滥用它:
mesh.getTexCoords().addAll(((Float.parseFloat(n) + 1) / -2));
其中:n
是法线向量中的值,而+ 1
/ / -2
是关于将法线向量归一化为-1 - &gt; 0,到0 - &gt; 1(.getTexCoords()
)的可接受范围。
这很hacky,但它更可行。你至少可以做出纹理的正面和反面。
这里的真正解决方案是使用实际从Blender等程序输出UV映射的对象(例如obj
&#39} vt
导出值):{{3} }
[1]:
facet normal -0 0 1
outer loop
vertex -10 12 9
vertex 10 0 9
vertex 10 12 9
endloop
endfacet