How to Add a Geometry3D to geometry feature of a component?

As We can create 3D models in Visual Components 3D View with HelixToolkit.Wpf.MeshBuilder, and create a Geometry3D type geometry. Is there a way to add this Geometry3D to a component ? Or convert Geometry3D to geometry feature IGeometryFeature?

1 Like

If you have MeshGeometry3D or other such triangle mesh for your UI-side model, you could fairly easily convert the vertices, triangle indices and normals to make one or more ITriangleSet objects into a IGeometryFeature.

There seems to be a ToMesh() method in the MeshBuilder.

With non-mesh objects you are probably out of luck.

First thanks for your reply, and I tried to build MeshGeometry3D to a ITriangleSet Feature Geometry with codes below, but none geometry show in the component.
There MeshGeometry3D should look like this.

            MeshGeometry3D meshGeo = MeshPart.Geometry3D;

            var geometryFeature = comp.RootNode.RootFeature.CreateFeature<IGeometryFeature>();
            var triangles = geometryFeature.Geometry.CreateGeometrySet(GeometrySetType.TriangleSet) as ITriangleSet;
            comp.RootNode.RootFeature.AddChild(geometryFeature, 0);

            foreach (var vertex in meshGeo.Positions)
                var vec = new Vector3(vertex.X, vertex.Y, vertex.Z);

            var listTriangle = new List<int>();
            foreach (var inde in meshGeo.TriangleIndices)

            //for (int i=0;i<geo.TriangleIndices.Count;i+=3)
            //    triangles.AddTriangle(geo.TriangleIndices[i], geo.TriangleIndices[i + 1], geo.TriangleIndices[i + 2]);


Here is the Debug trace:

Name = ""
    BoundBox: {VisualComponents.Revolution.BoundBoxWrapper}
    BrepAvailable: false
    Container: Name = error CS0103: The name 'Name' does not exist in the current context
    CreaseAngle: 45
    Feature: Name = "Geometry_1"
    HasMaterialInheritance: true
    HasNoHits: false
    HasTextureCoordinates: false
    IsHighlighted: false
    IsLayerVisible: true
    IsValid: true
    IsVisible: true
    IsWrapperValid: true
    Material: null
    Name: ""
    Normals: Count = 48
    ObjectPointer: 0x0000018392ada7e0
    ObjectPrimitiveType: GeometrySet
    Original: Name = ""
    PointCount: 48
    Pointer: 0x0000018392ada7b0
    Points: Count = 48
    Topology: {VisualComponents.Revolution.SolidTopologyWrapper}
    TopologyCurves: Count = 0
    TriangleCount: 48
    Triangles: Count = 144

Could you please show me how to Convert from Geometry3D to Feature.Geometry ITriangleSet, or what’s wrong up above?

This code works fine for me.
Is the component you are adding the geometry dynamic, or is there some other custom logic that might either remove or hide it? Possibly e.g. material inheritance could make the geometry hidden.

There is also IGeometrySet.Update() but it doesn’t seem to be needed in this case.

public void CreateGeometry()
     var app = IoC.Get<IApplication>();
     ISimComponent comp = app.World.CreateComponent("Test Component");

     var p0 = new Point3D(0, 0, 0);
     var p1 = new Point3D(0, 0, 1000);
     var p2 = new Point3D(0, 1000, 1000);

     var builder = new HelixToolkit.Wpf.MeshBuilder();
     builder.AddCylinder(p0, p1, diameter: 100, thetaDiv: 10);
     builder.AddSphere(p1, 50, thetaDiv: 10, phiDiv: 10);
     builder.AddCylinder(p1, p2, diameter: 100, thetaDiv: 10);
     MeshGeometry3D mesh = builder.ToMesh();

     var geometryFeature = comp.RootNode.RootFeature.CreateFeature<IGeometryFeature>();
     var triangleSet = geometryFeature.Geometry.CreateGeometrySet(GeometrySetType.TriangleSet) as ITriangleSet;
     comp.RootNode.RootFeature.AddChild(geometryFeature, 0);

     var points = mesh.Positions.Select(p => new Vector3(p.X, p.Y, p.Z)).ToArray();

Thanks, it’s the mesh points scaled to 1/1000 that made the geometry too small to be found.

1 Like


very interesting topic! :slight_smile:

But how to add the normals to the triangleSet?

Thx & Regards

The normal is a property of surface or frame ,it will calculate automatically when TriangleSet is built.

----code -----
            triangleAxisZ.AddPoints(mesh.Positions.Select(p => new Vector3(p.X, p.Y, p.Z)).ToArray());

------debug trace----
Count = 432
    [0]: {0;0;0}
    [1]: {-0.471394807100296;0;0.881922245025635}
    [2]: {0.161998867988586;0.98298442363739;0.0865903943777084}
    [3]: {0.161998867988586;0.98298442363739;0.0865903943777084}
    [4]: {-0.471394807100296;0;0.881922245025635}
    [5]: {-0.471394807100296;0;0.881922245025635}
    [6]: {0.445980191230774;0.701023817062378;-0.556477665901184}
    [7]: {0.445980161428452;0.701023817062378;-0.556477665901184}
    [8]: {-0.471394807100296;0;0.881922245025635}
    [9]: {-0.471445560455322;2.2293714209809E-05;0.881895184516907}
    [10]: {0.318571090698242;0.932479083538055;0.170280173420906}
    [11]: {0.318608015775681;0.932463049888611;0.17029894888401}
    [12]: {-0.471323013305664;-3.15350080200005E-05;0.88196063041687}
    [13]: {-0.471379607915878;-2.87530911009526E-05;0.881930410861969}
    [14]: {0.558590829372406;0.659363925457001;-0.503205299377441}
    [15]: {0.661563336849213;0.606326878070831;-0.441250294446945}
    [16]: {-0.471496313810349;4.45868281531148E-05;0.881868004798889}
    [17]: {-0.471437573432922;-1.61418138304725E-05;0.881899416446686}
    [18]: {0.59419459104538;0.738959431648254;0.317602902650833}
    [19]: {0.594176948070526;0.738977611064911;0.317593932151794}
    [20]: {-0.471441447734833;3.18389065796509E-05;0.881897330284119}
    [21]: {-0.471384167671204;-1.66147256095428E-05;0.881927967071533}
    [22]: {0.753448307514191;0.522566318511963;-0.399049073457718}
    [23]: {0.832350254058838;0.429788678884506;-0.349963963031769}
    [24]: {-0.471378833055496;-7.68753598094918E-05;0.881930828094482}
    [25]: {-0.471432447433472;4.52768763352651E-05;0.881902098655701}
    [26]: {0.789463520050049;0.445738852024078;0.421976566314697}
    [27]: {0.78946328163147;0.445739686489105;0.421976149082184}
    [28]: {-0.471373230218887;4.51830288739075E-07;0.881933867931366}
    [29]: {-0.471331506967545;4.22938092015102E-06;0.881956160068512}
    [30]: {0.891558706760406;0.315193593502045;-0.325232356786728}
    [31]: {0.935389161109924;0.195159092545509;-0.294889986515045}

Hi, there! Really a good discussion. I see we can create a geometry feature based on MeshBuilder or MeshGeometry3D. I am wondering, is there a good way to achieve the opposite process? Namely, how to generate mesh parameters (such as vertex positions and triangles indices) from the 3D geometry in Visual Components? Many thanks!!


natively you can by export geometry as step (Professional, Premium).