Jedes Dokument hat in Autodesk Inventor in seinen Dokumenteneinstellungen ein benutzerdefiniertes Set an Maßeinheiten (Units of Measure, kurz UOM), sowie Angaben zu deren Präzision. Werden bspw. Inch oder Millimeter für Längenangaben genutzt, werden der Radiant oder das Gradmaß verwendet oder Gewichtsangaben in Gramm oder Kilogramm angegeben. Diese Angaben dienen aber nur dem Nutzer, der die grafische Oberfläche von Inventor verwendet. Nutzt man bspw. die API um eine Länge von einem Bauteil zu berechnen, rechnet Inventor immer mit der internen Maßeinheit Zentimeter. Dies gilt es zu berücksichtigen, wenn man diese Werte ausliest und ggf. weiterverarbeitet. Die internet Bezeichnung für den Satz an Maßeinheiten der API lautet DatabaseUnits.

Internal DatabaseUnits

Inventor nutzt zur internen Berechnung die folgenden Maßeinheiten. Sie werden DatabaseUnits genannt:

Einheitenkategorie Maßeinheit
Mass Kilogramm
Length Centimeter
Time Second
Temperature Kelvin
Angle Radiant

Problematisch im Konstruktionswesen sind an dieser Stelle die Längenangaben in Zentimeter, da der Millimeter für Konstruktionsdaten als Goldstandard gilt, sowie das Winkelmaß als Radiant, das für den menschlichen Verstand nicht so gut greifbar ist, wie das Winkelmaß.

Maßeinheiten und die API

Die API stellt für das Arbeiten mit Maßeinheiten zwei wichtige Werkzeuge bereit:

  • Das Objekt UnitsOfMeasure:

    Dieses Objekt hat die zugehöriger Methode zur Konvertierung von Einheiten und gleichzeitig die in den Dokumenteneinstellungen gesetzten Einheiten zum Auslesen und Manipulieren verfügbar.

  • Den Enum UnitTypeEnum:

    Mit diesem Enum kann bestimmt werden, um was für eine Einheitenangabe es sich handelt, bspw. um eine generelle Längenangabe, aber auch präziser um eine Längenangabe mit der Einheit Millimeter.

Beispiel zur Veranschaulichung

Als praktisches Beispiel dient ein Zylinder mit einem Durchmesser Ø25mm und einer extrudierten Länge von 80mm:

Das Zylinderbauteil hat in den Dokumenteneigenschaften die Maßeinheit mm für Längenangaben gesetzt:

Eine Extrusion ist ein sogenanntes Feature. Features sind in der API unter dem Objekt ComponentDefinition.Features zu finden. Dort gibt es den Endpunkt ExtrudeFeatures, in dem alle Dimensionsparameter zu finden sind, die den Beispielzylinder beschreiben:

Unterhalb der ExtrudeFeatures gibt es den Abschnitt Parameters, der eine Liste mit allen geometriebeschreibenden Parametern vorhält. Der Durchmesser des Zylinder ist in dieser Liste Item 1 und die ausgetragene Länge Item 3.

Als Value erkennt man auf dem Screenshot, dass die Werte 2,5 und 8 angegeben werden, obwohl 25mm und 80mm definiert wurden. Dies muss immer berücksichtigt werden, wenn ein solcher Wert ausgelesen und bspw. in einer Variable gespeichert und weiterverwendet wird.

Konvertierung von Maßeinheiten

Als Beispiel für eine Maßeinheitenkonvertierung wird der Durchmesser des Zylinders gewählt. Dieser hat, wie bereits angemerkt, die Nummer Item 1 in der Parameterliste der ExtrudeFeatures. Um den internen Wert cm nun in mm zu konvertieren wird zum einen der UnitsTypeEnum benötigt und das UnitsOfMeasure-Objekt des Dokuments, dass die Methode ConvertUnits bereitstellt.

Die ConvertUnits()-Methode benötigt 3 Parameter:

  1. Einen Eingabewert, der konvertiert werden soll.
  2. Ein Ausgangsmaßeinheit, von dem aus konvertiert werden soll. In diesem Fall ist es die interne DatabaseUnit für Längenangaben.
  3. Ein Maßeinheit, in die konvertiert werden soll, also mm.
Dim oDoc As Document = ThisDoc.Document
Dim UOM As UnitsOfMeasure = oDoc.UnitsOfMeasure

' Auslesen des Zylinderdurchmessers
Dim DiameterCylinder As Double = oDoc.ComponentDefinition.Features.ExtrudeFeatures.Item(1).Parameters.Item(1).Value

' Konvertierung in Millimeter
Dim DiameterCylinderMillimeters As Double = UOM.ConvertUnits(DiameterCylinder, UnitsTypeEnum.kDatabaseLengthUnits, UnitsTypeEnum.kMillimeterLengthUnits)

MsgBox("Der Durchmesser beträgt intern: " & DiameterCylinder & vbLf & "Der Durchmesser beträgt konvertiert: " & DiameterCylinderMillimeters, MessageBoxButtons.OK, "Konvertierung")

Tipp: Im Post iLogic: User Interaktion wird ausführlich auf die Verwendung von MessageBoxes eingegangen.

Praxisbeispiel: Importierte CAD-Daten mit falschen Maßeinheiten in Dokumenteneinstellungen

