Creating geometry from scratch using Inventors API




With just a list of points and a list of indices to link the points together with, we can create any geometry.

This example shows how with just these two lists we can then create lines in a 3D sketch, construct a surface from the lines and then patching all the surfaces together into a solid body.

Setup

we need to create references to Inventor and the currently active part document, with this we can then create a new 3D sketch.

To define the geometry, two lists are used, a list of points and a list of faces.

The list of points is what will determine the size and shape of the geometry, in this case, a dodecahedron.

Each point of the dodecahedron is used by three different edges. A list of indices reduces duplication by listing out which points are used for each face. With a list of faces, each containing five indices, we can start constructing the geometry.

Constructing the geometry

By looping through each face in the list of faces, we can add lines to the sketch for each pair of indices. The data is not structured in pairs, but we can assume that each face constructs a loop. Thus, a line is added between each point and the next in the array.

Once all the lines have been added to the sketch, it is then possible to create a boundary patch between them. This patch is what results in a surface being created in Inventor.

To create the solid body the surfaces then need to be stitched together, to do this we will add the Work Surface object for each face to a collection that can then be stitched. Somewhat confusingly to get form the Boundary Patch Feature to the Work Surface Object we use the following line:

surfacetostich.Add(boundaryPatchFeature.SurfaceBody.Parent)

This line goes form: BoundaryPatchFeature to SurfaceBody to WorkSurfaceObject as KnitFeatrues only accepts WorkSurface objects.

Once all the surfaces have been added to the collection it is then a simple matter of calling the KnitFeatures.Add object with the collection.

The Code

C#
if (_invApp == null)
{
    _invApp = (Inventor.Application)Marshal.GetActiveObject("Inventor.Application");
}

PartDocument oDoc = (PartDocument)_invApp.ActiveDocument;
PartComponentDefinition oCompDef = oDoc.ComponentDefinition;
Sketch3D oSketch = oCompDef.Sketches3D.Add();

// Define the golden ratio
double phi = (1 + Math.Sqrt(5)) / 2;

// Define vertices of the dodecahedron
Inventor.Point[] vertices = new Inventor.Point[20];
vertices[0] = _invApp.TransientGeometry.CreatePoint(1, 1, 1);
vertices[1] = _invApp.TransientGeometry.CreatePoint(1, 1, -1);
vertices[2] = _invApp.TransientGeometry.CreatePoint(1, -1, 1);
vertices[3] = _invApp.TransientGeometry.CreatePoint(1, -1, -1);
vertices[4] = _invApp.TransientGeometry.CreatePoint(-1, 1, 1);
vertices[5] = _invApp.TransientGeometry.CreatePoint(-1, 1, -1);
vertices[6] = _invApp.TransientGeometry.CreatePoint(-1, -1, 1);
vertices[7] = _invApp.TransientGeometry.CreatePoint(-1, -1, -1);
vertices[8] = _invApp.TransientGeometry.CreatePoint(0, phi, 1 / phi);
vertices[9] = _invApp.TransientGeometry.CreatePoint(0, phi, -1 / phi);
vertices[10] = _invApp.TransientGeometry.CreatePoint(0, -phi, 1 / phi);
vertices[11] = _invApp.TransientGeometry.CreatePoint(0, -phi, -1 / phi);
vertices[12] = _invApp.TransientGeometry.CreatePoint(1 / phi, 0, phi);
vertices[13] = _invApp.TransientGeometry.CreatePoint(1 / phi, 0, -phi);
vertices[14] = _invApp.TransientGeometry.CreatePoint(-1 / phi, 0, phi);
vertices[15] = _invApp.TransientGeometry.CreatePoint(-1 / phi, 0, -phi);
vertices[16] = _invApp.TransientGeometry.CreatePoint(phi, 1 / phi, 0);
vertices[17] = _invApp.TransientGeometry.CreatePoint(phi, -1 / phi, 0);
vertices[18] = _invApp.TransientGeometry.CreatePoint(-phi, 1 / phi, 0);
vertices[19] = _invApp.TransientGeometry.CreatePoint(-phi, -1 / phi, 0);

// Define faces of the dodecahedron using vertex indices
List<int[]> faces = new List<int[]>
{
    new int[] {1, 13, 15, 5, 9}, new int[] {2, 12, 14, 6, 10}, new int[] {0, 12, 14, 4, 8},
    new int[] {0, 8, 9, 1, 16}, new int[] {16, 17, 3, 13, 1}, new int[] {11, 7, 15, 13, 3},
    new int[] {17, 2, 12, 0, 16}, new int[] {10, 2, 17, 3, 11}, new int[] {4, 14, 6, 19,18},
    new int[] {18, 4, 8, 9, 5}, new int[] {6, 10, 11, 7, 19}, new int[] {5, 18, 19, 7, 15}
};

// create edges and surfaces
ObjectCollection surfacetostich = _invApp.TransientObjects.CreateObjectCollection();
foreach (int[] face in faces)
{
    ObjectCollection edges = _invApp.TransientObjects.CreateObjectCollection();
    for (int i = 0; i < face.Length; i++)
    {
        if (i == 0) { edges.Add(oSketch.SketchLines3D.AddByTwoPoints(vertices[face[i]], vertices[face[face.Length - 1]])); }
        else { edges.Add(oSketch.SketchLines3D.AddByTwoPoints(vertices[face[i - 1]], vertices[face[i]])); }
    }

    BoundaryPatchDefinition boundaryPatchDefinition = oCompDef.Features.BoundaryPatchFeatures.CreateBoundaryPatchDefinition();
    boundaryPatchDefinition.BoundaryPatchLoops.Add(edges);
    BoundaryPatchFeature boundaryPatchFeature = oCompDef.Features.BoundaryPatchFeatures.Add(boundaryPatchDefinition);

    surfacetostich.Add(boundaryPatchFeature.SurfaceBody.Parent);
}
// Join surfaces together
_ = oCompDef.Features.KnitFeatures.Add(surfacetostich);
VB
If _invApp Is Nothing Then
    _invApp = CType(Marshal.GetActiveObject("Inventor.Application"), Inventor.Application)
