在3D圆柱模型中避免接缝(Avoiding seam in 3D cylinder model)

编程入门 行业动态 更新时间:2024-10-26 07:31:42
在3D圆柱模型中避免接缝(Avoiding seam in 3D cylinder model)

我有这个纹理代表管道的内部区域:

我创建了一个简单的圆柱模型( GeometryModel3D ),将上面的纹理分解为点网格,然后将其包裹起来形成圆柱体,然后将上面的纹理映射到它(网格上的每个正方形有两个三角形):

纹理的左边缘和右边缘在上面的黑色接缝线处相遇,这是不希望的。

我无法在那里使用单个顶点进行平滑连续,因为该点对应于0度和360度(单角度),而是2D纹理边缘上的两个不同点。

所以我在同一个位置使用了一对顶点,但每个顶点对应于源纹理中的不同点。

有什么我可以做的来隐藏接缝线?

模型创建代码:

private void SceneViewerWindowOnLoaded(object sender, RoutedEventArgs e) { var imageSource = new BitmapImage(new Uri("pack://application:,,,/Resources/out1.jpg")); var meshGeometry3D = new MeshGeometry3D(); double circumference = imageSource.PixelWidth; double radius = (circumference / (2.0 * Math.PI)); double angleSegment = (2.0 * Math.PI / SegmentCountTrans); double sizeSegmentLong = ((double)imageSource.PixelHeight / SegmentCountLong); double sizeSegmentTrans = ((double)imageSource.PixelWidth / SegmentCountTrans); for (int indexSegmentLong = 0; indexSegmentLong < SegmentCountLong; indexSegmentLong++) { double depth = (indexSegmentLong * sizeSegmentLong); for (int indexSegmentTrans = 0; indexSegmentTrans < SegmentCountTrans; indexSegmentTrans++) { meshGeometry3D.Positions.Add(GetVertexPosition(indexSegmentTrans, depth, radius, angleSegment)); meshGeometry3D.TextureCoordinates.Add(new Point(indexSegmentTrans * sizeSegmentTrans, depth)); } // add one extra vertex representing 360 degrees for complete wrap-around meshGeometry3D.Positions.Add(GetVertexPosition(SegmentCountTrans, depth, radius, angleSegment)); meshGeometry3D.TextureCoordinates.Add(new Point(SegmentCountTrans * sizeSegmentTrans, depth)); } meshGeometry3D.TriangleIndices.Clear(); for (int indexSegmentLong = 0; indexSegmentLong < (SegmentCountLong - 1); indexSegmentLong++) { for (int indexSegmentTrans = 0; indexSegmentTrans < SegmentCountTrans; indexSegmentTrans++) { int indexCurrent = (indexSegmentLong * (SegmentCountTrans + 1) + indexSegmentTrans); meshGeometry3D.TriangleIndices.Add(indexCurrent); meshGeometry3D.TriangleIndices.Add(indexCurrent + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 2); } } var geometryModel3D = new GeometryModel3D { Geometry = meshGeometry3D, Material = new DiffuseMaterial { Brush = new ImageBrush(imageSource) } }; this.SceneViewer.Model = geometryModel3D; } private static Point3D GetVertexPosition(int indexSegmentAngle, double depth, double radius, double angleSegment) { double angle = (StartAngle + indexSegmentAngle * angleSegment); return new Point3D( radius * Math.Cos(angle), radius * Math.Sin(angle), -depth); }

包含模型的Viewport3D元素的XAML代码:

<Viewport3D x:Name="Viewport3D"> <Viewport3D.Camera> <PerspectiveCamera x:Name="Camera" Position="0.0,0.0,0.0" LookDirection="0.0,0.0,-1.0" UpDirection="0.0,1.0,0.0" FieldOfView="90"/> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <AmbientLight Color="White"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D x:Name="ModelVisualModel"/> </Viewport3D>

I have this texture representing internal area of a pipe:

I have created a simple cylinder model (GeometryModel3D) by dissecting the above texture to a grid of points and than wrapping this to form a cylinder, then mapping the above texture to it (each square on a grid having two triangles):

The left and right edges of the texture meet at the above black seam line, which is unwanted.

I could not use single vertex point for smooth continuation there, because that point corresponds to both 0 and 360 degrees which is single angle, but two distinct points on edges of the 2D texture.

So I have used pairs of vertices on the same location but each corresponding to different point in the source texture.

Is there anything I can do to hide the seam line?

Model creation code:

private void SceneViewerWindowOnLoaded(object sender, RoutedEventArgs e) { var imageSource = new BitmapImage(new Uri("pack://application:,,,/Resources/out1.jpg")); var meshGeometry3D = new MeshGeometry3D(); double circumference = imageSource.PixelWidth; double radius = (circumference / (2.0 * Math.PI)); double angleSegment = (2.0 * Math.PI / SegmentCountTrans); double sizeSegmentLong = ((double)imageSource.PixelHeight / SegmentCountLong); double sizeSegmentTrans = ((double)imageSource.PixelWidth / SegmentCountTrans); for (int indexSegmentLong = 0; indexSegmentLong < SegmentCountLong; indexSegmentLong++) { double depth = (indexSegmentLong * sizeSegmentLong); for (int indexSegmentTrans = 0; indexSegmentTrans < SegmentCountTrans; indexSegmentTrans++) { meshGeometry3D.Positions.Add(GetVertexPosition(indexSegmentTrans, depth, radius, angleSegment)); meshGeometry3D.TextureCoordinates.Add(new Point(indexSegmentTrans * sizeSegmentTrans, depth)); } // add one extra vertex representing 360 degrees for complete wrap-around meshGeometry3D.Positions.Add(GetVertexPosition(SegmentCountTrans, depth, radius, angleSegment)); meshGeometry3D.TextureCoordinates.Add(new Point(SegmentCountTrans * sizeSegmentTrans, depth)); } meshGeometry3D.TriangleIndices.Clear(); for (int indexSegmentLong = 0; indexSegmentLong < (SegmentCountLong - 1); indexSegmentLong++) { for (int indexSegmentTrans = 0; indexSegmentTrans < SegmentCountTrans; indexSegmentTrans++) { int indexCurrent = (indexSegmentLong * (SegmentCountTrans + 1) + indexSegmentTrans); meshGeometry3D.TriangleIndices.Add(indexCurrent); meshGeometry3D.TriangleIndices.Add(indexCurrent + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + 1); meshGeometry3D.TriangleIndices.Add(indexCurrent + SegmentCountTrans + 2); } } var geometryModel3D = new GeometryModel3D { Geometry = meshGeometry3D, Material = new DiffuseMaterial { Brush = new ImageBrush(imageSource) } }; this.SceneViewer.Model = geometryModel3D; } private static Point3D GetVertexPosition(int indexSegmentAngle, double depth, double radius, double angleSegment) { double angle = (StartAngle + indexSegmentAngle * angleSegment); return new Point3D( radius * Math.Cos(angle), radius * Math.Sin(angle), -depth); }

XAML code for the Viewport3D element containing the model:

<Viewport3D x:Name="Viewport3D"> <Viewport3D.Camera> <PerspectiveCamera x:Name="Camera" Position="0.0,0.0,0.0" LookDirection="0.0,0.0,-1.0" UpDirection="0.0,1.0,0.0" FieldOfView="90"/> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <AmbientLight Color="White"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D x:Name="ModelVisualModel"/> </Viewport3D>

最满意答案

在创建图像画笔时,尝试将TileMode设置为TileMode.Tile,将ViewportUnits设置为BrushMappingMode.Absolute。 如果仍然不起作用,那么在这里发布一个后续评论,我会尝试在我的最后重现它。

When you create your image brush try setting the TileMode to TileMode.Tile and ViewportUnits to BrushMappingMode.Absolute. If that still doesn't work then post a follow-up comment here and I'll try to reproduce it on my end.

更多推荐

本文发布于:2023-08-03 16:09:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1393337.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:圆柱   模型   Avoiding   model   cylinder

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!