Option Strict Off
Option Explicit On
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Namespace ISOTable
    ' solidifying the interface guid
    <Guid("773DA145-E556-42ea-87E3-3EAD6F72EC8E"), _
        InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
       Public Interface _TABLEPZL
        <DispId(1)> Function PZLFunctionArgs() As Integer
        <DispId(2)> Function PZL(ByRef Feature As Object, ByRef Thickness As Double, ByRef Radius As Double, ByRef SweepAngle As Double, ByRef Material As String, ByRef NF As Double) As Double

    End Interface

    ' solidifying the clsID
    <Guid("885C7D03-24BD-454a-83C1-2146E09ED38C"), ClassInterface(ClassInterfaceType.None), _
    ProgId("TABLE.PZL")> Public Class TABLEPZL
        Implements _TABLEPZL
        '****************************************************************
        '*      PZL OLE Server Class Example for SE-Sheet Metal         *
        '*                                                              *
        '* This example uses a Bend Allowance table to determine the    *
        '* Length of the bend in the flat.                              *
        '*                                                              *
        '* If a table is not defined for the given thickness/radius and *
        '* bend angle then a default formula is used to compute the     *
        '* allowance value                                              *
        '****************************************************************
        Dim m_Tables As New Collection 'Collection of TableDefs.
        'Each TableDef in the collection is a table for specified thickness.
        Dim m_CurrentThickness As Double 'Stores the current thickness of the Sheet Metal Model.
        Dim m_CurrentTable As Object 'Current Thickness table
        'This value may be Nothing if no table defined for the specified thickness

        Public Sub New() 'Called only once when DLL is first loaded by SE-Sheet Metal
            Dim tmpTable As Object

            'Initialize default values
            m_CurrentThickness = 0.0#
            'UPGRADE_NOTE: Object m_CurrentTable may not be destroyed until it is garbage collected. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6E35BFF6-CD74-4B09-9689-3E1A43DF8969"'
            m_CurrentTable = Nothing

            'Create and Load Data into tables
            'Add Entry format Radius(inch), Bend Angle(Degree), Flat Length(inch)
            'Set Length value = -1 to force use of equation if desired
            'NOTE: There are a maximum of 10 entries per thickness table.
            '      Change this limit if desired by editing the TableDef.cls code.

            tmpTable = New TableDef
            'UPGRADE_WARNING: Couldn't resolve default property of object tmpTable.Thickness. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            tmpTable.Thickness = 0.016 'Thickness in inches
            'UPGRADE_WARNING: Couldn't resolve default property of object tmpTable.AddEntry. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            tmpTable.AddEntry(0.031, 90, -1)
            'UPGRADE_WARNING: Couldn't resolve default property of object tmpTable.AddEntry. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            tmpTable.AddEntry(0.047, 90, -1)
            'UPGRADE_WARNING: Couldn't resolve default property of object tmpTable.AddEntry. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            tmpTable.AddEntry(0.062, 90, -1)
            'UPGRADE_WARNING: Couldn't resolve default property of object tmpTable.AddEntry. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            tmpTable.AddEntry(0.094, 90, 0.156)
            m_Tables.Add(tmpTable)

            tmpTable = New TableDef
            tmpTable.Thickness = 0.031
            tmpTable.AddEntry(0.031, 90, -1)
            tmpTable.AddEntry(0.047, 90, 0.091)
            tmpTable.AddEntry(0.062, 90, 0.115)
            tmpTable.AddEntry(0.094, 90, 0.164)
            m_Tables.Add(tmpTable)

            tmpTable = New TableDef
            tmpTable.Thickness = 0.047
            tmpTable.AddEntry(0.031, 90, 0.075)
            tmpTable.AddEntry(0.047, 90, 0.1)
            tmpTable.AddEntry(0.062, 90, 0.124)
            tmpTable.AddEntry(0.094, 90, 0.173)
            m_Tables.Add(tmpTable)

            tmpTable = New TableDef
            tmpTable.Thickness = 0.062
            tmpTable.AddEntry(0.031, 90, 0.083)
            tmpTable.AddEntry(0.047, 90, 0.108)
            tmpTable.AddEntry(0.062, 90, 0.132)
            tmpTable.AddEntry(0.094, 90, 0.181)
            tmpTable.AddEntry(0.1, 90, 0.2)
            m_Tables.Add(tmpTable)

            tmpTable = New TableDef
            tmpTable.Thickness = 0.078
            tmpTable.AddEntry(0.031, 90, 0.092)
            tmpTable.AddEntry(0.047, 90, 0.17)
            tmpTable.AddEntry(0.062, 90, 0.141)
            tmpTable.AddEntry(0.094, 90, 0.19)
            m_Tables.Add(tmpTable)

            tmpTable = New TableDef
            tmpTable.Thickness = 0.094
            tmpTable.AddEntry(0.031, 90, 0.101)
            tmpTable.AddEntry(0.047, 90, 0.126)
            tmpTable.AddEntry(0.062, 90, 0.15)
            tmpTable.AddEntry(0.094, 90, 0.199)
            m_Tables.Add(tmpTable)

            tmpTable = Nothing
        End Sub

        Protected Overrides Sub Finalize()
            'Called only once when DLL is unloaded by SE-Sheet Metal
            'Delete TableDef objects in m_Tables
            Do While m_Tables.Count() > 0
                m_Tables.Remove(1)
            Loop

            m_CurrentTable = Nothing
        End Sub

        Public Function PZLFunctionArgs() As Integer Implements _TABLEPZL.PZLFunctionArgs
            PZLFunctionArgs = 0
        End Function


        Public Function PZL(ByRef Feature As Object, ByRef Thickness As Double, ByRef Radius As Double, ByRef SweepAngle As Double, ByRef Material As String, ByRef NF As Double) As Double Implements _TABLEPZL.PZL
            'This Function is called by SE-Sheet Metal whenever the PZL value is needed

            'The function arguments and units are defined as follows:
            'Feature - The SE-Sheet Metal feature that is being created/updated or flattened.
            'Thickness- Material thickness in meters. Defined in tools options
            'Radius- Bend radius in meters. Defined by the feature.
            'Angle- Sweep angle of the bend in radians. Defined by the feature
            'NF- Neutral factor value (No units). Define in tools options and on the feature.
            'PZL - Return value of this function. Must be in meters.
            '      NOTE: The PZL value that you return to SE-Sheet Metal must be >= 0.000

            Dim k As Double 'Compensation factor used in default formula.
            Dim R As Double 'Bend Radius in inches
            Dim A As Double 'Bend Sweep angle in degrees
            Dim thk As Double 'Material thickness in inches
            Dim TableValue As Double 'Return value from tabledef lookup

            Dim dErrFix As Double

            'Fix for division error bug when calling program from C++
            On Error Resume Next
            dErrFix = 1.0# / 2.0#

            On Error GoTo Handle_Error


            'Convert input values to inch and degrees using conversion functions (See modmain.bas)
            R = MtoI(Radius)
            thk = MtoI(Thickness)
            A = RtoD(SweepAngle)

            If m_CurrentThickness <> thk Then
                'Set the m_CurrentTable for the specified thickness
                'Note: If no table exists for the thickness we will use default formula
                SetCurrentTable(thk)
            End If

            If TypeName(m_CurrentTable) <> "Nothing" Then
                'Lookup the value if we have a table for this thickness
                'Note: If no entry exists for the given R and A value then -1 is returned and
                '      we will use default formula
                TableValue = m_CurrentTable.GetValueFromTable(R, A)
            Else
                TableValue = -1
            End If

            If TableValue >= 0 Then
                'The value from the table is valid, use it
                PZL = ItoM(TableValue)
                Exit Function
            End If

            'No match in tables or no table for the specified thickness
            'Use the default formula. The one below is for example purposes only
            'Compute correction factor
            If R <= 0.0005 Then 'Check for Zero bend radius.
                'The factor below is for example purposes only. Modify the value or formula
                'as needed to support your required values for zero bend radii.
                k = 1
            ElseIf (Radius / Thickness) > 5 Then
                k = 1
            Else
                k = 0.65 + 0.5 * System.Math.Log(R / m_CurrentThickness) / System.Math.Log(10)
            End If

            PZL = ItoM((R + m_CurrentThickness * k / 2) * PI * A / 180)

            Exit Function