End If

Dim oDoc As PartDocument = CType(_invApp.ActiveDocument, PartDocument)
Dim oCompDef As PartComponentDefinition = oDoc.ComponentDefinition
Dim oSketch As Sketch3D = oCompDef.Sketches3D.Add()

' Define the golden ratio
Dim phi As Double = (1 + Math.Sqrt(5)) / 2

' Define vertices of the dodecahedron
Dim vertices(19) As Inventor.Point
vertices(0) = _invApp.TransientGeometry.CreatePoint(1, 1, 1)
vertices(1) = _invApp.TransientGeometry.CreatePoint(1, 1, -1)
vertices(2) = _invApp.TransientGeometry.CreatePoint(1, -1, 1)
vertices(3) = _invApp.TransientGeometry.CreatePoint(1, -1, -1)
vertices(4) = _invApp.TransientGeometry.CreatePoint(-1, 1, 1)
vertices(5) = _invApp.TransientGeometry.CreatePoint(-1, 1, -1)
vertices(6) = _invApp.TransientGeometry.CreatePoint(-1, -1, 1)
vertices(7) = _invApp.TransientGeometry.CreatePoint(-1, -1, -1)
vertices(8) = _invApp.TransientGeometry.CreatePoint(0, phi, 1 / phi)
vertices(9) = _invApp.TransientGeometry.CreatePoint(0, phi, -1 / phi)
vertices(10) = _invApp.TransientGeometry.CreatePoint(0, -phi, 1 / phi)
vertices(11) = _invApp.TransientGeometry.CreatePoint(0, -phi, -1 / phi)
vertices(12) = _invApp.TransientGeometry.CreatePoint(1 / phi, 0, phi)
vertices(13) = _invApp.TransientGeometry.CreatePoint(1 / phi, 0, -phi)
vertices(14) = _invApp.TransientGeometry.CreatePoint(-1 / phi, 0, phi)
vertices(15) = _invApp.TransientGeometry.CreatePoint(-1 / phi, 0, -phi)
vertices(16) = _invApp.TransientGeometry.CreatePoint(phi, 1 / phi, 0)
vertices(17) = _invApp.TransientGeometry.CreatePoint(phi, -1 / phi, 0)
vertices(18) = _invApp.TransientGeometry.CreatePoint(-phi, 1 / phi, 0)
vertices(19) = _invApp.TransientGeometry.CreatePoint(-phi, -1 / phi, 0)

' Define faces of the dodecahedron using vertex indices
Dim faces As List(Of Integer()) = New List(Of Integer()) From {
    New Integer() {1, 13, 15, 5, 9}, New Integer() {2, 12, 14, 6, 10}, New Integer() {0, 12, 14, 4, 8},
    New Integer() {0, 8, 9, 1, 16}, New Integer() {16, 17, 3, 13, 1}, New Integer() {11, 7, 15, 13, 3},
    New Integer() {17, 2, 12, 0, 16}, New Integer() {10, 2, 17, 3, 11}, New Integer() {4, 14, 6, 19, 18},
    New Integer() {18, 4, 8, 9, 5}, New Integer() {6, 10, 11, 7, 19}, New Integer() {5, 18, 19, 7, 15}
}

' Create edges and surfaces
Dim surfacetostitch As ObjectCollection = _invApp.TransientObjects.CreateObjectCollection()
For Each face As Integer() In faces
    Dim edges As ObjectCollection = _invApp.TransientObjects.CreateObjectCollection()
    For i As Integer = 0 To face.Length - 1
        If i = 0 Then
            edges.Add(oSketch.SketchLines3D.AddByTwoPoints(vertices(face(i)), vertices(face(face.Length - 1))))
        Else
            edges.Add(oSketch.SketchLines3D.AddByTwoPoints(vertices(face(i - 1)), vertices(face(i))))
        End If
    Next

    Dim boundaryPatchDefinition As BoundaryPatchDefinition = oCompDef.Features.BoundaryPatchFeatures.CreateBoundaryPatchDefinition()
    boundaryPatchDefinition.BoundaryPatchLoops.Add(edges)
    Dim boundaryPatchFeature As BoundaryPatchFeature = oCompDef.Features.BoundaryPatchFeatures.Add(boundaryPatchDefinition)

    surfacetostitch.Add(boundaryPatchFeature.SurfaceBody.Parent)
Next

' Join surfaces together
oCompDef.Features.KnitFeatures.Add(surfacetostitch)

This method does have a slight flaw in that each line is drawn twice, once for each face that uses it. For this demonstration it does not make much difference but if you wanted to go in and add constraints to the sketch you would run into issues. To solve this implementing a method to keep track of edges and reuse them if a line between the same points is required.

By applying this approach, you can create complex geometries from scratch using Inventor’s API, saving time and reducing errors. This example focuses on creating a dodecahedron, but by simply changing out the two lists, any geometry can be created.


Why not see how your newly created parts can be placed in Autodesk Inventor using the API


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *