How to use i-logic "ICadMeasure" in Vb.net (Autodesk.iLogic.Interfaces.dll)

How to use i-logic "ICadMeasure" in Vb.net (Autodesk.iLogic.Interfaces.dll)

bradeneuropeArthur
Mentor Mentor
500 Views
3 Replies
Message 1 of 4

How to use i-logic "ICadMeasure" in Vb.net (Autodesk.iLogic.Interfaces.dll)

bradeneuropeArthur
Mentor
Mentor

Hi,

 

How can I use the IcadMeasure Tools from I-logic in vb.net or VBA?

The tool should be available within the "C:\Program Files\Autodesk\Inventor 2018\Bin\Autodesk.iLogic.Interfaces.dll", but I don't know how to use it correctly.

 

What I have already is:

Dim a As Autodesk.iLogic.Interfaces.ICadMeasure

What I need is the property:

ExtentsHeight
ExtentsLength
ExtentsWidth

Any Ideas?

 

Regards,

 

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes
501 Views
3 Replies
Replies (3)
Message 2 of 4

JamieVJohnson2
Collaborator
Collaborator

Since I can't see how that function works under its hood, I surmised that it is using the standard Inventor.Interop, and drilled down to this:  ComponentDefinition.RangeBox (which has MinPoint and MaxPoint).  My guess the iLogic is simplifying this path for you, doing some math, and storing 3 values.

Jamie Johnson : Owner / Sisu Lissom, LLC https://sisulissom.com/
Message 3 of 4

bradeneuropeArthur
Mentor
Mentor

Hi,

 

That was also what I was thinking.

I only wanted to know how it works in background, because maybe there is a easier method then the Rangebox Min and Max point solution.

 

Can anyone confirm my and @JamieVJohnson2 their assumption?

 

Regards,

Regards,

Arthur Knoors

Autodesk Affiliations & Links:
blue LinkedIn LogoSquare Youtube Logo Isolated on White Background


Autodesk Software:Inventor Professional 2025 | Vault Professional 2024 | Autocad Mechanical 2024
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:
Drawing List!|
Toggle Drawing Sheet!|
Workplane Resize!|
Drawing View Locker!|
Multi Sheet to Mono Sheet!|
Drawing Weld Symbols!|
Drawing View Label Align!|
Open From Balloon!|
Model State Lock!
Posts and Ideas:
My Ideas|
Dimension Component!|
Partlist Export!|
Derive I-properties!|
Vault Prompts Via API!|
Vault Handbook/Manual!|
Drawing Toggle Sheets!|
Vault Defer Update!

! For administrative reasons, please mark a "Solution as solved" when the issue is solved !


 


EESignature

0 Likes
Message 4 of 4

Will.Ehrendreich
Contributor
Contributor

I know I'm like.. responding to a long dead thread.. but in case you're super curious, if you use ILSpy or DotPeek or whatever, you can decompile the dll.

 

To see what's actually going on, what you want is not the interface, but the implementation, so that would be in Autodesk.iLogic.Core.dll.

 

when you look at that dissassembly in ILSpy, and search for cadmeasure it spits out this:

 

// iLogic.CadMeasure
using System;
using System.Globalization;
using Autodesk.iLogic.Core.Resources;
using Autodesk.iLogic.Interfaces;
using iLogic;
using iLogic.EntityNameStorage;
using Inventor;

public class CadMeasure : ICadMeasure
{
    private Document m_rootDoc;

    private InventorServerObject m_server;

    private Application m_app;

    private double[] m_currentExtents = new double[3];

    private string m_currentGeomVersion;

    private const string MinimumDistanceName = "MinimumDistance";

    private const string AngleName = "Angle";

    public double ExtentsLength
    {
        get
        {
            if (GetExtents() != 0)
                return 0.0;
            return m_currentExtents[0];
        }
    }

    public double ExtentsWidth
    {
        get
        {
            if (GetExtents() != 0)
                return 0.0;
            return m_currentExtents[1];
        }
    }

    public double ExtentsHeight
    {
        get
        {
            if (GetExtents() != 0)
                return 0.0;
            return m_currentExtents[2];
        }
    }