Vor kurzem gab es in meinem Unternehmen folgende Situation:

  • Ein externer Zulieferer importierte eine größere native Inventor Baugruppe.
  • Sämtliche Bauteile hatten in den Dokumenteneigenschaften einen abweichenden Satz an Maßeinheiten, konkret wurde Meter, statt Millimeter als Längeneinheit definiert.

Korrekturoption 1: Abfrage und Korrektur der Units im Dokument mit iLogic trigger

Diese Subroutine kann einfach als Trigger vor dem Speichern gesetzt werden und kontrolliert, ob die gewünschten Einheiten und Präzisionswerte vorhanden sind. Ist dies nicht der Fall werden sie korrigiert. Sie prüft und korrigiert nur in Bauteilen und Baugruppen, da Zeichnungen auf die Werte der dargestellten Dokumente zugreifen.

Sub Main()
    Dim oDoc As Document = ThisDoc.Document

    If oDoc.DocumentType = kPartDocumentObject Or oDoc.DocumentType = kAssemblyDocumentObject Then
        Call CheckAndSetUnits(oDoc)
    End If
End Sub


Private Sub CheckAndSetUnits(oDoc As Document)
    If oDoc.UnitsOfMeasure.LengthUnits = UnitsTypeEnum.kMillimeterLengthUnits _
        And oDoc.UnitsOfMeasure.LengthDisplayPrecision = 3 _
        And oDoc.UnitsOfMeasure.AngleUnits = UnitsTypeEnum.kDegreeAngleUnits _
        And oDoc.UnitsOfMeasure.AngleDisplayPrecision = 2 _
        And oDoc.UnitsOfMeasure.MassUnits = UnitsTypeEnum.kKilogramMassUnits _
        And oDoc.UnitsOfMeasure.TimeUnits = UnitsTypeEnum.kSecondTimeUnits Then

        ' Subroutine beenden, da Einheiten korrekt sind
        Exit Sub
    Else
        oDoc.UnitsOfMeasure.LengthUnits = UnitsTypeEnum.kMillimeterLengthUnits
        oDoc.UnitsOfMeasure.LengthDisplayPrecision = 3
        oDoc.UnitsOfMeasure.AngleUnits = UnitsTypeEnum.kDegreeAngleUnits
        oDoc.UnitsOfMeasure.AngleDisplayPrecision = 2
        oDoc.UnitsOfMeasure.MassUnits = UnitsTypeEnum.kKilogramMassUnits
        oDoc.UnitsOfMeasure.TimeUnits = UnitsTypeEnum.kSecondTimeUnits
    End If
End Sub

Korrekturoption 2: Alle Unterkomponenten der Baugruppe im Batch korrigieren

Alternativ zu einer Trigger-basierten Korrektur, kann auch die oberste Baugruppe geöffnet und eine iLogic manuell ausgeführt werden, die über die gesamten Unterkomponenten der Bauteile iteriert und jedes Teil dabei prüft und ggf. korrigiert. Dafür muss in der API das Objekt ReferencedDocuments verwendet werden. ReferencedDocuments beinhaltet Verweise auf sämtliche Dokumente, die in einer Baugruppe verbaut sind und auch auf den Basiseinheitensatz jedes verbauten Dokuments:

Dies ist zugleich eine gute Möglichkeit eine nützliche Funktionalität kennenzulernen: Eine For Each-Schleife.

Sub Main()
    Dim oDoc As Document = ThisDoc.Document
    Dim oDocRefs As DocumentsEnumerator = oDoc.ReferencedDocuments

    For Each oDocRef In oDocRefs
        If oDoc.DocumentType = kPartDocumentObject Or oDoc.DocumentType = kAssemblyDocumentObject Then
            Call CheckAndSetUnits(oDocRef)
        End If
    Next
End Sub


Private Sub CheckAndSetUnits(oDoc As Document)
    If oDoc.UnitsOfMeasure.LengthUnits = UnitsTypeEnum.kMillimeterLengthUnits _
        And oDoc.UnitsOfMeasure.LengthDisplayPrecision = 3 _
        And oDoc.UnitsOfMeasure.AngleUnits = UnitsTypeEnum.kDegreeAngleUnits _
        And oDoc.UnitsOfMeasure.AngleDisplayPrecision = 2 _
        And oDoc.UnitsOfMeasure.MassUnits = UnitsTypeEnum.kKilogramMassUnits _
        And oDoc.UnitsOfMeasure.TimeUnits = UnitsTypeEnum.kSecondTimeUnits Then

        ' Subroutine beenden, da Einheiten korrekt sind
        Exit Sub
    Else
        oDoc.UnitsOfMeasure.LengthUnits = UnitsTypeEnum.kMillimeterLengthUnits
        oDoc.UnitsOfMeasure.LengthDisplayPrecision = 3
        oDoc.UnitsOfMeasure.AngleUnits = UnitsTypeEnum.kDegreeAngleUnits
        oDoc.UnitsOfMeasure.AngleDisplayPrecision = 2
        oDoc.UnitsOfMeasure.MassUnits = UnitsTypeEnum.kKilogramMassUnits
        oDoc.UnitsOfMeasure.TimeUnits = UnitsTypeEnum.kSecondTimeUnits
    End If
End Sub