Handle_Error:
            Err.Clear()
            PZL = (Radius + Thickness * 0.33) * SweepAngle

        End Function

        '******************************************************************************
        Private Sub SetCurrentTable(ByRef thk As Double)
            'Select the table using the thickness
            Dim ii As Short

            m_CurrentThickness = thk

            ii = 1
            Do While ii <= m_Tables.Count()
                If m_Tables.Item(ii).ThicknessMatch(m_CurrentThickness) Then
                    'We have a table for the specified thickness, set it to m_CurrentTable
                    m_CurrentTable = m_Tables.Item(ii)
                    Exit Sub
                End If
                ii = ii + 1
            Loop

            'If we reach this point then there it not a table defined for the specified thickness.
            'We will use the default formula to calculate the flat length of the bend. (PZL)
            m_CurrentTable = Nothing
        End Sub
#Region "REGISTRATION"

        ' Code to register/unregister the additional add-in data was derived from Jason Newell (jasonnewell.net)

        ' When Regasm is run on this project, either through IDE or command window, these functions will be called.

        ' Setup the required Solid Edge registry values for an addin that were not automatically
        ' added due to the guid, progid and com visible attributes.
        <ComRegisterFunctionAttribute()> _
        Public Shared Sub RegisterFunction(ByVal t As Type)

            Dim Key As RegistryKey = Registry.ClassesRoot.CreateSubKey("CLSID\{" + t.GUID.ToString() + "}")
            '   {40FC6ED5-2438-11CF-A3DB-080036F12502} = automation object
            If Not (Key Is Nothing) Then
                Key.CreateSubKey("Implemented Categories\" & "{40FC6ED5-2438-11CF-A3DB-080036F12502}")
                Key.Close()
            End If
        End Sub

        ' Remove any registry values specifically added above.
        <ComUnregisterFunctionAttribute()> _
        Public Shared Sub UnregisterFunction(ByVal t As Type)
            Registry.ClassesRoot.DeleteSubKeyTree("CLSID\{" + t.GUID.ToString() + "}")
        End Sub
#End Region

    End Class
End Namespace