    public CadMeasure(Document rootDoc, InventorServerObject server)
    {
        m_rootDoc = rootDoc;
        m_server = server;
        m_app = server as Application;
        m_currentGeomVersion = string.Empty;
    }

    public double MinimumDistance(object entityName1, object entityName2)
    {
        ApplicationIsRequired(VisibleCallerName("MinimumDistance"));
        return EntityDistance(GetEntityByName(m_rootDoc, entityName1, VisibleCallerName("MinimumDistance")), ent2: GetEntityByName(m_rootDoc, entityName2, VisibleCallerName("MinimumDistance")), entName1: entityName1.ToString(), entName2: entityName2.ToString());
    }

    public double MinimumDistance(object componentName1, object entityName1, object componentName2, object entityName2)
    {
        ApplicationIsRequired(VisibleCallerName("MinimumDistance"));
        ComponentOccurrence componentOccurrence = FindComponent(componentName1, VisibleCallerName("MinimumDistance"));
        if (componentOccurrence == null)
            return 0.0;
        ComponentOccurrence componentOccurrence2 = FindComponent(componentName2, VisibleCallerName("MinimumDistance"));
        if (componentOccurrence2 == null)
            return 0.0;
        return EntityDistance(GetProxyByName(componentOccurrence, entityName1, VisibleCallerName("MinimumDistance")), ent2: GetProxyByName(componentOccurrence2, entityName2, VisibleCallerName("MinimumDistance")), entName1: entityName1.ToString(), entName2: entityName2.ToString());
    }

    public double Angle(object entityName1, object entityName2, object entityName3)
    {
        ApplicationIsRequired(VisibleCallerName("Angle"));
        object entityByName = GetEntityByName(m_rootDoc, entityName1, VisibleCallerName("Angle"));
        object entityByName2 = GetEntityByName(m_rootDoc, entityName2, VisibleCallerName("Angle"));
        object ent = null;
        string entName = "";
        if (entityName3 is string)
        {
            ent = GetEntityByName(m_rootDoc, entityName3, VisibleCallerName("Angle"));
            entName = entityName3.ToString();
        }
        return EntityAngle(entityByName, entityName1.ToString(), entityByName2, entityName2.ToString(), ent, entName);
    }

    public double Angle(object componentName1, object entityName1, object componentName2, object entityName2, object componentName3, object entityName3)
    {
        ApplicationIsRequired(VisibleCallerName("Angle"));
        ComponentOccurrence componentOccurrence = FindComponent(componentName1, VisibleCallerName("Angle"));
        if (componentOccurrence == null)
            return 0.0;
        ComponentOccurrence componentOccurrence2 = FindComponent(componentName2, VisibleCallerName("Angle"));
        if (componentOccurrence2 == null)
            return 0.0;
        ComponentOccurrence compo = null;
        if (componentName3 != null)
            compo = FindComponent(componentName3, VisibleCallerName("Angle"));
        object proxyByName = GetProxyByName(componentOccurrence, entityName1, VisibleCallerName("Angle"));
        object proxyByName2 = GetProxyByName(componentOccurrence2, entityName2, VisibleCallerName("Angle"));
        object ent = null;
        string entName = "";
        if (entityName3 != null)
        {
            ent = GetProxyByName(compo, entityName3, VisibleCallerName("Angle"));
            entName = entityName3.ToString();
        }
        return EntityAngle(proxyByName, entityName1.ToString(), proxyByName2, entityName2.ToString(), ent, entName);
    }

    public double Area(string sketchName)
    {
        PlanarSketch sketchByName = GetSketchByName(m_rootDoc, sketchName, VisibleCallerName("Area"));
        if (sketchByName == null)
            return 0.0;
        RegionProperties regionProperties = sketchByName.Profiles.AddForSolid(Combine: true, Type.Missing, Type.Missing).RegionProperties;
        regionProperties.Accuracy = AccuracyEnum.kMedium;
        double value = Math.Sqrt(regionProperties.Area);
        double num = m_rootDoc.UnitsOfMeasure.ConvertUnits(value, UnitsTypeEnum.kDatabaseLengthUnits, m_rootDoc.UnitsOfMeasure.LengthUnits);
        return num * num;
    }

