获取几何模型3D的名称

本文关键字:3D 模型 何模型 获取 | 更新日期: 2023-09-27 18:37:25

>FrameworkElement.FindName(string name)方法从 XAML 名称范围返回一个对象。与此相反,有没有办法通过传递对象来获取对象的名称作为字符串?

例:

以下视口3D包含一个红色圆锥体和一个蓝色圆锥体。在命中测试中,我可以得到单击的锥体对象。但是我需要的是关于哪个锥体被击中的信息(最好是"redCone"作为字符串),所以我可以使用这些信息来决定,比如说,弹出哪个图像

    <Viewport3D Name="myViewport" MouseDown="myViewport_MouseDown">
        <Viewport3D.Children>
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <Model3DGroup >
                        <Model3DGroup.Children>
                            <!-- Define a red cone -->
                            <GeometryModel3D x:Name="redCone">
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D />
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                            <!-- Define a blue cone -->
                            <GeometryModel3D x:Name="redCone">
                                <GeometryModel3D.Geometry>
                                    <MeshGeometry3D />
                                </GeometryModel3D.Geometry>
                            </GeometryModel3D>
                        </Model3DGroup.Children>
                    </Model3DGroup>
                </ModelVisual3D.Content>
            </ModelVisual3D>
        </Viewport3D.Children>
    </Viewport3D>

到目前为止,我拥有的:

确实有一个非动态解决方案,我必须根据硬编码对象检查单击的对象:

    private void myViewport_MouseDown(object sender, MouseButtonEventArgs e)
    {
        Point mousePoint = e.GetPosition(this);
        PointHitTestParameters pointparams = new PointHitTestParameters(mousePoint);
        //Test for a result in the Viewport3D
        VisualTreeHelper.HitTest(myViewport, null, HTResult, pointparams);
    }
    public HitTestResultBehavior HTResult(System.Windows.Media.HitTestResult rawresult)
    {
        RayHitTestResult rayResult = rawresult as RayHitTestResult;
        if (rayResult != null)
        {
            RayMeshGeometry3DHitTestResult rayMeshResult = rayResult as RayMeshGeometry3DHitTestResult;
            if (rayMeshResult != null)
            {
                GeometryModel3D hitGeometry = rayMeshResult.ModelHit as GeometryModel3D;
                // Non-dynamic solution:
                if (hitGeometry.Equals(redCone))
                    infoImage.Source = System.IO.Path.Combine(imagesPath, "redCone.png");
                else if (hitGeometry.Equals(blueCone))
                    infoImage.Source = System.IO.Path.Combine(imagesPath, "blueCone.png");
                // Desired solution:
                // string hitName = FindObject(hitGeometry);
                // infoImage.Source = System.IO.Path.Combine(imagesPath, hitName, ".png");
            }
        }
        return HitTestResultBehavior.Stop;
    }

但如您所见,我必须为要进行命中测试的每个GeometryModel3D对象编写代码,并将其与hitGeometry进行比较。最好有一个方法(如上面的代码中的FindObject),该方法通过传递对象返回分配给 XAML 名称范围中"hitGeometry"的名称。

问题:

有没有一种解决方案,我可以获取被击中的对象的名称,这样我就不必在每次 3D 景观更改时都更改我的代码?

注意事项:

  • 这适用于GeometryModel3D对象,因此没有Name属性。
  • GeometryModel3D是密封类
  • ViewPort3D 的实际 XAML 是从.3ds文件生成的,并且比这更复杂,所以我无法更改结构

获取几何模型3D的名称

我们前段时间一直在寻找方法来做到这一点,发现无论如何您都必须存储可点击元素的列表......在我们的项目中,我们通过存储一个包含您实际单击GeometryModel3D对象名称的List<string>来部分解决此问题。

命中测试部分看起来与您的相似:

...
    if (rayMeshResult != null)
       {
          GeometryModel3D hitgeo = rayMeshResult.ModelHit as GeometryModel3D;
          foreach (string s in List)
          {
           if (hitgeo.Equals(FindName(s)))
           {
               //do something
           }
         }
       }

对于想要实现这一目标的人,

我使用了这种方法:

  <GeometryModel3D x:Name="cube" AutomationProperties.Name="cube1">

然后在鼠标按下事件中:

        // See if we hit a model.
        RayMeshGeometry3DHitTestResult mesh_result =
            result as RayMeshGeometry3DHitTestResult;
        if (mesh_result != null)
        {
            GeometryModel3D model =
                (GeometryModel3D)mesh_result.ModelHit;
            Title = AutomationProperties.GetName(model);

你会得到立方体1

实际上,x:Name似乎在运行时毫无用处,只有 AutomationProperties.Name 在工作。

这篇文章对我很有帮助:在 WPF 中,x:Name 和 Name 属性之间有什么区别?