    public double Perimeter(string sketchName)
    {
        PlanarSketch sketchByName = GetSketchByName(m_rootDoc, sketchName, VisibleCallerName("Perimeter"));
        if (sketchByName == null)
            return 0.0;
        RegionProperties regionProperties = sketchByName.Profiles.AddForSolid(Combine: true, Type.Missing, Type.Missing).RegionProperties;
        regionProperties.Accuracy = AccuracyEnum.kMedium;
        double perimeter = regionProperties.Perimeter;
        return m_rootDoc.UnitsOfMeasure.ConvertUnits(perimeter, UnitsTypeEnum.kDatabaseLengthUnits, m_rootDoc.UnitsOfMeasure.LengthUnits);
    }

    public static object GetEntityByName(Document doc, object entityName, string callerName)
    {
        string text = entityName.ToString();
        if (doc.DocumentType == DocumentTypeEnum.kPartDocumentObject)
        {
            object entityByNameInCompDef = GetEntityByNameInCompDef(new CadComponentDefinition(doc), text);
            if (entityByNameInCompDef != null)
                return entityByNameInCompDef;
        }
        else if (doc.DocumentType == DocumentTypeEnum.kAssemblyDocumentObject)
        {
            ComponentOccurrence componentOccurrence = CadAssemblyUtil.FindComponentOccurrence(doc, entityName);
            if (componentOccurrence != null)
                return componentOccurrence;
            object entityByNameInCompDef2 = GetEntityByNameInCompDef(new CadComponentDefinition(doc), text);
            if (entityByNameInCompDef2 != null)
                return entityByNameInCompDef2;
        }
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionMsgs.EntityNotFound, callerName, text));
    }

    public static object GetProxyByName(ComponentOccurrence compo, object entityName, string callerName)
    {
        if (compo.Suppressed)
            return null;
        object entityByName = GetEntityByName((Document)compo.Definition.Document, entityName, callerName);
        if (entityByName == null)
            return null;
        object Result = null;
        try
        {
            compo.CreateGeometryProxy(entityByName, out Result);
            return Result;
        }
        catch
        {
            return null;
        }
    }

    public static PlanarSketch GetSketchByName(Document doc, object sketchName, string callerName)
    {
        string text = sketchName.ToString();
        if (doc.DocumentType == DocumentTypeEnum.kPartDocumentObject)
        {
            foreach (PlanarSketch sketch in ((PartDocument)doc).ComponentDefinition.Sketches)
            {
                if (string.Equals(sketch.Name, text, StringComparison.OrdinalIgnoreCase))
                    return sketch;
            }
        }
        else if (doc.DocumentType == DocumentTypeEnum.kAssemblyDocumentObject)
        {
            foreach (PlanarSketch sketch2 in ((AssemblyDocument)doc).ComponentDefinition.Sketches)
            {
                if (string.Equals(sketch2.Name, text, StringComparison.OrdinalIgnoreCase))
                    return sketch2;
            }
        }
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionMsgs.SketchNotFound, callerName, text));
    }

    public static object GetEntityByNameInCompDef(CadComponentDefinition compDef, string entName)
    {
        object obj = CadWorkFeatureUtil.FindWorkFeature(compDef, entName);
        if (obj != null)
            return obj;
        foreach (iMateDefinition iMateDefinition in compDef.iMateDefinitions)
        {
            if (string.Equals(iMateDefinition.Name, entName, StringComparison.OrdinalIgnoreCase))
            {
                if (iMateDefinition is MateiMateDefinition mateiMateDefinition)
                    return mateiMateDefinition.Entity;
                if (iMateDefinition is FlushiMateDefinition flushiMateDefinition)
                    return flushiMateDefinition.Entity;
                if (iMateDefinition is AngleiMateDefinition angleiMateDefinition)
                    return angleiMateDefinition.Entity;
                if (iMateDefinition is InsertiMateDefinition insertiMateDefinition)
                    return insertiMateDefinition.Entity;
                if (iMateDefinition is TangentiMateDefinition tangentiMateDefinition)
                    return tangentiMateDefinition.Entity;
            }
        }
        if (compDef.PartDefinition != null)
            return new EntityNameListAttributeSet((Document)compDef.PartDefinition.Document).GetEntity(entName);
        return CadWorkFeatureUtil.TryToGetWorkFeature(compDef, entName);
    }

    private double EntityDistance(object ent1, string entName1, object ent2, string entName2)
    {
        if (ent1 == null || ent2 == null)
            return 0.0;
        double num;
        try
        {
            object Context = null;
            num = m_server.MeasureTools.GetMinimumDistance(ent1, ent2, InferredTypeEnum.kNoInference, InferredTypeEnum.kNoInference, ref Context);
        }
        catch (Exception innerException)
        {
            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionMsgs.MeasureFailedBetweenObjects, VisibleCallerName("MinimumDistance"), entName1, entName2), innerException);
        }
        return m_rootDoc.UnitsOfMeasure.ConvertUnits(num, UnitsTypeEnum.kDatabaseLengthUnits, m_rootDoc.UnitsOfMeasure.LengthUnits);
    }

    private double EntityAngle(object ent1, string entName1, object ent2, string entName2, object ent3, string entName3)
    {
        double num;
        try
        {
            num = m_server.MeasureTools.GetAngle(ent1, ent2, ent3);
        }
        catch (Exception innerException)
        {
            if (string.IsNullOrEmpty(entName3))
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionMsgs.MeasureFailedBetweenObjects, VisibleCallerName("Angle"), entName1, entName2), innerException);
            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionMsgs.MeasureFailedBetweenThreeObjects, VisibleCallerName("Angle"), entName1, entName2, entName3), innerException);
        }
        return m_rootDoc.UnitsOfMeasure.ConvertUnits(num, UnitsTypeEnum.kDatabaseAngleUnits, m_rootDoc.UnitsOfMeasure.AngleUnits);
    }

    private ComponentOccurrence FindComponent(object componentName, string callerName)
    {
        ComponentOccurrence componentOccurrence = CadAssemblyUtil.FindComponentOccurrence(m_rootDoc, componentName);
        if (componentOccurrence != null)
            return componentOccurrence;
        throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionMsgs.ComponentNotFound, callerName, CadAssemblyUtil.ComponentNameToString(componentName)));
    }

    private int GetExtents()
    {
        ComponentDefinition componentDefinition = CadDocUtil.DocGetComponentDefinition(m_rootDoc);
        if (componentDefinition == null)
            return -1;
        if (componentDefinition.ModelGeometryVersion == m_currentGeomVersion)
            return 0;
        Box rangeBox = componentDefinition.RangeBox;
        Point minPoint = rangeBox.MinPoint;
        Point maxPoint = rangeBox.MaxPoint;
        double value = maxPoint.X - minPoint.X;
        double value2 = maxPoint.Y - minPoint.Y;
        double value3 = maxPoint.Z - minPoint.Z;
        m_currentExtents[0] = m_rootDoc.UnitsOfMeasure.ConvertUnits(value, UnitsTypeEnum.kDatabaseLengthUnits, m_rootDoc.UnitsOfMeasure.LengthUnits);
        m_currentExtents[1] = m_rootDoc.UnitsOfMeasure.ConvertUnits(value2, UnitsTypeEnum.kDatabaseLengthUnits, m_rootDoc.UnitsOfMeasure.LengthUnits);
        m_currentExtents[2] = m_rootDoc.UnitsOfMeasure.ConvertUnits(value3, UnitsTypeEnum.kDatabaseLengthUnits, m_rootDoc.UnitsOfMeasure.LengthUnits);
        m_currentGeomVersion = componentDefinition.ModelGeometryVersion;
        return 0;
    }

    private void ApplicationIsRequired(string callerName)
    {
        if (m_app == null)
            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, ExceptionMsgs.NotInInventorServer, callerName));
    }

    private static string VisibleCallerName(string functionName)
    {
        return "Measure." + functionName;
    }
}

 This is just one of many examples of how beneficial it is to see how Autodesk thinks about doing these things, there are so many little tips and bits of insight to pick out of even just this one class.

 

I don't suggest copy-pasting it into your project, I'm no lawyer, and don't know what the line is as far as what would be considered bad to use or not, even if it is just the decompiler's best guess at what is going on, you probably want to rewrite and refactor anything you use from these outputs. But the real point is to understand how they interact with their own api, what they have seen as ways that calls could fail, what they guard against, what they don't, what they call, etc.