Sunteți pe pagina 1din 104

IronCAD Customization

Microsoft Visual Basic 6.0, IronCAD 2.0 and Accompanying Source Code Required.

Version 1.01
Documentation By: Brandon Cole IronCAD, LLC, 1999
Unauthorized duplication strictly prohibited.

IronCAD Customization: Table Of Contents

Table of Contents
I: Introduction
1. Vision 2. Pre-Requisites Pg. 3 Pg. 3

II: Visual Basic Objects


1. 2. 3. 4. 5. Introduction Using Classes In Visual Basic Accessing Classes In Visual Basic From The Type Library Accessing Classes In Visual Basic Using CreateObject() Final Notes Pg. Pg. Pg. Pg. Pg. 4 4 10 12 14

III: IronCAD Automation Data Model


1. Introduction 2. IronCAD Basics 3. IronCAD Shape And Component Architecture Pg. 16 Pg. 16 Pg. 29

IV: IronCAD Shape Creation


1. 2. 3. 4. 5. 6. 7. Introduction Profile Creation Extrude Shapes Spin Shapes Sweep Shapes Loft Shapes Complex Shapes Pg. Pg. Pg. Pg. Pg. Pg. Pg. 39 39 47 52 54 56 62

V: IronCAD Add-Ons
1. Introduction 2. Creating Catalog Entries 3. Handling Shape Events Pg. 64 Pg. 64 Pg. 67

VI: IronCAD Sheet Metal Architecture


1. 2. 3. 4. Introduction Tooling File Punch Shapes Forming Shapes Pg. Pg. Pg. Pg. 71 71 71 82

VII: IronCAD BOM Customization


1. 2. 3. 4. Introduction Creating Custom BOM Export Creating Custom BOM Columns Advanced Custom BOM Columns Using Shape Properties Pg. Pg. Pg. Pg. 95 95 97 98

VIII: IronCAD Utilities Reference


1. 2. 3. 4. Introduction IronCAD Tool Utilities IronCAD Tool Expression Server IronCAD Tool Selection Helper Pg. Pg. Pg. Pg. 101 102 102 103

Page 2 of 104

IronCAD Customization: Introduction

Introduction
Vision
Imagine for a moment that there is a company that specializes in the production of fasteners. The company manufactures several types of bolts, screws and washers and other miscellaneous items. In an attempt to ease the way the company does business they hire a software engineer for a couple of weeks to meticulously program a tool that clients can use if they have IronCAD . Once the tool is completed, the tool, along with installation instructions are placed on the company web page for customers to download. Customers can now download the tool and use it in the creation of their designs. When production time comes for the customer, a utility that the company delivered with their tool can be used to create a list of the parts that need to be ordered from the company including part numbers, prices and quantities. With the list of materials created, it can then be E-mailed or faxed to the company for ordering. This concept is possible right now using IronCADs automation system and it can be used for any type of part not just fasteners. As the tools have shown in the past, the automation system in IronCAD makes a wide variety of things possible Gears, Bearings, Hot Formed and Cold Formed Steel. In fact the only limit is programmers ability to accurately define the geometry of the part. This document will cover the basics of IronCADs shape and component architecture as well as covering previously unreleased information concerning the Sheet Metal architecture so that custom forming and punch shapes can be programmed to meet the needs of customers.

Pre-Requisites
Programming experience is definitely necessary. The ability to create simple programs in Microsoft Visual Basic 5.0 or 6.0 is required. Since this document is intended for a wide variety of audiences, Type Libraries and Visual Basic classes are discussed in the next section to assure that there is a common starting point for the audience. Knowledge of the Windows Registry and Class IDs will also be helpful to the reader. Lastly, good geometry and math skills will be required and prove useful. There is an exit here.

Page 3 of 104

IronCAD Customization: Visual Basic Objects

Visual Basic Objects


Introduction
Objects, commonly referred to as classes allow the programmer to develop their own data types. The ability to do so makes a programming language an Object Oriented Programming (OOP) Language. Object Oriented Programming Languages (C++, Visual Basic, Java) for this reason can also be more complicated to understand compared to script languages such as LISP, which is why it is important that a firm understanding of the way objects work in Visual Basic before going further. Key points in this section will be: Using classes In Visual Basic Accessing Classes In Visual Basic From The Type Library Accessing Classes In Visual Basic Using CreateObject() If a firm understanding of these key points is already known then continue to the next section.

Using Classes In Visual Basic


This part refers to the project Box.vbp in the Example 1 directory in the accompanying source code. Before continuing please open this project in Microsoft Visual Basic.

To get used to using math since a lot more will be needed later on, classes in Visual Basic will be demonstrated through a class called CBox. Inside of the project Box.vbp, there is a file called CBox.cls which is the class. The way Microsoft Visual Basic classes work is that every class needs its own file. This is very different from the way C++ for instance does classes, where several classes can be in a single file, however there are several benefits that come with the way Visual Basic does classes which will present themselves later on. The class CBox is a class that helps calculate properties of a box such as volume and surface area when the dimensions of the box are specified. Before going further, examine the properties and methods that CBox provides by looking at the Object Browser by either selecting Object Browser from the View menu, or clicking the toolbar button if it is available. Once inside the Object Browser, click on the top combo box and select Box. By selecting Box, the Object Browser will now display all classes inside of the project Box.vbp as well as the methods, properties and constants defined within the project. In the view pane on the left Page 4 of 104

IronCAD Customization: Visual Basic Objects side there should be four items: <globals>, CBox, frmProperties and Startup. From the left side select CBox so the properties and methods of the class CBox can be seen on the right side. By looking in the Object Browser the 3 methods: SetDimensions, GetDimensions, and DisplayProperties, along with the 5 properties : Length, Width, Height, Volume and SurfaceArea of CBox can be seen. There is also one more property listed in the Object Browser: m_dDimensions, which is not actually a property of CBox, instead it is a private member variable but since the project is open, m_dDimensions is shown in the Object Browser. Later when this project is referenced by another project, m_dDimensions will not be shown in the Object Browser since it is a private member variable of CBox. Select the property Volume and then select the property SurfaceArea. In the bottom pane of the Object Browser, both these properties are listed as readonly properties meaning both the volume and surface area can not explicitly be set by the user of this class. The logical reason for this is that both volume and surface area are dependent on the length, width and height of the box. If the volume or surface area is specified then the length, width and height can be infinitely many combinations to satisfy the specified volume or surface area, so these properties can not be set, only read. To understand the way this is specified in Visual Basic, take a look first at the code that defines the property Volume along with the definition of the variable m_dDimensions :
Private m_dDimensions(1 To 3) As Double Public Property Get Volume() As Double Volume = (m_dDimensions(1) * m_dDimensions(2) * m_dDimensions(3)) End Property

The variable m_dDimensions is an array with 3 places to hold the length, width and height of the box respectively. In the definition of the Volume property for the box, the 3 dimensions of the box are multiplied together and returned as a double. The reason the Volume property can not be set however is because there would have to be another specification of the property using the keywords Property Let along with the existing definition of the property. For instance, the Length, Width and Height properties of CBox are capable of being set and read, so take a look at the differences between the code defining the Length property and the code defining the Volume property. If the code to the Length property is Page 5 of 104

IronCAD Customization: Visual Basic Objects examined, there is an extra piece of code that does not exist for the Volume property, which is the part utilizing the keywords Property Let. This extra piece of code allows the Length property to be set by the user of the class, along with being read.
Public Property Get Length() As Double Length = m_dDimensions(1) End Property Public Property Let Length(Distance As Double) m_dDimensions(1) = Distance End Property

The definition for setting the Length property takes a parameter called Distance, which is a double. This variable will be filled with the value that this property is being set to. Take a look at the code segment below:
Dim cDemoBox As CBox Set cDemoBox = New CBox cDemoBox.Length = 5.5 Set cDemoBox = Nothing

The Let definition of the Length property will be used and the variable Distance will be filled with the value 5.5. If a property of a class is an object, which can be anything declared as the Object variable type or a user defined class, then instead of using the Let keyword, the Set keyword should be used. This makes the user of the class to use the keyword Set when setting the property, which is consistent with the way objects are assigned in Visual Basic . A property of a class may also be referenced by the class which the property belongs to. Take for instance the original definition of the Volume property below:
Public Property Get Volume() As Double Volume = (m_dDimensions(1) * m_dDimensions(2) * m_dDimensions(3)) End Property

The definition could be rewritten as:


Public Property Get Volume() As Double Volume = (Length * Width * Height)

Page 6 of 104

IronCAD Customization: Visual Basic Objects


End Property

The reason this is possible is because the Length, Width and Height properties are properties of CBox, which is the class that is referencing them. For the same reason a class can also call its own methods. However be careful when calling properties on a class from within the class because if there were private variables defined in the class to be Length, Width and Height, then the properties would not be called, instead the private variables would be referenced. To solve this, the definition could be rewritten again as the following:
Public Property Get Volume() As Double Volume = (Me.Length * Me.Width * Me.Height) End Property

In the definition above, the keyword Me is a Visual Basic keyword that is a pointer to the class that it is used in. Keep in mind that classes are user defined variables, so Me is a variable that points to the class that the variable is used in. That covers mostly everything that needs to be known right now concerning properties of Visual Basic classes. Methods on classes work in the same way that methods in modules or forms work. If the method is declared as Public, then the user of the class will be able to call the method, however if the method is declared as Private then users of the class will not be able to call the method. This is also true for any variables of the class. Now take a look at the project properties by selecting Box Properties from the Project menu. Once inside the Project Properties dialog, notice that the Startup Object is set to Sub Main. This means

that when the program is run, instead of loading the dialog, the subroutine Main inside of the Startup.bas module will be called. Also note that the project type is a Standard EXE right now, meaning that when the project is compiled the result will be an executable file that a user could run by double clicking. This is fine for the time being, but in the next part the project type will be changed to ActiveX DLL so that the class CBox can be used outside of this project.

Page 7 of 104

IronCAD Customization: Visual Basic Objects To begin understanding how to interact with Visual Basic objects, take a look at the code inside of the public subroutine Main inside of Startup.bas for a moment. For the purposes of demonstrating classes, assume that there is a shoe box whos dimensions are known and the volume and surface area need to be displayed.
Public Sub Main() 1 2 3 4 5 6 7 8 9 10 11 12 13 Dim cShoeBox As CBox 'Create a new instance of CBox... Set cShoeBox = New CBox 'Set the dimensions of the shoebox... cShoeBox.SetDimensions 1.25, 2.5, 5 'Now display all the properties of the shoebox... cShoeBox.DisplayProperties 'Release the CBox... Set cShoeBox = Nothing

End Sub

The first thing that is done is a new variable cShoeBox is declared (line 1) as type CBox, which the class defined in the file CBox.cls. However declaring the variable does not mean the variable can be used yet, in fact the variable is not able to be used until after it has been initialized (line 4). Until this point the variable is a NULL pointer, meaning it is nothing. For those familiar with C++, if CBox was a simple C++ class, the equivalent declaration in C++ for line 1 would be: CBox* cShoeBox ; And then the equivalent to line 4 in C++ would be: cShoeBox = new CBox ; Until line 4 executes, this variable can not be used. The dimensions of the shoebox are then set by calling the SetDimensions method on the variable cShoeBox. Instead of using this method, the properties Length, Width and Height could also be used to set the dimensions of the shoe box by replacing line 7 with the following three lines of code:
cShoeBox.Length = 1.25 cShoeBox.Width = 2.5 cShoebox.Height = 5

Page 8 of 104

IronCAD Customization: Visual Basic Objects The first method is generally preferred since there is less code to write, however both ways would yield the same result. Next, the properties of the shoebox are displayed by calling DisplayProperties. All of the properties: Length, Width, Height, Volume and SurfaceArea are displayed by creating an instance of the dialog, much like an instance of CBox was created. To understand what is happening exactly, take a look at the code in DisplayProperties method inside the CBox.cls file:
Public Sub DisplayProperties() 1 2 3 4 5 6 7 8 9 10 11 12 13 Dim dlgProperties As frmProperties 'Create a new instance of the dialog... Set dlgProperties = New frmProperties 'Initialize the values on the form from the data in this class... dlgProperties.InitializeBoxValues Me 'Display the form... dlgProperties.Show vbModal 'Release the form... Set dlgProperties = Nothing

End Sub

First a new variable dlgProperties is declared much like the variable cShoeBox was declared in the subroutine Main. And then, once again the keyword New is used to create a new instance of the variable. Dialogs in Visual Basic are classes just like user defined classes and when they are being used as variables, new instances of the dialogs must be created exactly in the same way new instances of user defined classes such as CBox needed to be created earlier. On line 7, the method InitializeBoxValues defined in the dialog frmProperties.frm is called. This method is passed in a pointer to the instance of this class since the keyword Me is used. Take a look at the source code for the method InitializeboxValues:
Public Sub InitializeBoxValues(Box As CBox) 'First set the dimensions on the form... Me.lblDimensions(0).Caption = Box.Length Me.lblDimensions(1).Caption = Box.Width Me.lblDimensions(2).Caption = Box.Height 'Now set the areas... Me.lblAreas(0).Caption = Box.Volume Me.lblAreas(1).Caption = Box.SurfaceArea End Sub

Page 9 of 104

IronCAD Customization: Visual Basic Objects The method InitializeBoxValues takes one parameter, which is of type CBox, which is the user defined class defined in CBox.cls. Since the keyword Me was used for this variable inside of the DisplayProperties method, then the variable Box at this point is the same as the variable cShoeBox inside of the subroutine Main in Startup.bas. The label captions on the form are set to the properties of the shoebox, then the properties dialog is shown on line 10 inside of the method DisplayProperties. Once the user hits the <OK> button, the variable dlgProperties is set to Nothing on line 13 inside of DisplayProperties, and code execution returns to the subroutine Main inside of Startup.bas where the variable cShoeBox is set to Nothing as well. It is important when using the keyword New, to set the variable initialized by the keyword to Nothing when the variable is not needed any more. Although it is not mandatory to do so, it is a good practice and prevents problems from occurring later. When the program is run, the properties of the shoebox are displayed successfully in the dialog and when the <OK> button is clicked the program exits normally.

This concludes the part on creating and using classes in Visual Basic. The next two parts will discuss accessing the class CBox from another project using two methods, first by referencing the project Box.vbp in the Type Library and secondly by using the Visual Basic method CreateObject().

Accessing Classes In Visual Basic From The Type Library


This part refers to the project Box.vbp in the Example 1 directory, as well as the project ShoeBox1.vbp in the Example 2 directory. Both projects can be found in the accompanying source code.

Since there is a good understanding of how the class CBox works, discussed in the previous part, CBox will be the class used to demonstrate using classes from the Type Library. But before CBox can be used in another project, the project Box.vbp needs to be compiled into an ActiveX DLL. To do this first open Box.vbp and go to the project properties for Box.vbp as described Page 10 of 104

IronCAD Customization: Visual Basic Objects previously. First set the Project Type to ActiveX DLL from Standard EXE and then set the Startup Object to (none) from Sub Main. Next, in the Project Description field type CBox IronCAD Customization Tutorial if it has not already been entered. When finished click the <OK> button and a dialog like the one shown at right will appear and just click <OK>. Next the class CBox will need to be changed to a public class so that it can be accessed from another project. In the project browser, select CBox.cls so that the properties for the class are displayed in the pane below the project browser. If the properties of the class are not being displayed, then select Properties Window from the View menu or press F4. Next change the Instancing property of the class from 1 Private to 5 Multiuse so that the class is able to be accessed outside of the project. Once this is completed compile the project into a DLL by selecting Make Box.dll from the File menu. The name of the DLL does not make a difference but it would be a good idea to compile the DLL into a temporary directory instead of the default directory. Once the DLL has been successfully compiled then continue on. Next open the project ShoeBox1.vbp. If an attempt to run the project is made now, it will be unsuccessful because the variable cShoeBox in the Click event of the command button cmdDisplay is declared as type CBox which is the class that was defined in Box.vbp. Before the project can be run, the compiled DLL from the previous project must be referenced first. To reference the project that contains the CBox class, select References from the Project menu, or click the toolbar button if available. Once the References dialog is opened for the project, scroll down the list of available entries until the entry CBox IronCAD Customization Tutorial is found, then place a check mark in the box to the left of the entry to select it. When finished click <OK>. Now the class CBox is able to be used in ShoeBox1.vbp even though the source code for CBox is in a DLL outside of the project. Open the Object Browser inside of ShoeBox1.vbp now and select Box again from the drop down list to

Page 11 of 104

IronCAD Customization: Visual Basic Objects view the classes exposed. There is a big difference between what was seen before when inside of Box.vbp and what is displayed now when they are compared. Only the class CBox is displayed now and frmProperties along with Startup can no longer be seen in the Object Browser. The property m_dDimensions is also not shown as a property of CBox now since it was a private member variable of the class CBox. Now that the project that contains CBox has been referenced, it is possible to run ShoeBox1.vbp successfully. Run the project and type the values 1.25, 2.5, and 5.0 into the Length, Width and Height fields respectively, when finished click <Display>. Once again the dialog that appeared before inside the Box.vbp project appears when running ShoeBox1.vbp confirming that everything is working correctly. The code inside of the Click event for the command button cmdDisplay should look familiar. The code for using the class CBox is exactly the same and nothing has changed, except that instead of always using 1.25, 2.5 and 5.0 for the shoebox dimensions, the values are read from the dialog frmMain and then set.

Accessing Classes In Visual Basic Using CreateObject()


This part refers to the project Box.vbp in the Example 1 directory, as well as the project ShoeBox2.vbp in the Example 3 directory. Both projects can be found in the accompanying source code. If the project Box.vbp has not been compiled into a DLL, then please refer to the first part of Accessing Classes In Visual Basic From The Type Library for detailed instructions before continuing.

In the previous part, the class CBox was used because after referencing the project Box.vbp. However in the project ShoeBox2.vbp nothing will be referenced other than the default references that Visual Basic requires. Instead, an instance of the CBox class will be created without the keyword New, instead using the Visual Basic function CreateObject(). Before continuing further open the Windows Registry Editor by typing regedit at either the MS-DOS prompt, or by selecting Run from the Windows Start menu. Once inside of Page 12 of 104

IronCAD Customization: Visual Basic Objects the Registry Editor, double-click on the node HKEY_CLASSES_ROOT to expand the tree underneath it. Scroll down the list until the entry Box.CBox becomes visible. This entry is the unique entry for the class CBox. When a class is created in a Visual Basic ActiveX DLL or ActiveX EXE and the Instancing property of the class is marked as either 2 PublicNotCreatable, 5 MultiUse or 6 GlobalMultiUse a registry entry is made with the format < Project Name>.<Class Name>, often referred to as the ProgramID. For instance, the project was named Box and the class name was CBox, so when the project was compiled into a DLL the resulting registry entry Box.CBox was created. Do not confuse the project and class name with the project filename and class filename since it is not the filenames that the registry entry is dependent on, it is the name of the project and class specified inside of Visual Basic. When the entry Box.CBox is found underneath HKEY_CLASSES_ROOT, doubleclick Box.CBox to expand the tree underneath Box.CBox and another key titled Clsid should be visible as shown. Next click on the key Clsid and in the right pane there will be one string value stored in the key Clsid which is titled

(Default). This value is the ClassID of the class CBox. The value shown here will NOT be the same value shown on another computer unless the DLL that was compiled on one machine is placed on another computer and registered. The ClassID of a class is a globally unique identifier (GUID) meaning that no other class on the computer will have the same ClassID. Later on in this document when the ClassID of a class is referred to, this is what is meant by it. Now that an understanding of what role the registry plays in Visual Basic classes, examine the source code in the Click event of the command button cmdDisplay in ShoeBox2.vbp below:
Private Sub cmdDisplay_Click()

Page 13 of 104

IronCAD Customization: Visual Basic Objects


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Dim cShoeBox As Object Dim dLength As Double, dWidth As Double, dHeight As Double 'Get the dimensions from the form... dLength = CDbl(Me.txtLength.Text) dWidth = CDbl(Me.txtWidth.Text) dHeight = CDbl(Me.txtHeight.Text) 'Create a new instance of the box and set the dimensions... Set cShoeBox = CreateObject("Box.CBox") cShoeBox.SetDimensions dLength, dWidth, dHeight 'Display the box properties... cShoeBox.DisplayProperties 'Release the box... Set cShoeBox = Nothing

End Sub

The first change to note is that the variable cShoeBox is no longer declared as the variable type CBox, instead it is declared as variable type Object. The reason the variable cShoeBox is not declared as type CBox is because since the project which contains the definition for CBox is not referenced, variables can not be declared as type CBox since Visual Basic has no knowledge of CBox. Since the project which contains CBox is not referenced, there is also no way to see the methods and properties for cShoeBox now, so they must be known by the programmer. The next change is on line 10, instead of creating a new instance of the class using the New keyword, the CreateObject() method is used and the registry location of the class is passed into the method. Visual Basic will then create an instance of the class and on the next line the variable cShoeBox will be an instance of the CBox class. The rest of the code is similar to the preceding 2 parts, including setting the variable cShoeBox to Nothing at the end when the variable is no longer needed. Once again, run the project ShoeBox2.vbp and specify the Length, Width and Height to confirm that things are working correctly.

Final Notes
It is very important that there is a firm understanding of the concepts discussed in this section before continuing further. These basic concepts will be the groundwork that is built on in the sections to come. If something is not completely understood or clear, please take the time to read through the section again before continuing so that the following sections will be easier to understand. The importance of being able to understand Object Oriented Programming and the interaction between Visual Basic classes with the Windows Registry will be critical in the following sections. Page 14 of 104

IronCAD Customization: Visual Basic Objects

This is also the conclusion of discussing general Visual Basic concepts. The remaining sections focus strongly on the IronCAD Automation data model. More advanced topics involving IronCADs shape events and the Sheet Metal data model will follow as well. The time has come for better things.

Page 15 of 104

IronCAD Customization: IronCAD Automation Data Model

IronCAD Automation Data Model


Introduction
The automation data model for IronCAD is large and complex, along with having many small intricacies to it. This section will introduce the data model starting with the IronCAD scene and discussing how to get the active scene and catalogs in the first part IronCAD Basics. Then the more complicated shape and component architecture will be discussed in IronCAD Shape And Component Architecture, where the fundamentals of dealing with shapes and their components such as position, sizebox and profiles to list a few are discussed. Ultimately, the goal for this section is to be prepared for the next section IronCAD Shape Creation, which thoroughly discusses the steps needed to create shapes in IronCAD. The IronCAD Type Library may be referenced in a Visual Basic project by selecting IronCAD 3.0 Object Library from the available list of references.

IronCAD Basics
This part refers to the project Basics1.vbp in the Example 4 directory in the accompanying source code.

Automation in IronCAD always begins with knowing one of the following three objects: Application The base object from which most others can be attained. BOMTable A BOM table, attainable only by a direct call from IronCAD. Shape Shape in IronCAD, attainable by direct call and other ways.

The BOMTable object as mentioned above may only be attained right now by a direct call from IronCAD to an object specified by its Program ID and a method to invoke on the object. The BOMTable object is discussed in detail in section VII IronCAD BOM Customization. The Shape object represents any shape in IronCAD despite the shape type. This means that extrude shapes are represented by the Shape object, as well as loft shapes, parts, assemblies and imported shapes. Unlike the BOMTable object, the Shape object is attainable in several ways ranging from direct calls by IronCAD to an object specified by a Class ID and a method to invoke, or by getting a scene and traversing the shape tree. The main topic of this part is the Application object, focussing on how to access it, what other objects can be obtained from it and what can be done when starting from the Application object.

Page 16 of 104

IronCAD Customization: IronCAD Automation Data Model Accessing the Application object can generally be done in two ways, the first is using the Visual Basic functions GetObject() and CreateObject(). The other way to get the Application object is by setting up an Add-on tool on the Tools menu in IronCAD. Since the former should be somewhat familiar, it will be discussed first. The IronCAD Type Library has a module called Constants, inside of which is a constant called triApp. This constant is simply a string with the value IronCAD.Application, which is the Program ID for the IronCAD application. Just like the Visual Basic function CreateObject() was used to create an instance of the CBox object in the previous section, the function can also be used to create an instance of the IronCAD Application object. The example code below creates an instance of the Application object in the IronCAD Type Library, which also starts IronCAD:
1 2 3 4 Dim objApplication As Object Create an instance of the IronCAD application object: Set objApplication = CreateObject(triApp) objApplication.Visible = True

Since the IronCAD application is started in line 3, the line may take a second to execute. When execution of line 3 is finished, the application has been started but a user will not be able to see it until line 4 is executed and sets the Visible property of the Application object to True. To see what properties and methods are available on the Application object, look inside of the IronCAD Type Library (shown at left) at the Application object. The Visible property is second to last at the bottom of the column on the right. There are several other properties on the Application object such as DialogPrecision which allows the number of decimal places displayed in dialogs to be set and read, DimensionPrecision which is identical to DialogPrecision, only it is used for the decimal precision for dimensions. The Units property allows the default units for a scene to be set and read. The Pages and Catalogs properties return Page 17 of 104

IronCAD Customization: IronCAD Automation Data Model enumerations of scenes and catalogs. Getting back to the example code above however, it is not very useful if a user already has a scene open in IronCAD and a tool that will export an image of the active scene needs to be created. For this particular case what really needs to happen is that the Application object for the current instance of IronCAD is set. To get the Application object for the current instance of IronCAD the GetObject() function needs to be used instead of the CreateObject() function:
1 2 3 Dim objApplication As Object Create an instance of the IronCAD application object: Set objApplication = GetObject(, triApp)

In the example above there is no need to set the Visible property since the user currently be using the application so it should be visible. However the GetObject() function has a few pitfalls. First is that it will return the Application object for the first copy of IronCAD that was started. For example, if a user has two copies of IronCAD running, it will return the Application object for the first copy of IronCAD that was started. The other pitfall is that if there is no copy of IronCAD running, instead of just returning Nothing, the function also raises an error. The way that the GetObject() function is mostly used is to try and get the current running copy of IronCAD and if there isnt a copy of IronCAD running then start IronCAD. The code segment below shows how to get the current copy of IronCAD or start a new copy:
1 2 3 4 5 6 7 8 9 10 Dim objApplication As Object Turn error handling on and try to get the current copy of IronCAD On Error Resume Next Set objApplication = GetObject(, triApp) If there was an error or the application has not been set create one If((Err.Number <> 0) Or (objApplication Is Nothing)) Then Set objApplication = CreateObject(triApp) End If Turn off error handling On Error Goto 0

That is the way to get an application for sure, although it still doesnt solve the problem completely of getting the application the user is using even though GetObject() is being used. If the user is working in the second copy of IronCAD they started then the correct application object will not be set. The way to solve this is to use the last way of getting the Application object by adding an Add-on tool to the Tools menu in IronCAD. Adding an Add-On tool to the Tools menu in IronCAD is very simple and solves all of the problems above. Add-On tools work very similarly to the way that an instance of the IronCAD Application object is created above. Basically a Page 18 of 104

IronCAD Customization: IronCAD Automation Data Model Class ID of an object that needs to be created is specified along with the name of a subroutine or function to call on the object. Inside of the project Basics1.vbp there is a class called AppProperties which only has one subroutine called DisplayProperties defined below:
Public Sub DisplayProperties(Application As Object) 1 2 3 4 5 6 7 8 9 10 Dim cFormProperties As frmProperties 'Create a new instance of the form : Set cFormProperties = New frmProperties 'Just display simple properties of the application object : cFormProperties.lblDimension(0).Caption = Application.Width cFormProperties.lblDimension(1).Caption = Application.Height cFormProperties.lblPrecision(0).Caption = Application.DialogPrecision cFormProperties.lblPrecision(1).Caption = _ Application.DimensionPrecision 'Release the form : Set cFormProperties = Nothing

End Sub

The subroutine takes only takes one parameter which is an object. When creating Add-On tools to add to the Tools menu in IronCAD, the object must have one method that supports this function prototype. When IronCAD invokes the method, the value passed in will be the Application object in the IronCAD Type Library of the current instance of the IronCAD application. Compile the project Basics1.vbp into a DLL with any name desired since the filename of the compiled DLL does not matter. At this point the object AppProperties will be considered a tool since it is an object that IronCAD can create an instance of and use, so now it needs to be added to the Tools menu in IronCAD. To add the tool to the Tools menu in IronCAD select Tools | Add-on Tools and then the Add On Tools dialog should appear. Click Add and a dialog will appear to add a tool. The dialog will have the types listed Ole Object, Executable and Function Exported from a DLL. The one that pertains to this case is Ole Object which should be the default selection. In the object field type Basics1.AppProperties which is the Program ID of the class. Next click the combo box in the Method field and after a brief pause it will list all of the public functions in the object AppProperties. Once the list is displayed which should consist of one item, select DisplayProperties which is the function whose code appears above. Keep in mind Page 19 of 104

IronCAD Customization: IronCAD Automation Data Model that all public functions are listed in the combo box even functions that have different prototypes than the one listed above. If a function is selected that has a different prototype than just an object, then IronCAD will fail to execute the tool and will display an error message. When finished click OK to go back to the main Add On Tools dialog. Specify the desired menu text for the tool, for the purposes of demonstration the menu text has been set to Application Properties. When finished specifying the desired menu text click OK to close the dialog. Now the tool Application Properties should appear on the Tools menu in IronCAD and when the menu item is selected the tool will be executed and display the decimal precision for the dialogs and dimensions, along with the width and height of the IronCAD application window. Not too many users would jump at the opportunity to have this addition to the Tools menu, after all it is hard to remember the last time the size of the application window or precision of the dialogs had to be known to model a part. However what this addition to the Tools menu does do is allow the correct Application object to be accessed, independent of the number IronCAD applications open which was the original problem. The Application object by itself however is not much fun to play with unless changing the precision of dialogs and dimensions is considered entertainment. Other than the Application object there are 80 more objects in the IronCAD type library to play with, so next the Catalogs object will be discussed. On the Application object, there is a Catalogs property that returns the Catalogs object in the IronCAD Type Library. The Catalogs object is nothing more than an array of Catalog objects, often referred to as an enumeration. The Catalogs object enables new catalogs to be added, existing catalogs to be opened, and opened catalogs to be saved and closed. Inside of the Basics1.vbp project there is another class called AppCatalogs which has a function called AddCatalog for which the code is below:
Public Sub AddCatalog(Application As Object) 1 2 3 4 5 Dim objCatalogs As Object 'Get the enumeration of catalogs : Set objCatalogs = Application.Catalogs 'Add a new catalog : objCatalogs.Add

Page 20 of 104

IronCAD Customization: IronCAD Automation Data Model


End Sub

The code is relatively simple. On the first line a new variable called objCatalogs is declared that will be set on line 3 to the enumeration of catalogs in IronCAD , therefor at the end of code execution on line number 3, objCatalogs is the Catalogs object in the IronCAD Type Library. The previous code example simply adds a new catalog to the catalogs in IronCAD , however the code sample below from the AppCatalogs class in Basics1.vbp opens an existing catalog:
Public Sub AddExistingCatalog(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Dim Dim Dim Dim szName As String frmOpen As frmFile objCatalog As Object objCatalogs As Object

'Get the enumeration of catalogs : Set objCatalogs = Application.Catalogs 'Set up the open dialog : Set frmOpen = New frmFile frmOpen.DefaultExt = ".icc" frmOpen.Filter = "IronCAD Catalogs (*.icc)|*.icc" 'Display the open dialog, and if a file name was specified continue : If (frmOpen.ShowOpen(szName)) Then 'Open the catalog with the specified filename and set it to 'be the active catalog : Set objCatalog = objCatalogs.Add(szName) objCatalog.MakeActive End If 'Release the open dialog : Set frmOpen = Nothing

End Sub

As far as IronCAD automation is concerned, the code in this example is identical to the first set of example code, except on line 15 a filename is passed to the Add method on the Catalogs object and the catalog that was added is returned as a Catalog object. On line 16 the catalog that was added is set to be the active catalog. The rest of the code is there to obtain the name of the catalog to open from the user. On line 2 the variable frmOpen is declared as a frmFile object which is in the project as well, however it is just a simple dialog that is used to get the filename from the user so it wont be discussed. There are a total of 9 properties and methods on the Catalog object, only the MakeActive method was used here but the majority of them are self explanatory except for the Entries property which returns a CatalogEntries object in the IronCAD Type Library.

Page 21 of 104

IronCAD Customization: IronCAD Automation Data Model The CatalogEntries object is very similar to the Catalogs object in the sense that it is an enumeration of the entries in the catalog. Objects that are an enumeration of other objects are very easy to identify because they will almost always have the 3 methods : Add, Item and Remove, along with the property Count which is the number of objects in the enumeration. The enumeration objects are also most often the plural of the objects that they are an enumeration of, i.e. the Catalogs and Catalog objects, or the CatalogEntries and CatalogEntry object. Although shapes in IronCAD have not been discussed yet, a shape is added to the catalog by using the Add method on a CatalogEntries object and passing in a Shape object of the shape that needs to be added to the catalog. A CatalogEntry object is returned when calling the Add method, which is the entry that was made in the catalog for the shape that was added. CatalogEntry objects have a property called Object which returns the shape that is in the catalog for the specified CatalogEntry object. An example of this is used in the next part when shapes and their components are discussed. The diagram on the left shows some catalog entries and points to the label and icon of one of the entries so that it is easy to picture what the Label property and LoadIcon method specify on a CatalogEntry object. Catalog entries are not limited to shapes though, SurfaceFinish objects can be placed into catalogs as well. SurfaceFinish objects are objects that hold all the properties of a surface finish. When SurfaceFinish objects are dragged from the catalog onto a shape or the background of the scene all of the properties of the SurfaceFinish object are copied to the shape or background that it was dropped onto. To add a surface finish to a catalog, there are 3 easy steps : Create a new SurfaceFinish object using the CreateSurfaceFinish method on the Application Object Get the Catalog object for the desired catalog to add the finish to Add the SurfaceFinish object to the catalog using the Add method on the CatalogEntries object for the desired catalog An example of doing such is below from the AppCatalogs class in Basics1.vbp:
Public Sub AddSurfaceFinish(Application As Object) 1 2 3 Dim objCatalog As Object, objCatalogEntry As Object, objSurfaceFinish As Object 'Create a new surface finish object and set the color to be bright blue : Set objSurfaceFinish = Application.CreateSurfaceFinish

Page 22 of 104

IronCAD Customization: IronCAD Automation Data Model


4 5 6 7 8 objSurfaceFinish.SurfaceColor = RGB(0, 0, 255) 'Add the surface finish to the active catalog and label it 'Blue' : Set objCatalog = Application.ActiveCatalog Set objCatalogEntry = objCatalog.Entries.Add(objSurfaceFinish) objCatalogEntry.Label = "Blue"

End Sub

The default icon created in the catalog for surface finishes looks a little funny but it can be changed using the LoadIcon method on the CatalogEntry object or manually from the catalog. There are a total of 47 methods and properties on a SurfaceFinish object so a suggestion would be to play around with the settings and add different SurfaceFinish objects with different settings to a catalog and drag and drop them out to see the differences. The majority of the properties take a parameter that is labeled as Type which is a long. The Type is one of the constants in the EyeSurfaceFinishTypes enum in the IronCAD Type Library triBumps, triColor and triDecal. That should just about cover all the basics of catalogs and surface finishes, so now back to the Application object for the next topic which is the Pages property on the Application object. The Pages property returns the Pages object in the IronCAD Type Library which is an enumeration of Page objects, just like the Catalogs property returned the Catalogs object which was an enumeration of Catalog objects. Adding a new scene or opening an existing scene to IronCAD works almost identically to the way catalogs are added and opened. The example code below from the AppPages class in the Basics1.vbp project creates a new scene:
Public Sub AddPage(Application As Object) 1 2 3 4 5 Dim objPages As Object 'Get the enumeration of pages: Set objPages = Application.Pages 'Add a new page (Scene): objPages.Add

End Sub

The code is almost identical to the code for adding a new catalog except for the variable names. The code could be changed however to return the page that is added so that when line 5 is finished executing, there is a Page object variable, and the same could be done for the previous example adding a catalog:
Public Sub AddPage(Application As Object) 1 Dim objPages As Object, objPage As Object

Page 23 of 104

IronCAD Customization: IronCAD Automation Data Model


2 3 4 5 'Get the enumeration of pages : Set objPages = Application.Pages 'Add a new page and set a variable to the newly added page: Set objPage = objPages.Add

End Sub

Opening existing scenes is still just as easy as it was to open an existing catalog, simply pass the name of the scene into the Add method to open and instead of creating a new scene, the scene with the specified filename is opened. The example below is also from the AppPages class in the Basics1.vbp project:
Public Sub AddExistingPage(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Dim Dim Dim Dim szName As String frmOpen As frmFile objPage As Object objPages As Object

'Get the enumeration of pages : Set objPages = Application.Pages 'Set up the open dialog : Set frmOpen = New frmFile frmOpen.DefaultExt = ".ics" frmOpen.Filter = "IronCAD Scenes (*.ics)|*.ics" 'Display the open dialog, and if a file name was specified continue : If (frmOpen.ShowOpen(szName)) Then 'Open the scene with the specified filename : Set objPage = objPages.Add(szName) End If 'Release the open dialog : Set frmOpen = Nothing

End Sub

The code should look very familiar except for the fact that the page added is not set to be the active page like the catalog that was added was set to be the active page. The basic file operations open, save and close are very similar for the Catalog object and the Page object and if they are not clear, the help text on the methods in the IronCAD Type Library should help explain what parameters are needed. There are many things that can be done with a Page object in IronCAD or with a view from the Page object. The easiest thing to do since surface finishes have already been discussed is to set the background color or texture of a scene. To specify the background color or texture of a scene first a SurfaceFinish object Page 24 of 104

IronCAD Customization: IronCAD Automation Data Model needs to be created, then the Background property on the Page object needs to be set to the newly created SurfaceFinish object. The following code example is taken from the AppPages class in the Basics1.vbp project, which adds a new scene to IronCAD and then sets the background color of the newly created scene to a bright red:
Public Sub AddPageWithRedBackground(Application As Object) 1 2 3 4 5 6 7 8 9 Dim objPage As Object Dim objSurfaceFinish As Object 'Create a new surface finish object : Set objSurfaceFinish = Application.CreateSurfaceFinish 'Specify the surface color to be bright red : objSurfaceFinish.SurfaceColor = RGB(255, 0, 0) 'Now add a new page and make the background the bright red : Set objPage = Application.Pages.Add Set objPage.Background = objSurfaceFinish

End Sub

On line 4 a new SurfaceFinish object is created and on line 6 the SurfaceColor property is set to a bright red. Line 8 adds a new page to IronCAD and sets the variable objPage to be the newly created page. Finally on line 9 the Background property of the page is set to the SurfaceFinish object created earlier on line 4. The Page object also has another important property called SelectedItems. Another important property of the Page object is the SelectedItems property which returns the SelectedItems object in the IronCAD Type Library which is either an array of Shape objects or Face objects. Based upon what type is passed into the SelectedItems property on the Page object determines whether Shape objects or Face objects are returned. The type is specified by the EyeSelectedItemsTypes enum in the IronCAD Type Library which has 2 values triFace and triShape. The example code below from the AppPages class in the Basics1.vbp project displays the number of selected faces and shapes:
Public Sub DisplaySelectedItemsCount(Application As Object) 1 2 3 4 5 6 7 8 Dim szMsg As String Dim objPage As Object, objSelFaces As Object, objSelShapes As Object 'If there is atleast one page then continue : If (Application.Pages.Count > 0) Then 'Set the active page and selected items : Set objPage = Application.ActivePage Set objSelFaces = objPage.SelectedItems(triFace) Set objSelShapes = objPage.SelectedItems(triShape)

Page 25 of 104

IronCAD Customization: IronCAD Automation Data Model


9 10 11 12 'Display a message with how many shapes and faces are selected : szMsg = "Selected Faces: " & objSelFaces.Count & vbCrLf & _ "Selected Shapes: " & objSelShapes.Count MsgBox szMsg, vbInformation, "IronCAD Basics" End If

End Sub

The SelectedItems object works the same way the Pages object and Catalogs object work. To get an object from the enumeration use the Item method on the SelectedItems object. This object will be discussed more in the next part when shapes and their components are discussed, but since it is a property of the Page object it has been mentioned now. It is important to keep this property in mind for the next part dealing with shapes and their components. One of the most important properties of the Page object however is the Units property. This property returns the length or angle units that the page is currently in. The Units property takes a type, which is one of the constants defined in the EyeUnitTypes enum in the IronCAD Type Library, either triAngleUnits or triLengthUnits. The reason it is so important to know the units of a page is because there are properties and methods on the objects in the IronCAD Type Library that require the values to be set in centimeters or radians, or that return the values in centimeters or radians. The majority of the properties and methods on the objects in the IronCAD Type Library are in the user units so nothing special needs to be done. There are only a few properties and methods which require the values be set in centimeters or radians and these properties and methods should be clearly labeled in the IronCAD Type Library. Up to this point none of these properties have been mentioned, however in the upcoming sections these properties and methods will become apparent. Below is a code example taken from the AppPages class in the Basics1.vbp project which displays the user units for the active page:
Public Sub DisplayUserUnits(Application As Object) 1 2 3 4 5 6 7 8 9 10 Dim szMsg As String Dim objPage As Object 'If there is at least one page then continue : If (Application.Pages.Count > 0) Then 'Set the active page : Set objPage = Application.ActivePage 'Display a message with the units : szMsg = "Length Units: " & objPage.Units(triLengthUnits) & vbCrLf & _ "Angle Units: " & objPage.Units(triAngleUnits) MsgBox szMsg, vbInformation, "IronCAD Basics" End If

Page 26 of 104

IronCAD Customization: IronCAD Automation Data Model


End Sub

The majority of the time the ratio from the user units to centimeters or radians is more important than the actual units the user is using. To facilitate this there is another property on the Page object which is UnitsScale which also takes a type that is the EyeUnitTypes enum. The UnitsScale property returns the ratio that a value must be multiplied to convert it from the user units to either centimeters or radians based on the type. Below is a simple table that shows how to convert units so that the correct values for properties can be set : From User Length Units User Angle Units Centimeters Radians To Centimeters Radians User Length Units User Angle Units Multiply By Page.UnitsScale(triLengthUnits) Page.UnitsScale(triAngleUnits) 1 / Page.UnitsScale(triLengthUnits) 1 / Page.UnitsScale(triAngleUnits)

IronCAD uses centimeters and radians internally for calculations, so from this point on centimeters and radians will be considered system units. It is very important to understand how to convert from system units to user units, and vice versa. Some of the advanced methods for shape creation require that units be in radians and centimeters so a firm understanding of units will be helpful later on. The last object to be covered in IronCAD Basics is the Pane object. The Pane object is the object used to export images or fit the geometry of a scene. There is always at least one Pane object per page, however there can be infinitely many. In the screen capture on the left there are 3 panes for the scene. The Page object has a property called ActivePane which returns the Pane object the user is currently working in, but to get an enumeration of Pane objects first a PageWindows object must be set by using the Windows property of a Page object. Then from the PageWindows object a PageWindow must get set from the enumeration, and on the PageWindow object there is a Panes property which returns the Panes object which is the enumeration of Pane objects for a scene. An example of doing such is below:

Page 27 of 104

IronCAD Customization: IronCAD Automation Data Model


1 2 3 Dim objPageWindows As Object, objPanes As Object Set objPageWindows = objPage.Windows Set objPanes = objPageWindow.Item(1).Panes

In the example above it is assumed that the variable objPage has been set to a Page object before line 2 in the code. To demonstrate how to use the Panes object enumeration, the code example below is from the AppPanes class in the Basics1.vbp project, which goes to each pane in the scene and fits the geometry:
Public Sub FitAllViews(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Dim Dim Dim Dim Dim i As Integer objPage As Object objWindows As Object objPanes As Object objPane As Object

'If there is at least 1 page open then continue : If (Application.Pages.Count > 0) Then 'Set the page to be the active page : Set objPage = Application.ActivePage 'Set the panes enumeration : Set objWindows = objPage.Windows Set objPanes = objWindows.Item(1).Panes 'Next loop through all the panes and fit the geometry : For i = 1 To objPanes.Count 'Set the pane object and fit the geometry : Set objPane = objPanes.Item(i) objPane.FitGeometry Next End If

End Sub

On line 16 the Pane object is set, then on the next line the FitGeometry method on the Pane object is called to fit the geometry in the pane so everything is visible. This example shows how to loop through all the available panes and get at each pane to use the methods and properties available on a Pane object. Another common use of the Pane object is for exporting images. There is a method called ExportImage on a Pane object, which allows a filename, image type and the dimensions of the image being exported to be specified. Below is an example of exporting an image from a pane taken from the AppPanes class in the Basics1.vbp project:
Public Sub ExportImage(Application As Object)

Page 28 of 104

IronCAD Customization: IronCAD Automation Data Model


1 2 3 4 5 6 7 Dim objPane As Object 'If there is at least 1 page open then continue : If (Application.Pages.Count > 0) Then 'Get the active pane of the active page and export it : Set objPane = Application.ActivePage.ActivePane objPane.ExportImage "C:\Image.jpg", triJPEG, 100, 100 End If

End Sub

The rendering style of the pane, along with the position of the camera and a few other properties are able to be set from the Pane object. There are also two methods HorizontalSplit and VerticalSplit which split the Pane object into two Pane objects to create a new pane. This concludes this part on the basics of IronCAD . There has been a lot discussed up to this point, however only about half of the functionality dealing with the basics of IronCAD have been discussed. The IronCAD automation system is very large and the primary focus of this document is shape creation so such things like the cameras, lights and animation are not be discussed. From this point on the primary objective will be to explain the shape and component system and provide the information needed to create Add-On tools, create custom Sheet Metal shapes and explain how to customize the BOM table in a 2D drawing.

IronCAD Shape And Component Architecture


This part refers to the Shapes1.vbp project in the Example 5 directory in the accompanying source code.

The first thing that needs to be done is define what a shape is in IronCAD , and particularly what the Shape object is. Simply, the Shape object represents any shape in IronCAD. This means extrude shapes, loft shapes, spin shapes and sweep shapes are all represented by the Shape object in the IronCAD Type Library. While that may not be too difficult to grasp, assemblies, parts, 2D profile shapes and imported shapes are also represented by the Shape object. In fact, the Shape object represents a total of 14 shapes in IronCAD which are defined in the EyeShapeTypes enum in the IronCAD Type Library, below is a list:
triBrepShape B-Rep / Imported Shape triComplexShape1 Complex Shape triCompoundShape Part triEdgeBevelShape Chamfer or Blend triExtrudeShape Extrude Shape triFacetShape Facet Shape triGeneralSweepShape Sweep Shape triGroupShape Assembly triLoftShape Loft Shape triProfileShape 2D Profile Shape / Profile Shape triSheetMetalBendShape 1 S.M. Bend Shape triSheetMetalExtrudeShape1 S.M. Extrude Shape triSheetMetalFormShape1 S.M. Forming Shape triTurnShape Spin Shape

Page 29 of 104

IronCAD Customization: IronCAD Automation Data Model


1

Indicates new shape in IronCAD 2.0

The Shape object has a property called Type, which returns the type of shape that the Shape object represents. The type returned will be one of the constants listed in the EyeShapeTypes enum in the IronCAD Type Library. There are a total of 30 properties and methods on the Shape object which allow the shape to be suppressed, the user name to be set and the components of the shape to be retrieved. The example below simply lists all the names of the selected shapes in the active scene and is taken from the Shapes class in the Shapes1.vbp project:
Public Sub DisplaySelectedShapeNames(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Dim Dim Dim Dim i As Integer szMsg As String objShape As Object objSelShapes As Object

'If there is at least one page then continue : If (Application.Pages.Count > 0) Then 'Get the list of selected shapes : Set objSelShapes = Application.ActivePage.SelectedItems(triShape) 'Now display a message box with the names of the shapes that are selected : For i = 1 To objSelShapes.Count 'Set the selected shape : Set objShape = objSelShapes.Item(i) 'Get the shape name and add it to the message : szMsg = szMsg & objShape.Name & vbCrLf Next 'Display the message with all the shape names : MsgBox szMsg, vbInformation, "IronCAD Shapes And Components" End If

End Sub

The majority of the code should look very familiar, in fact the only new piece of code should be line 15 where the Name property of the Shape object is retrieved and added to the string that holds all the shape names. There are several methods on the Shape object, but only a few of them will be used to any great extent. When dealing with shape creation, the Shift and Rotate methods will be used most often. These two methods require the values to be in system units (centimeters and radians) so it is important to convert any values from user units to system units before calling these methods. The Copy method on the Shape Page 30 of 104

IronCAD Customization: IronCAD Automation Data Model object is also used often during shape creation. The Copy method takes one parameter which is whether to create a link or copy the shape. If the value TRUE is passed to the Copy method, then a link is created, otherwise the shape is copied. The Copy method returns the new shape that resulted from the copy or link. The last method which is used to any extent during shape creation is the ResetSizebox method. This method resets the sizebox of the shape to fit around the extents of the shape. When creating a shape, the sizebox is initialized to 100 x 100 x 100 in user units, so often it is required that the sizebox be reset. However the ResetSizebox method should be used sparingly, instead the sizebox dimensions should be calculated by the program and set. This will be discussed more during the discussing on shape creation. There are a few other methods on the Shape object, however the help text in the Type Library should guide the way for explaining what the methods do. There are two more methods on the Shape object which require system units and they are the GetPointTransformUp and GetPointTransformDown methods. Very rarely will methods other than the ones mentioned above be used, so now the most commonly used properties will be listed. There are only two properties on the Shape object that get used most of the time, the first is the Suppressed property. This property allows the suppression state of a shape to be set and read. The other property which is the most commonly used property, is the Components property on a Shape object. Components are the heart of the IronCAD shape data model. The Components property of the Shape object returns an enumeration of the type of component specified. There are a total of 68 components, which the majority of are listed in the EyeShapeComponentTypes enum in the IronCAD Type Library. The number of components can be determined by the value of the constant triMaxComponentNumber which is the number of components. The Components property on the Shape object always returns the Components object which is an enumeration of Component objects for the majority of the component types, but for some components the Components object is returned with an enumeration of objects other than the Component object. Below is a list of the component types that return the Components object as an enumeration of something other than the Component object:
Component Types and the objects returned if not a Component object : Component Type Object Returned Component Type Object Returned
triCamera triEdgeBevel triEmbeddedPage triFaceFinish1 triFacet triGroup triHistory triLight CameraComponent EdgeBevelComponent EmbeddedPageComponent FaceFinishComponent FacetComponent GroupComponent HistoryComponent LightComponent triOleObject triPath triPathMasterComponent triProfile triSizebox triSMBend triSMExtrude triSMForm OleObjectComponent PathComponent PathMasterComponent ProfileComponent SizeboxComponent SMBendComponent SMExtrudeComponent SMFormComponent

Page 31 of 104

IronCAD Customization: IronCAD Automation Data Model


triLineStyle triLoft
1

LineStyleComponent LoftComponent

triSMPart triFaceFinish1

SMPartComponent SurfaceFinishComponent

The triFaceFinish component type returns either a FaceFinishComponent object or a SurfaceFinishComponent object depending on the circumstance when invoked.

Components are what really defines a shape. The position of a shape, the position of a shapes anchor, the dimensions of a shape sizebox, the extrude height of an extrude shape and more are all defined in the components on a shape. For example, to set the position of a shape or get the position of a shape, first the enumeration of position components must be set. Next the position component must be set. Then once the position component is set, variables on the component can be set to position the shape or read to find out the position of a shape. To introduce the concept of components, below is an example piece of code taken from the Components class in the Shapes1.vbp project. The code displays the X, Y and Z position of the selected shape in the active scene, then moves the shape to the 0, 0, 0 position:
Public Sub DisplayAndResetShapePosition(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16 17 18 19 20 21 22 23 24 Dim Dim Dim Dim szMsg As String objSelShapes As Object objPositionCT As Object objPosComponents As Object

'Continue if there is at least one page open : If (Application.Pages.Count > 0) Then 'Continue if there is one selected shape : Set objSelShapes = Application.ActivePage.SelectedItems(triShape) If (objSelShapes.Count = 1) Then 'Set the position components of the selected shape : Set objPosComponents = objSelShapes.Item(1).Components(triPosition) 'Make sure there is a position component, if so continue : If (objPosComponents.Count > 0) Then 'Set the position component and display the position : Set objPositionCT = objPosComponents.Item(1) szMsg = "X : " & objPositionCT.Variable(triX).Value & vbCrLf & _ "Y : " & objPositionCT.Variable(triY).Value & vbCrLf & _ "Z : " & objPositionCT.Variable(triZ).Value MsgBox szMsg, vbInformation, "IronCAD Shapes And Components" 'Now set the postion of the shape to objPositionCT.Variable(triX).Value = objPositionCT.Variable(triY).Value = objPositionCT.Variable(triZ).Value = End If End If be at 0, 0, 0 : 0 0 0

Page 32 of 104

IronCAD Customization: IronCAD Automation Data Model


25 End If

End Sub

Until line 11 the code should look very familiar, the code simply checks and makes sure that there is a scene open, if so it sets the active Page object, then it sets the SelectedShapes object and if only one shape is selected it continues. What is new however is line 11 when the enumeration of position components is set. At the end of execution on line 11, the variable objPositionComponents is a Components object because the Components property of a shape always returns a Components object. On line 14 something very important happens, a check is done to see whether there are any position components on the shape. Since an enumeration of components is returned, it is possible for there not to be any of the requested component on the shape. Once it is confirmed that there is at least one position component on the shape, the variable objPositionCT is set to the position component of the shape on line 16. Since the position component is not a component that has a special object associated with it listed on page 31, the variable objPositionCT is a Component object at the end of line execution. The majority of the components should never occur more than once on a single shape. For instance, there will never be more than one position component, sizebox component or anchor component on a shape it would not make sense. Some components however can exist multiple times on a shape which will be discussed when talking about shape creation. On line 17 and then again on lines 20 through 22 the Variable property on the Component object is called and the constants triX, triY and triZ are passed to the property which returns the Variable object. Each component has certain variables associated with it and for the position and anchor component the variable types are defined in the IronCAD Type Library in the EyePositionAndAnchorComponentVariables enum. Hopefully the name of the enum is not too long but it is descriptive which is a general goal when coming up for enum names. The constants in the enum are the variables that can be read or set from either a position or anchor component. As the discussion concerning shapes and their components progresses it will become apparent which enums go to the components. Inside of the position and anchor variable enum there are also 3 more constants called triRotX, triRotY and triRotZ which specify the rotation axis that the shape is rotated about. The angle that the shape is rotated about around the axis defined by the triRotX, triRotY and triRotZ is defined by the variable using the constant triRotAngle. To help picture this, in the diagram on the left the 3 axes have been Page 33 of 104

IronCAD Customization: IronCAD Automation Data Model labeled and so has the rotation vector and the shape normal. Imagine the rotation vector originally aligned with the X axis and the shape normal originally aligned with the Z axis. Also imagine that the rotation vector is glued at a 90 angle to the shape normal vector, so any time the rotation vector or the shape normal vector is moved, the other moves with it. Now as the rotation vector is moved around the shape normal vector will also move. The direction of the rotation vector is represented by the variables triRotX, triRotY and triRotZ. Now imagine rotating the rotation vector about its axis. The rotation vector will not appear to move but the shape normal vector will appear to be spinning around the rotation vector. The angle that the rotation vector is rotated about its axis is represented by the triRotAngle variable. If the concept of vector spaces is new this may be a difficult thing to picture, but this is a very important principle because when it comes time to create shapes it will be very crucial to understand positioning in 3D and the way rotations are represented. The anchor component works the same way that the position component does as far as rotations are concerned. Next to demonstrate a component that does not return a Component object like the position component did, the sizebox component will be used which returns a SizeboxComponent object instead of the Component object which can be determined by looking at the table once again on page 31. The example below taken from the Components class in the Shapes1.vbp project displays the length, width and height of the sizebox of the selected shape in the active scene:
Public Sub DisplayShapeSizeboxDimensions(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Dim Dim Dim Dim szMsg As String objSelShapes As Object objSizeboxComponents As Object objSizeboxCT As Object

'Continue if there is at least one page open : If (Application.Pages.Count > 0) Then 'Set the selected shapes : Set objSelShapes = Application.ActivePage.SelectedItems(triShape) 'If there is one selected shape then continue : If (objSelShapes.Count = 1) Then 'Set the sizebox components of the shape then get the sizebox 'component of the shape : Set objSizeboxComponents = objSelShapes.Item(1).Components(triSizeBox) If (objSizeboxComponents.Count > 0) Then 'Set the sizebox component : Set objSizeboxCT = objSizeboxComponents.Item(1) 'Display the dimensions of the sizebox :

Page 34 of 104

IronCAD Customization: IronCAD Automation Data Model


18 szMsg = "Length:" & objSizeboxCT.Variable(triLength).Value & _ vbCrLf & _ "Width :" & objSizeboxCT.Variable(triWidth).Value & vbCrLf & _ "Height:" & objSizeboxCT.Variable(triHeight).Value MsgBox szMsg, vbInformation, "IronCAD Shapes And Components" End If End If End If

19 20 21 22

End Sub

The code segment above should look very familiar once again and not too intimidating. There are no big changes to the way the variable values were retrieved from the SizeboxComponent object, except different constants were used. The variables available on the SizeboxComponent object are defined in the IronCAD Type Library in the EyeSizeboxComponentVariables enum. The values of the sizebox can also be set just like the position of the shape was set using the position component in the example prior to this one. There are also three other variables that are unique to the SizeboxComponent object, the triHideHeightHandles, triHideLengthHandles and triHideWidthHandles variables. These variables can be set just like the position of the shape was set, only the values for these variables should be set to the value 1 or True if the handles should be hidden, or to the value 0 or False if the handles should be shown. The final variable which is of unique interest is the triDisplayType variable of the sizebox component. The value of this variable must be set to one of the constants defined in the EyeSizeboxDisplayTypes enum. This variable sets whether the sizebox of the shape is shown and if so what parts of the sizebox are displayed. The majority of the components work in the same way that has been demonstrated above using the position and sizebox components. Once a good understanding of how the position and sizebox components work, that knowledge can be applied to almost any of the other components since they are all very identical. The two components that are very special however are the history component, represented by the HistoryComponent object and the group component, represented by the GroupComponent object. In the beginning of this part, a statement was made that assemblies are shapes. An assembly shape is represented by the shape type triGroupShape because that is what it is really doing grouping shapes. However assembly shapes have a special component called the group component. The GroupComponent object has a property called Shapes which returns a Shapes object from the IronCAD Type Library. The Shapes object is an enumeration of all the shapes in the assembly shape and specifying an item from the enumeration using the Item method on the Shapes object returns a Shape object. The Shapes object is almost exactly like the SelectedItems object that was discussed previously in the IronCAD Basics part. Page 35 of 104

IronCAD Customization: IronCAD Automation Data Model The example code below is taken from the Components class in the Shapes1.vbp project. The code displays the names for all the shapes at the root level in the active scene:
Public Sub DisplayRootShapes(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 Dim Dim Dim Dim Dim Dim i As Integer szMsg As String objTopAssembly As Object objGroupCT As Object objGroupCTS As Object objShapes As Object

'Continue if there is at least one page open : If (Application.Pages.Count > 0) Then 'Set the top shape of the page : Set objTopAssembly = Application.ActivePage.Shape 'Set the group components of the top assembly shape : Set objGroupCTS = objTopAssembly.Components(triGroup) 'Make sure that there is a group component and set it : If (objGroupCTS.Count > 0) Then 'Set the group component of the top assembly and 'the shapes inside of the assembly Set objGroupCT = objGroupCTS.Item(1) Set objShapes = objGroupCT.Shapes 'Now display all the shapes at the root level : For i = 1 To objShapes.Count szMsg = szMsg & objShapes.Item(i).Name & vbCrLf Next MsgBox szMsg, vbInformation, "IronCAD Shapes And Components" End If End If

End Sub

The first new unfamiliar piece of code should be on line 10, the objTopAssembly variable is set to the Shape property of the Page object. The Shape property of the Page object actually returns a shape which is an assembly. Basically, all of the shapes in a scene are placed in this shape, often referred to as the Top Shape. The shape that the Shape property on the Page object returns can never be removed nor does it have a name, the only purpose of it is to be a container for all the other shapes in the scene. Next the code gets the group component and verifies that there is one which should be familiar. The next piece of new code however exists on line 18 when the objShapes variable is set to the Shapes property of the GroupComponent object. The Shapes property returns the Shapes object, which is an enumeration of Shape objects. Then for each shape in Page 36 of 104

IronCAD Customization: IronCAD Automation Data Model the enumeration, the name of the shape is added to the message displayed on lines 20 through 22, then the message with the names of all the shapes in the root level is displayed on line 23. The history component is exactly identical to the group component, except for the fact that only parts have history components, just like only assemblies have group components. Shapes which have history components are shapes identified by the shape types: triCompoundShape, triSheetMetalFormShape and finally triComplexShape. The shape type triCompoundShape is the shape type of a part that a user is accustomed to working with in IronCAD . Shapes specified by triComplexShape and triSheetMetalFormShape are new shapes in IronCAD 2.0 and the complex shape will be briefly discussed in during shape creation and the sheet metal forming shape will be discussed in the IronCAD Sheet Metal Architecture section. Below is a code segment taken from the Components class in the Shapes1.vbp project which displays the names of the IntelliShapes inside of a selected part in the active IronCAD scene:
Public Sub DisplayChildShapes(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Dim Dim Dim Dim Dim Dim Dim i As Integer szMsg As String objPart As Object objShapes As Object objSelShapes As Object objHistoryCT As Object objHistoryCTS As Object

'Continue if there is at least one page open : If (Application.Pages.Count > 0) Then 'Set the selected shapes : Set objSelShapes = Application.ActivePage.SelectedItems(triShape) 'If there is one selected shape and it is a part then continue : If ((objSelShapes.Count = 1) And _ (objSelShapes.Item(1).Type = triCompoundShape)) Then 'Set the selected shape and its history components : Set objPart = objSelShapes.Item(1) Set objHistoryCTS = objPart.Components(triHistory) 'If there is at least one history component then continue : If (objHistoryCTS.Count > 0) Then 'Set the history component and the shapes that are 'in the history of the part : Set objHistoryCT = objHistoryCTS.Item(1) Set objShapes = objHistoryCT.Shapes 'Now display all the names of the IntelliShapes that 'make up the part : For i = 1 To objShapes.Count szMsg = szMsg & objShapes.Item(i).Name & vbCrLf

Page 37 of 104

IronCAD Customization: IronCAD Automation Data Model


27 28 29 30 31 Next MsgBox szMsg, vbInformation, "IronCAD Shapes And Components" End If End If End If

End Sub

As promised, the code is identical to the code for listing the shapes in an assembly except for the constants used. By this point the way that components work should be clear. Only four of the components up to this point have been discussed but that will change exponentially in the next few sections. This is also the conclusion of this section. The basic fundamentals of the IronCAD Automation Data Model should be relatively clear by this point and while working with the components of shapes may not be 100% understood at this point, there should be a comfortable understanding of how to get access to the components. The purpose of this section was to provide the ground work for the next section IronCAD Shape Creation, which concentrates on how to create shapes and add the correct components so that the shapes can successfully be created without flaw. As the sections continue, working with the components of shapes will become more intuitive and it will begin to be more fun since results will start to be seen. Sweet dreams are made of this.

Page 38 of 104

IronCAD Customization: IronCAD Shape Creation

IronCAD Shape Creation


Introduction
The process of creating shapes involves two basic steps, the first of which is setting up the components of the shape being created and the second is drawing the geometry for the shape cross-section(s). In the first part a 2D Profile shape will be used to demonstrate the way geometry is drawn to a profile and how to get desired results. Since the 2D Profile shape is the simplest shape, there will be no need to discuss components so geometry creation can be focused on. The subsequent parts will discuss how to create the four basic shapes extrudes, spins, sweeps and lofts, along with the complex shape, which is a new shape in IronCAD.

Profile Creation
This part refers to the project Profile1.vbp in the Example 6 directory in the accompanying source code.

Before discussing how to draw geometry on a profile, first there needs a median to draw on. Inside of the Creation class in the Profile1.vbp project there is a private function called Add2DProfileShape for which the code is below. This function tries to add a profile shape to the active page in the application if it is successful it returns true and returns the 2D profile shape added by reference. However if it is unable to add the 2D profile shape it returns false. For the rest of this part this function will be used to add a 2D Profile shape to the scene so that the code does not need to be re-typed for each example.
Private Function Add2DProfileShape(Application As Object, _ ByRef ProfileShape As Object) As Boolean 1 2 3 4 5 6 7 8 9 10 11 12 13 Dim bShapeAdded As Boolean Dim objTopAssembly As Object Dim objGroupComponent As Object 'Make sure there is at least on page, if so set the active 'page's top assembly shape, otherwise return FALSE : If (Application.Pages.Count > 0) Then 'Set the top assembly : Set objTopAssembly = Application.ActivePage.Shape 'Get the group component of the top shape : Set objGroupComponent = objTopAssembly.Components(triGroup).Item(1) 'Add the shape and return it : Set ProfileShape = objGroupComponent.Shapes(triProfileShape).Add bShapeAdded = True

Page 39 of 104

IronCAD Customization: IronCAD Shape Creation


14 15 16 17 18 19 Else 'Set that the shape was not added : bShapeAdded = False End If 'Return whether the shape was added : Add2DProfileShape = bShapeAdded

End Function

In the code segment above there should only be one thing that is unfamiliar which is on line 12 when the profile shape is added. What is happening is that an enumeration of the profile shapes in the top assembly is set and then a shape is added to the enumeration. Since it is an enumeration of 2D profile shapes, that means the Add method adds a 2D profile shape. The 2D profile shape is then returned by reference and TRUE is returned on success, otherwise FALSE is returned so that the calling function knows whether it should continue or not. This function as mentioned before will be used throughout the rest of this part so it is important that what it does is understood. Profile shapes have as many path components as there are the loops in the profile. For those whom are not familiar with the concept of a loop, a loop is a closed path, or also commonly referred to as an outline. To the left are examples of cross sections with different numbers of loops in them. The examples are all circular, but the geometry of the loop does not matter. As long as the path is closed it is considered a loop, so even a rectangular, triangular or a hexagon is a loop as long as the path is closed. In the first example, there would be at least 1 path component on the profile shape, in the second example there would be at least 2 path components on the profile shape and in the final example there would be at least 3 path components on the profile shape. The reason there will be at least that number of path components is because for each piece of construction geometry on a profile, there will be another path component. If the cross sections pictured above had no construction geometry there would be one, two and three path components for the profiles respectively. The following example has one purpose which is to demonstrate adding a path to a profile and adding the curves to the path which was added. The geometry consists only of a few lines that produce a rectangle, however understanding the basic concept of creating the rectangle is the important part of this example. The source code of the example is taken from the Creation class in Page 40 of 104

IronCAD Customization: IronCAD Shape Creation the Profiles1.vbp project. A picture of what the source code produces is also shown at the end of the source code in the discussion of the source code:
Public Sub CreateRectangle(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Dim obj2DProfile As Object Dim objPathComponent As Object Dim objPathComponents As Object 'Add a 2D Profile shape to the scene, if successful continue : If (Add2DProfileShape(Application, obj2DProfile)) Then 'Get the path components of the profile : Set objPathComponents = obj2DProfile.Components(triPath) 'Add a new path component for the geometry to be drawn to : Set objPathComponent = objPathComponents.Add 'Now draw the geometry on the path component : objPathComponent.SetStartPoint -1, 1 objPathComponent.AddLineTo 1, 1 objPathComponent.AddLineTo 1, -1 objPathComponent.AddLineTo -1, -1 objPathComponent.AddLineTo -1, 1 End If

End Sub

The first thing that happens is that on line 5 an attempt to add a 2D profile shape to the scene happens. If it is successful then TRUE is returned and code execution continues. Next on line 7 an enumeration of PathComponent objects is set to the variable objPathComponents. So now the variable objPathComponents is an enumeration of PathComponent objects on the profile. Then on line 9 a PathComponent object is added to the enumeration and returned so that the variable objPathComponent is set to be a PathComponent object. Next the profile of the rectangle is drawn starting in the upper left hand corner and finishing up in the upper left hand corner of the profile. The SetStartPoint method must always be called on a PathComponent object before adding any geometry so that the system knows where the geometry is starting. Since the path must be closed, it is also important that the last piece of geometry is added so that it ends at the starting point. The method AddLineTo draws a line from the current position to the values passed in to the method. To the left is a diagram of how this profile was drawn.

Page 41 of 104

IronCAD Customization: IronCAD Shape Creation The next logical step to the example above would be to fillet some of the corners to produce a more rounded looking shape. The PathComponent object has another method called AddFilletAt which adds a fillet at the vertex index specified. In the example above, it seems logical to add a fillet at index 1, 2, 3 and then 4 since there are 4 vertices in the profile. However it is important to understand that when a fillet is added, two vertices are produced from one so all of the subsequent indexes of the vertices are increased by 1. In the following code sample taken from the Creation class in the Profiles1.vbp project, the radii of the fillets is increased so it is clear to understand which vertex the fillet is added to and keep in mind the order in which the profile is was created :
Public Sub CreateFilletedRectangle(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Dim obj2DProfile As Object Dim objPathComponent As Object Dim objPathComponents As Object 'Add a 2D Profile shape to the scene, if successful continue : If (Add2DProfileShape(Application, obj2DProfile)) Then 'Get the path components of the profile : Set objPathComponents = obj2DProfile.Components(triPath) 'Add a new path component for the geometry to be drawn to : Set objPathComponent = objPathComponents.Add 'Now draw the geometry on the path component : objPathComponent.SetStartPoint -1, 1 objPathComponent.AddLineTo 1, 1 objPathComponent.AddLineTo 1, -1 objPathComponent.AddLineTo -1, -1 objPathComponent.AddLineTo -1, 1 'Add the fillets to the profile objPathComponent.AddFilletAt 1, objPathComponent.AddFilletAt 3, objPathComponent.AddFilletAt 5, objPathComponent.AddFilletAt 7, End If : 0.25 0.375 0.5 0.625

End Sub

The key to understanding the reasoning behind the fillet index is below:

Page 42 of 104

IronCAD Customization: IronCAD Shape Creation

Originally the profile is created and the vertex numbering resembles the picture in the first frame. A fillet is then added at vertex one in the first frame which produces frame two. In frame two there are 2 vertices where the vertex 1 used to be and subsequently all of the vertices thereafter have been incremented by 1. So, instead of logically adding the next fillet at vertex 2 which was originally suggested, the vertex needs to be added at the index 3 instead. Then once the vertex at index 3 has been added two vertices take the place of the previous vertex 3, which subsequently increment all the remaining vertices by one. This process continues until the last frame when the original vertex 4 is now vertex 7 since 3 fillets have been added. An easy way to calculate which vertex the fillet needs to be added at is to figure out which vertex the fillet originally needed to be added at, then add the number of fillets added to the profile up to that point. The next piece of 2D geometry after fillet which may cause confusion, is the arc. The way arcs are defined in IronCAD is by the ratio of the arcs chord height divided by the arc chord length, often referred to as the elliptical ratio of the arc. The diagram on the left shows variations of an arc and the chord height and length for each. The method AddArcTo on the PathComponent object takes X and Y for the first two parameters, and r for the third parameter. The third parameter is the elliptical ratio of the arc. The fourth parameter Veccentr is optional and generally is not used. In the following example the latter of the two diagrams above is created since the elliptical ratio is more difficult to figure out. The elliptical ratio for the first diagram is simply , or 0.5 since it is a half circle. Below is the code to create the cross section of the second diagram starting from the top left corner taken from the Creation class in the Profiles1.vbp project:
Public Sub CreateArcs(Application As Object) 1 2 3 4 5 6 7 8 Dim Dim Dim Dim obj2DProfile As Object dEllipticalRatio As Double objPathComponent As Object objPathComponents As Object

'Add a 2D Profile shape to the scene, if successful continue : If (Add2DProfileShape(Application, obj2DProfile)) Then 'Get the path components of the profile : Set objPathComponents = obj2DProfile.Components(triPath)

Page 43 of 104

IronCAD Customization: IronCAD Shape Creation


9 10 11 12 13 14 15 16 17 18 19 20 'Add a new path component for the geometry to be drawn to : Set objPathComponent = objPathComponents.Add 'Calculate the elliptical ratio : dEllipticalRatio = (1 - ((2 * (0.5 ^ 2)) ^ (1 / 2))) / (2 ^ (1 / 2)) 'Now draw the geometry on the path component : objPathComponent.SetStartPoint -1, 1 objPathComponent.AddLineTo -0.5, 1 objPathComponent.AddArcTo 1, -0.5, dEllipticalRatio objPathComponent.AddLineTo 1, -1 objPathComponent.AddLineTo -1, -1 objPathComponent.AddLineTo -1, 1 End If

End Sub

In the example above the arc is created tangent at the edges that it is adjacent to. However, if the direction of an arc needs to be reversed, then pass in the negative value of the elliptical ratio for the arc to produce the arc flipped about its end points. To the left is a picture of the cross section created from the code above if the code above is modified to pass the negative value of the elliptical ratio for the arc. Essentially the cross section is identical to the previously created cross section however the center of the arc has been flipped to the other side to produce a perpendicular relationship of the arc to its neighboring edges, instead of the tangent relationship it once had in the previous example. The second to last piece of 2D geometry to be discussed is the ellipse. When creating a simple circle, the AddEllipse method on the PathComponent object only needs the X and Y values of the center of the circle to be specified, along with the radius of the circle. For example, in the cross section on the right the circle has been created with the center set at 0, 0 and the radius was set to 1. The code to fragment below is not in the accompanying source code, but shows how to create the cross section to the right:
1 2 3 Create an ellipse centered at 0, 0, 0 with a radius of 1 objPathComponents.SetStartPoint 0, 0 objPathComponents.AddEllipse 0, 0, 1

Page 44 of 104

IronCAD Customization: IronCAD Shape Creation The more difficult type of ellipse is one where the major radius and minor radius are different. In the following example an ellipse will be created which has a major radius of 1 and a minor radius of 0.5. The ellipse is also rotated 45 in the counter-clockwise direction. When creating an ellipse that has a different major and minor radius, the parameter which was originally the radius of the circle is now the minor radius of the circle. The last two parameters u and v in the AddEllipse method specify the point on the cross section where the major radius ends. This means that the major radius is not actually specified as a parameter in the method, instead the X and Y component of the radius is specified. Since the ellipse needs to be rotated 45 and we know the radius is 1, the X and Y position of the radius must be calculated first by doing the following: X = 1 * Cos(45) Y = 1 * Sin(45) Since the goal is for the major radius to be 1, the cos and sine of 45 are multiplied by the value 1. If the radius needed to be 2, the cos and sin of 45 would be multiplied by 2 instead. Below is a code sample from the Creation class in the Profiles1.vbp project, which creates the cross section pictured above:
Public Sub CreateEllipse(Application As Object) 1 2 4 4 5 6 7 8 9 10 11 12 13 14 'The constant PI Const PI = 3.14159265358979 Dim obj2DProfile As Object Dim objPathComponent As Object Dim objPathComponents As Object 'Add a 2D Profile shape to the scene, if successful continue : If (Add2DProfileShape(Application, obj2DProfile)) Then 'Get the path components of the profile : Set objPathComponents = obj2DProfile.Components(triPath) 'Add a new path component for the geometry to be drawn to : Set objPathComponent = objPathComponents.Add 'Now draw the geometry on the path component : objPathComponent.SetStartPoint 0, 0 objPathComponent.AddEllipse 0, 0, 0.5, (1 * Cos(PI / 4)), _ (1 * Sin(PI / 4)) End If

End Sub

Page 45 of 104

IronCAD Customization: IronCAD Shape Creation

That just about covers profile creation except for the B-Spline curve. The B-Spline is unlike all the other curves because unlike most where the complete definition of the curve is set when it is added, the B-Spline curve is added then the definition of the curve must be set. Due to the complexity of a B-Spline, it is not possible to set the definition of the curve when adding it, instead after it has been added the definition is set. When a B-Spline curve is added, the Add method of the ProfileComponent returns a CurveBSpline object instead of the Curve object which is returned for all other curves. The CurveBSpline object provides two methods for setting the definition of a B-Spline curve SetDefinition and SetDefinitionByFitPoints. The first method requires the control polygon and the weights of all the control points to be known which is not usually the case unless the information is coming from another CAD package. The second method, SetDefinitionByFitPoints only requires a list of points that the B-Spline must pass through, then it will fit itself to go through the fit points. In the code example below, a B-Spline is drawn to fit the points (-1,0), (0, 1) and (1, 0) and there is a line drawn at the bottom to close the profile. The example is taken from the Creation class in the Profiles1.vbp project:
Public Sub CreateBSpline(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Dim dFitPts() As Double Dim objBSpline As Object, obj2DProfile As Object Dim objPathComponent As Object, objPathComponents As Object 'Add a 2D Profile shape to the scene, if successful continue : If (Add2DProfileShape(Application, obj2DProfile)) Then 'Get the path components of the profile : Set objPathComponents = obj2DProfile.Components(triPath) 'Add a new path component for the geometry to be drawn to : Set objPathComponent = objPathComponents.Add 'Redimension the array of fit points and set them : ReDim dFitPts(1 To 3, 1 To 2) dFitPts(1, 1) = -1 'X Position of first fit point dFitPts(1, 2) = 0 'Y Position of first fit point dFitPts(2, 1) = 0 'X Position of second fit point dFitPts(2, 2) = 1 'Y Position of second fit point dFitPts(3, 1) = 1 'X Position of third fit point dFitPts(3, 2) = 0 'Y Position of third fit point 'Set the start point : objPathComponent.SetStartPoint -1, 0 'Add the B-Spline then set the defintion by fit points : Set objBSpline = objPathComponent.AddBSplineTo(dFitPts(3, 1), _ dFitPts(3, 2)) objBSpline.SetDefinitionByFitPoints 3, False, False, _ dFitPts, Nothing, Nothing

Page 46 of 104

IronCAD Customization: IronCAD Shape Creation


23 24 25 'Now add the line across the bottom to connect everyting : objPathComponent.AddLineTo -1, 0 End If

End Sub

The CurveBSpline object also has many properties associated with the B-Spline data that can be retrieved in the event that its information needs to be copied to another profile. This concludes the part on profile creation. Since the next few parts explain how to create specific shapes in IronCAD , it is important to fully understand how to create cross sections of desired geometry. Although the cross sections for the following parts will not be complicated since the goal of the next parts is to discuss how to create a shape, it is still important to understand the fundamentals of profile creation listed above so that more complicated profiles can be created.

Extrude Shapes
This part refers to the Shapes2.vbp project in the Example 7 directory in the accompanying source code.

Extrude shapes are the simplest shape to create in general. When creating an extrude shape there are essentially 4 things that need to be done to create and initialize the shape: Initialize Sizebox Initialize Position Initialize Anchor Create Profile Geometry

When creating IntelliShapes such as extrude shapes, first a part needs to be created to place the IntelliShape inside. When a block for instance is dropped from a catalog into an IronCAD scene, the block does not appear at the root level in the scene, a part is created around the block. It is important that when creating an IntelliShape a part be created first to place the IntelliShape in so that an IntelliShape does not exist at the scene level or in an assembly. For extrude shapes, spin shapes, loft shapes, sweep shapes and complex shapes, a part must be created first to place the IntelliShape in. The new few parts discussing shape creation will use 3 functions that are defined in the Globals.bas module in the project. These 3 functions are: SetShapePosition, SetShapeAnchor and InitializeSizebox. Since setting the position of a shape, anchor and size of a sizebox is a very frequently occurring Page 47 of 104

IronCAD Customization: IronCAD Shape Creation task when creating shapes these utility functions will be used throughout the rest of this section so that the code does not need to be typed redundantly. Since these functions will be used quite frequently lets take a look at them before continuing so that their purpose is understood. The first utility function is SetShapePosition. This function takes a shape and an X, Y and Z value to position the shape at. Below is the code:
Public Sub SetShapePosition(Shape As Object, X As Double, _ Y As Double, Z As Double) 1 2 3 4 5 6 Dim objPositionSC As Object 'Get the position shape component then set the position : Set objPositionSC = Shape.Components(triPosition).Item(1) objPositionSC.Variable(triX).Value = X objPositionSC.Variable(triY).Value = Y objPositionSC.Variable(triZ).Value = Z

End Sub

On line 3 the position component of the shape is set, then on the following 3 lines the X, Y and Z value of the position is set to the position component of the shape. The next utility function is SetShapeAnchor. This function is identical to the SetShapePosition function, only instead of using the position component of the shape, the anchor component of the shape is set:
Public Sub SetShapeAnchor(Shape As Object, X As Double, _ Y As Double, Z As Double) 1 2 3 4 5 6 Dim objAnchorSC As Object 'Get the anchor shape component then set the position : Set objAnchorSC = Shape.Components(triAnchor).Item(1) objAnchorSC.Variable(triX).Value = X objAnchorSC.Variable(triY).Value = Y objAnchorSC.Variable(triZ).Value = Z

End Sub

Once again, the code is an exact replica of the SetShapePosition function except for the component that is used so it should not be too difficult to grasp. The final function is InitializeSizebox takes 4 parameters as well, however instead of being a position they are the desired length, width and height of the sizebox. When initializing a sizebox it is also important to set which handles of the sizebox should be displayed and the display type of the sizebox. The InitializeSizebox function sets the length, width and height of the sizebox and initializes all the handles of the sizebox to be visible: Page 48 of 104

IronCAD Customization: IronCAD Shape Creation

Public Sub InitializeSizebox(Shape As Object, Length As Double, _ Width As Double, Height As Double) 1 2 3 4 5 6 7 8 9 10 11 12 Dim objSizeboxSC As Object 'Get the sizebox shape component then set the dimensions 'along with initializing the values : Set objSizeboxSC = Shape.Components(triSizeBox).Item(1) objSizeboxSC.Variable(triLength).Value = Length objSizeboxSC.Variable(triWidth).Value = Width objSizeboxSC.Variable(triHeight).Value = Height 'Next set the sizebox to display all handles : objSizeboxSC.Variable(triHideLengthHandles).Value = 0 objSizeboxSC.Variable(triHideWidthHandles).Value = 0 objSizeboxSC.Variable(triHideHeightHandles).Value = 0 objSizeboxSC.Variable(triDisplayType).Value = triBoxAndHandles

End Sub

The function is very similar to the previous 2 functions until line 9. Line 9 sets whether the length handle is visible or not, so it sets the hide variable to false. The variable is then set to false for the width and height handles as well. On line 12 the sizebox display type is set to display the box and handles of the display type. It is important to set the display type of the sizebox even thought the variables have been set to display the handles. Now with that out of the way it is time to create an extrude shape. The shape that is going to be created is a simple pipe, which is not too complex, but it does show the mechanics of shape creation. To the right is a picture of the shape created by the code. The code below is taken from the Extrude class in the Shapes2.vbp project:
Public Sub CreateExtrudeShape(Application As Object) 1 'Shapes : Dim objAssembly As Object, objExtrude As Object, _ objPart As Object, objProfile As Object 'Shape Components : Dim objGroupSC As Object, objHistorySC As Object, _ objProfileSC As Object, objPathSC As Object 'Make sure there is at least one scene open, if so continue : If (Application.Pages.Count > 0) Then Const RADIUS_INSIDE = 1, RADIUS_OUTSIDE = 1.25, HEIGHT = 5 'Set the top shape on the page which is an assembly and 'add a part to it to place the extrude in : Set objAssembly = Application.ActivePage.Shape Set objGroupSC = objAssembly.Components(triGroup).Item(1)

3 4 5 6 7 8

Page 49 of 104

IronCAD Customization: IronCAD Shape Creation


9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 Set objPart = objGroupSC.Shapes(triCompoundShape).Add 'Next add an extrude shape to the part that was just added : Set objHistorySC = objPart.Components(triHistory).Item(1) Set objExtrude = objHistorySC.Shapes(triExtrudeShape).Add 'Initialize the length and width of the sizebox to be the 'outside radius * 2 and the height to be the defined height : Globals.InitializeSizebox objExtrude, (RADIUS_OUTSIDE * 2), _ (RADIUS_OUTSIDE * 2), HEIGHT 'Next initialize the anchor to be in the middle of the sizebox 'which at the bottom : Globals.SetShapeAnchor objExtrude, RADIUS_OUTSIDE, RADIUS_OUTSIDE, 0 'Finally initialize the position to be 0, 0, 0 Globals.SetShapePosition objExtrude, 0, 0, 0 'Now that the basic components have been initialized, get 'the profile to draw the cross section on : Set objProfileSC = objExtrude.Components(triProfile).Item(1) Set objProfile = objProfileSC.Profile 'Next position the profile to be in the center of the sizebox so 'that the geometry can be drawn about 0, 0, 0 on the profile : Globals.SetShapePosition objProfile, RADIUS_OUTSIDE, _ RADIUS_OUTSIDE, 0 'Now draw the inside outline of the pipe : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddEllipse 0, 0, RADIUS_INSIDE 'Draw the outside outline of the pipe : Set objPathSC = objProfile.Components(triPath).Add objPathSC.AddEllipse 0, 0, RADIUS_OUTSIDE 'Finally update the shape so that it regenerates, then update the 'page so the newly created shape is rendered : objExtrude.Update Application.ActivePage.Update End If

End Sub

On line 3 a simple check is made to ensure that there is at least one page open so that there will be an active page. Line 4 declares some constants for the inside and outside radius of the pipe, along with the height of the pipe. Lines 7 through 9 add a part to the scene to create the extrude shape inside. The first thing that happends is the GroupComponent of the top assembly shape is set, then a part is added to the assembly. The part that was added to the scene was never positioned, nor was the sizebox or anchor set. The reason is that by default in IronCAD the sizebox of a part is not shown, only a sketch of the edges is shown. If desired the sizebox could be initialized but it is not commonly done in IronCAD . Page 50 of 104

IronCAD Customization: IronCAD Shape Creation Next on lines 11 and 12 an extrude shape is added to the part that was previously added to the scene. Unlike the assembly shape where the part was placed in the group component, the extrude shape needs to be placed in the history component of the part. On line 15 the sizebox of the extrude shape is initialized to twice the outside radius of the pipe so that the sizebox fits perfectly around the pipe. The anchor is then set in the middle of the sizebox on line 18 so that the pipe is nicely centered around the anchor. On line 20 the position of the extrude shape is placed at 0, 0, 0 inside the part so that the anchor of the extrude shape is exactly over the anchor of the part. Next on line 23 the ProfileComponent of the extrude shape is set and then on line 24 the variable objProfile is set to the Profile property of the ProfileComponent. The Profile property returns a 2D profile shape which was used in the previous part on profile creation. The extrude shape essentially holds on to a 2D profile shape which contains all the cross

section information for the extrude shape. Once the profile shape is set, everything that was learned previously in the Profile Creation part can now be applied to creating extrude shape geometry. Line 27 sets the position of the profile shape to be the same as the anchor position of the extrude shape so that the 0, 0 point on the profile is over the anchor of the extrude shape. Otherwise by default the 0, 0 point on the profile is over the bottom left hand corner of the sizebox. The diagram above shows the position of the profile before and after positioning it relative to the sizebox. The red arrows represent the X, Y and Zaxes of the sizebox. All of the code until line 37 should look familiar from the previous part, but then on line 37 the extrude shape is updated by calling the Update method on the extrude shape which generates the shape. Finally the page is updated by calling the Update method on the page so that the newly created shape is rendered. Those are the basics of creating an extrude shape. If the handles on the sizebox of the pipe created above from the code are then pulled, an undesirable sizing behavior is exhibited. The reason is because when the shape was created Page 51 of 104

IronCAD Customization: IronCAD Shape Creation all the values are hard coded on the profile. When an extrude shape or any other shape is created through the UI of IronCAD , the positions and dimensions of the profiles are specified by expressions to the sizebox. If the shape that is being created will be a shape that the user interacts with by pulling the handles, call the ResetSizebox method on the Shape object to make the profile geometry dependent on the sizebox which is the usual behavior an IntelliShape . However when calling the ResetSizebox method on a Shape object, the sizebox will automatically be resized to fit exactly around the shape.

Spin Shapes
This part refers to the Shapes2.vbp project in the Example 7 directory in the accompanying source code.

Spin shapes are created almost the same way that extrude shapes are created, below is the list of key things to do when creating spin shapes: Initialize Sizebox Initialize Position Initialize Anchor Create Profile Geometry Specify Spin Angle (if not 360)

Since the example used for creating an extrude shape was a pipe, the example used for creating a spin shape will be an elbow joint for the pipe. The elbow joint has the same inside and outside radius, however there are also 2 more additional parameters: spin angle and the radius of the elbow joint bend to the inside. The picture to the left shows the desired shape and the code below taken from the Spin class in the Shapes2.vbp project is the code used to generate the shape:
Public Sub CreateSpinShape(Application As Object) 1 'Shapes : Dim objAssembly As Object, objSpin As Object, _ objPart As Object, objProfile As Object 'Shape Components : Dim objGroupSC As Object, objHistorySC As Object, _ objProfileSC As Object, objPathSC As Object, _ objSolidSC As Object 'Make sure there is at least one scene open, if so continue : If (Application.Pages.Count > 0) Then

Page 52 of 104

IronCAD Customization: IronCAD Shape Creation


4 5 6 7 8 9 10 11 12 13 14 Const RADIUS_INSIDE = 1, RADIUS_OUTSIDE = 1.25, _ SPIN_ANGLE = 90, TURN_RADIUS = 0.5 'Set the top shape on the page which is an assembly and 'add a part to it to place the spin in : Set objAssembly = Application.ActivePage.Shape Set objGroupSC = objAssembly.Components(triGroup).Item(1) Set objPart = objGroupSC.Shapes(triCompoundShape).Add 'Next add a spin shape to the part that was just added : Set objHistorySC = objPart.Components(triHistory).Item(1) Set objSpin = objHistorySC.Shapes(triTurnShape).Add 'Initialize the sizebox : Globals.InitializeSizebox objSpin, (((RADIUS_OUTSIDE*2)+TURN_RADIUS)* 2), _ (((RADIUS_OUTSIDE*2)+TURN_RADIUS)* 2), _ (RADIUS_OUTSIDE * 2) 'Initialize the position of the anchor : Globals.SetShapeAnchor objSpin, ((RADIUS_OUTSIDE * 2) + TURN_RADIUS), _ ((RADIUS_OUTSIDE * 2) + TURN_RADIUS), _ RADIUS_OUTSIDE 'Initialize the position of the spin : Globals.SetShapePosition objSpin, 0, 0, 0 'Next initialize the spin angle of the spin shape by setting the 'solid component of the spin, then setting the angle : Set objSolidSC = objSpin.Components(triSweep).Item(1) objSolidSC.Variable(triAngle).Value = SPIN_ANGLE 'Get the profile to draw the cross section on : Set objProfileSC = objSpin.Components(triProfile).Item(1) Set objProfile = objProfileSC.Profile 'Position the profile : Globals.SetShapePosition objProfile, ((RADIUS_OUTSIDE*2)+TURN_RADIUS), _ ((RADIUS_OUTSIDE*2)+TURN_RADIUS), _ RADIUS_OUTSIDE 'Draw the inside outline of the pipe elbow : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint (RADIUS_OUTSIDE + TURN_RADIUS), 0 objPathSC.AddEllipse (RADIUS_OUTSIDE + TURN_RADIUS), 0, RADIUS_INSIDE 'Draw the outside outline : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint (RADIUS_OUTSIDE + TURN_RADIUS), 0 objPathSC.AddEllipse (RADIUS_OUTSIDE + TURN_RADIUS), 0, RADIUS_OUTSIDE 'Update the shape and page : objSpin.Update Application.ActivePage.Update End If

15 16

17 18 19 20 21 22 23 24 25 26 27

28 29 30 31 32 33 34 35 36 37 38 39

End Sub

Page 53 of 104

IronCAD Customization: IronCAD Shape Creation

All of the code until line 12 should look very familiar, except for the constants that are defined. On line 12 instead of adding an extrude shape, a spin shape is added to the part. Next on lines 13 through 18 the sizebox, position and anchor of the spin shape are initialized very similar to the way the sizebox, position and anchor were initialized previously. Then on line 21 and 22 the solid component of the spin shape is set and then the angle of the spin is set. The solid component of a shape is very important since it also holds whether the shape adds or removes material, and many other attributes of a shape. There is another variable inside the solid component called triOperationType which can be set to one of the values listed in the EyeShapeOperationTypes enum in the IronCAD Type Library. By default the shape is set to add material. Finally in lines 24 through 38 the profile shape component is set and then the geometry of the profile is drawn which should be familiar process by now. That is all that there is to creating spin shapes, nothing too complicated.

Sweep Shapes
This part refers to the Shapes2.vbp project in the Example 7 directory in the accompanying source code.

Sweep shapes are a little more complicated to create because instead of only having to create one set of geometry on a profile, two sets of geometry need to be created. The first profile that needs geometry to be created is for the path that a cross section is swept along. The other profile which geometry needs to be created for is the actual cross section that is being swept along the path. There are 5 basic parts to creating sweep shapes: Initialize Sizebox Initialize Position Initialize Anchor Create Path Geometry Create Cross Section Geometry

The five steps are very identical to the previous steps for creating shapes. The following example continues with the concept of a pipe, but this time a connecting piece of pipe will be made, using the same dimensions as before for the pipes inside and outside radii. A picture of the pipe connector being created is shown to the right and the code for creating the pipe is below taken from the Sweep class in the Shapes2.vbp project:
Public Sub CreateSweepShape(Application As Object)

Page 54 of 104

IronCAD Customization: IronCAD Shape Creation


'Shapes : Dim objAssembly As Object, objSweep As Object, _ objPart As Object, objSweepProfile As Object, _ objProfile As Object 'Shape Components : Dim objGroupSC As Object, objHistorySC As Object, _ objProfileSC As Object, objPathSC As Object, _ objPathSweepSC As Object 'Make sure there is at least one scene open, if so continue : If (Application.Pages.Count > 0) Then Const RADIUS_INSIDE = 1, RADIUS_OUTSIDE = 1.25, _ LENGTH = 6, TURN_RADIUS = 0.5, LIP = 0.25 'Set the top shape on the page which is an assembly and 'add a part to it to place the sweep in : Set objAssembly = Application.ActivePage.Shape Set objGroupSC = objAssembly.Components(triGroup).Item(1) Set objPart = objGroupSC.Shapes(triCompoundShape).Add 'Next add a sweep shape to the part that was just added : Set objHistorySC = objPart.Components(triHistory).Item(1) Set objSweep = objHistorySC.Shapes(triGeneralSweepShape).Add 'Initialize the sizebox for the sweep : Globals.InitializeSizebox objSweep, (LENGTH+(RADIUS_OUTSIDE * 2)), _ (RADIUS_OUTSIDE * 2), _ ((LIP *2)+(TURN_RADIUS * 2)+ _ (RADIUS_OUTSIDE * 2)) 'Initialize the anchor for the sweep : Globals.SetShapeAnchor objSweep, RADIUS_OUTSIDE, RADIUS_OUTSIDE, 0 'Initialize the position for the sweep : Globals.SetShapePosition objSweep, 0, 0, 0 'Next set the profile component and get the profile and 'create the cross section that will be swept along the path : Set objProfileSC = objSweep.Components(triProfile).Item(1) Set objProfile = objProfileSC.Profile 'Position the profile where the anchor was positioned : Globals.SetShapePosition objProfile, RADIUS_OUTSIDE, _ RADIUS_OUTSIDE, 0 'Create the inside outline of the pipe : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddEllipse 0, 0, RADIUS_INSIDE 'Create the outside outline of the pipe : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddEllipse 0, 0, RADIUS_OUTSIDE

3 4 5 6 7 8 9 10 11 12 13 14 15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

Page 55 of 104

IronCAD Customization: IronCAD Shape Creation


34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 'Next set the sweep path component then get the sweep 'path and the path that the cross section above will be 'swept along : Set objPathSweepSC = objSweep.Components(triPathSweep).Item(1) Set objProfile = objPathSweepSC.Profile 'Position the sweep path where the profile being swept along it is : Globals.SetShapePosition objProfile, RADIUS_OUTSIDE, _ RADIUS_OUTSIDE, 0 'Create the path that is being swept along : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddLineTo 0, (RADIUS_OUTSIDE + TURN_RADIUS + LIP) objPathSC.AddLineTo LENGTH, (RADIUS_OUTSIDE + TURN_RADIUS + LIP) objPathSC.AddLineTo LENGTH, _ ((RADIUS_OUTSIDE + TURN_RADIUS + LIP) * 2) objPathSC.AddFilletAt 2, (RADIUS_OUTSIDE + TURN_RADIUS) objPathSC.AddFilletAt 4, (RADIUS_OUTSIDE + TURN_RADIUS) 'Update the shape and page now : objSweep.Update Application.ActivePage.Update End If

End Sub

Once again the code should look familiar until line 13 where the sweep shape is added to the part. Lines 15 through 19 initialize the 3 basic components: sizebox, anchor and position very similarly to the way the previous shapes had their sizebox, anchor and positions initialized with different values of course. Lines 21 through 33 get the profile that is swept along the path and create the pipe cross section. This code is identical to the previous spin shape example. Then on lines 37 and 38 the profile that contains the sweep path is set. Then the code starts to look familiar again on line 40 when the position of the sweep path is set and the shape and page are then updated on lines 50 and 51. This was the most code seen so far for the creation of a single shape and loft shapes discussed next require much more code to create a single shape.

Loft Shapes
So far 3 pipe components have been created and now one more will be created to demonstrate loft shapes. Loft shapes creation can vary depending on the desired outcome either the cross sections can be placed on the curve specified by a parametric value on the curve, or the cross sections can be implicitly positioned by the source code. The basic steps are below: Initialize Sizebox Initialize Position Page 56 of 104

IronCAD Customization: IronCAD Shape Creation Initialize Anchor Create Profile Geometry Create Profile Geometry Insert Cross Sections In Set Match Points Create Profile Geometry

For First Cross Section For Last Cross Section The Middle And Create Geometry For Guide Curve

There is much more involved in the creation of a loft shape, than in any other shape. The main thing to remember about loft shapes is that the geometry for the first cross section is created first and the geometry for the last cross section (whether it is cross section 2 or cross section 20) is created second. Then profiles are added and inserted in between the first and last cross sections and then their geometry is created. Once that is done, the match points of the loft cross sections must be set manually so that a the modeling kernel knows which paths to link from one cross section to the next. To the left is a picture of what will be created in the following example it is an adapter that will go from the pipe to an exhaust vent perhaps. Regardless, it is a shape and the purpose it serves in life is to be the same size of the pipe on one end and look impressive. The code below is taken from the Loft class in the Shapes2.vbp project:
Public Sub CreateLoftShape(Application As Object) 'Shapes : 1 Dim objAssembly As Object, objLoft As Object, _ objPart As Object, objProfile As Object 2 'Shape Components : Dim objGroupSC As Object, objHistorySC As Object, _ objProfileSC As Object, objPathSC As Object, _ objProfileGroupSC As Object, objLoftSC As Object, _ objLoftSectionSC As Object 'Make sure there is at least one scene open, if so continue : If (Application.Pages.Count > 0) Then Const RADIUS_INSIDE = 1, RADIUS_OUTSIDE = 1.25, HEIGHT = 5, _ END_OUTSIDE_LENGTH = 6, END_INSIDE_LENGTH = 5.5, _ END_OUTSIDE_WIDTH = 2.5, END_INSIDE_WIDTH = 2 'Set the top shape on the page which is an assembly and 'add a part to it to place the extrude in : Set objAssembly = Application.ActivePage.Shape Set objGroupSC = objAssembly.Components(triGroup).Item(1) Set objPart = objGroupSC.Shapes(triCompoundShape).Add 'Next add an extrude shape to the part that was just added : Set objHistorySC = objPart.Components(triHistory).Item(1) Set objLoft = objHistorySC.Shapes(triLoftShape).Add

3 4

5 6 7 8 9 10 11 12

Page 57 of 104

IronCAD Customization: IronCAD Shape Creation


13 14 'Initialize the sizebox of the loft : Globals.InitializeSizebox objLoft, END_OUTSIDE_LENGTH, _ END_OUTSIDE_WIDTH, _ HEIGHT 'Initialize the position of the loft : Globals.SetShapePosition objLoft, 0, 0, 0 'Initialize the anchor of the loft : Globals.SetShapeAnchor objLoft, (END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2), _ 0 'Next get the 2 profiles that are placed in a loft shape by default 'which correspond to the first and last profiles, and set their 'positions and geometry : Set objProfileGroupSC = objLoft.Components(triProfileGroup).Item(1) Set objProfile = objProfileGroupSC.Shapes(triProfileShape).Add Set objLoftSectionSC = objProfile.Components(triLoftSection).Add 'Set the position of the first profile : Globals.SetShapePosition objProfile, (END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2), _ 0 'Draw the inside pipe outline : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddEllipse 0, 0, RADIUS_INSIDE 'Draw the outside pipe outline : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddEllipse 0, 0, RADIUS_OUTSIDE 'Next get the last profile in the loft : Set objProfile = objProfileGroupSC.Shapes(triProfileShape).Add Set objLoftSectionSC = objProfile.Components(triLoftSection).Add 'Set the position of the profile : Globals.SetShapePosition objProfile, (END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2), _ HEIGHT 'Draw the inside outline of the last profile : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint -(END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo (END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo (END_OUTSIDE_LENGTH / 2), _ -(END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_OUTSIDE_LENGTH / 2), _ -(END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2)

15 16 17 18

19 20 21 22 23 24 25 26

27 28 29 30 31 32 33 34 35 36 37 38 39

40 41 42 43 44 45 46

Page 58 of 104

IronCAD Customization: IronCAD Shape Creation


47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 'Next draw the outside outline of the last profile : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint -(END_INSIDE_LENGTH / 2), _ (END_INSIDE_WIDTH / 2) objPathSC.AddLineTo (END_INSIDE_LENGTH / 2), (END_INSIDE_WIDTH / 2) objPathSC.AddLineTo (END_INSIDE_LENGTH / 2), -(END_INSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_INSIDE_LENGTH / 2), -(END_INSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_INSIDE_LENGTH / 2), (END_INSIDE_WIDTH / 2) 'Next set the loft component of the loft so that two more 'cross sections can be added to the loft to make the loft 'from the circle to the rectangle more gradual : Set objLoftSC = objLoft.Components(triLoft).Item(1) 'Add the second profile to the loft and once again position it and 'set the geometry of it : Set objProfile = objLoftSC.InsertSection(2) 'Position the second cross section : Globals.SetShapePosition objProfile, (END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2), _ (HEIGHT / 5) 'Draw the inside pipe outline : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddEllipse 0, 0, RADIUS_INSIDE 'Draw the outside pipe outline : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddEllipse 0, 0, RADIUS_OUTSIDE 'Now add the third profile to the loft and once again position 'it and set the geometry of it : Set objProfile = objLoftSC.InsertSection(3) 'Position the third cross section : Globals.SetShapePosition objProfile, (END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2), _ (4 / 5 * HEIGHT) 'Draw the inside outline of the third profile : Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint -(END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo (END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo (END_OUTSIDE_LENGTH / 2), _ -(END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_OUTSIDE_LENGTH / 2), _ -(END_OUTSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_OUTSIDE_LENGTH / 2), _ (END_OUTSIDE_WIDTH / 2) 'Next draw the outside outline of the third profile :

64 64 65 66 67 68 69 70 71 72 73 74 75

76 77 78 79 80 81 82 83

Page 59 of 104

IronCAD Customization: IronCAD Shape Creation


84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint -(END_INSIDE_LENGTH / 2), _ (END_INSIDE_WIDTH / 2) objPathSC.AddLineTo (END_INSIDE_LENGTH / 2), (END_INSIDE_WIDTH / 2) objPathSC.AddLineTo (END_INSIDE_LENGTH / 2), -(END_INSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_INSIDE_LENGTH / 2), -(END_INSIDE_WIDTH / 2) objPathSC.AddLineTo -(END_INSIDE_LENGTH / 2), (END_INSIDE_WIDTH / 2) 'Now the match points need to be added : Dim i As Integer For i = 1 To 3 'Set the profile from the list of profiles in the loft : Set objProfile = objProfileGroupSC.Shapes.Item(i) 'Set the match point for the inside outline : Set objPathSC = objProfile.Components(triPath).Item(1) objPathSC.SetMatchPoint 1, 1 'Set the match point for the outside outline : Set objPathSC = objProfile.Components(triPath).Item(2) objPathSC.SetMatchPoint 2, 1 Next 'Finally the guide curve must be set If (objLoft.Components(triProfile).Count > 0) Then Set objProfileSC = objLoft.Components(triProfile).Item(1) Else Set objProfileSC = objLoft.Components(triProfile).Add End If Set objProfile = objProfileSC.Profile Set objPathSC = objProfile.Components(triPath).Add objPathSC.SetStartPoint 0, 0 objPathSC.AddLineTo 0, HEIGHT 'Update the shape and page : objLoft.Update Application.ActivePage.Update

115 End If End Sub

This shape is going to take some explaining, the number of lines of code more than doubled from the sweep shape but this was not supposed to be easy. The code until line 12 once again should look familiar. A part is simply placed into the scene and then a loft shape is added to the part. Then on lines 13 through 18 the sizebox, position and anchor are initialized just like they were in all the previous shapes, so thus far everything should be okay. Then on line 22 the profile group component of the loft shape is set. The component that is returned is actually a GroupComponent, however the only methods that can be used on it are the Add and Item methods since they are the only methods that make sense. This component essentially holds onto all of the profiles that a loft shape consists of. Next on line 23 a new profile shape is added to the group. The profile that is being added will be the first profile in the loft, regardless of what profiles get Page 60 of 104

IronCAD Customization: IronCAD Shape Creation added later. Next on line 24 a loft section component is added to the profile. This component is never used by the code, but the component must be added to the profile shape so that the profile shape knows it is a cross section in a loft. If this component is not added then setting the match points on lines 92 to 101 will fail and IronCAD will return an error message. Then on lines 25 through 34 the profile is positioned and the geometry for the cross section is created on it. That code should look familiar. Next on line 36 another profile shape is added to the profile group component for the loft and once again a loft section component is added to it. This is the second shape that was added to the profile group component and therefor will always be the last cross section no matter how many cross sections are added to the loft in the future. Lines 38 through 53 position the profile and create the geometry for the cross section in the same way that it was done for the first loft profile that was added. Now the code starts to change. Line 37 gets the loft component of the loft shape and sets it to the variable objLoftSC. The object returned is the LoftComponent listed in the IronCAD type library. The reason the loft component is set is because if there are more than 2 profiles in a loft, subsequent profiles must be added by calling the InsertSection method on the LoftComponent object. The reason for this is that subsequent profiles must be added at an index in the current set of profiles. For this reason, the Add method on the profile group component can not be used for adding additional profiles to the loft after the first two are added. On line 60 the third profile is added to the loft and placed in the 2nd position of the profiles that create the loft. The code from lines 52 to 70 is exactly the same as the code when the first profile was added, except for the position is different. The only thing that has changed is that the profile was not added using the Add method on the profile group component, it was added using the InsertSection method of the loft component. Now on line 73 the fourth and final profile is added to the loft and is set at index 3. The significance of the indices is that the loft will be created starting with the profile at index 1 and finishing at the profile with index 4. Lines 75 to 89 should once again be very familiar since the exact code was used to initialize the second profile that was added using the Add method of the profile group component originally, the only thing that has changed is the positioning. As a recap of what has happened so far, four profiles have been added to the loft shape. The first two profiles added where added using the Add method on the profile group component of the loft shape, then initialized. These profiles that were added using the Add method will always be the first and last profile in the loft respectively. Next, two more profiles were added to the loft shape to reach the total of four, only these two profiles were added using the InsertSection method on the loft component of the loft shape. These profiles were inserted at index 2 and then at index 3 respectively and then were initialized.

Page 61 of 104

IronCAD Customization: IronCAD Shape Creation

The difficult part to understand comes in lines 91 through lines 101 when the match points are set. Setting match points in a loft determine which loop in one cross section gets lofted to which loop in the next cross section. The code loops 3 times because loop 1 and loop 2 on the first profile pictured at left must be mapped to loop 1 and loop 2 on the second profile. Then loop 1 and loop 2 on the second profile must be mapped to loop 1 and loop 2 in the third profile. Finally loop 1 and loop 2 on the third profile must be mapped to loop 1 and loop 2 on the fourth profile. That is where it ends though because loop 1 and loop 2 on the fourth profile can not be mapped to any loops since the fourth profile is the last profile. For that reason, the code only loops 3 times since there is no fifth profile for fourth profile to map to. In the code for creating the cross sections of the loft, the inside path was always created first, then the outside path was created so that the inside path would always be loop 1 and the outside path would always be loop 2. If in one of the profiles the inside and outside paths were created in reversed order, then when the code on lines 91 through 101 executed it would produce an invalid shape because the outside loop of one profile would be mapped to the inside loop of the next profile and the body would shape inverted at one end and intersect itself. The parameters of the SetMatchPoint method on the PathComponent object are the index of that path component to match to on the next profile in the profile group component of the loft shape, and then the index of the loop to start with if not 1. If the index of the path (or loop) is passed in first, always pass 1 for the second parameter, which is the simplest way to remember how to use the method. Next on lines 102 to 111 the guide curve of the loft is set up. The guide curve is used when the positions of the profiles in the loft are defined parametrically by a relative position on the curve 0 being the beginning and 1 being the end of the curve. To position a profile parametrically on the curve there is a method called SetParamValue on a PathComponent object which sets the position of that path at a relative position on the curve. Finally on lines 113 and 114 the shape is updated and then the page is updated. Loft shapes are much more complicated compared to the other three shapes previously discussed before loft shapes and hopefully this helped understand loft shapes more. If there is a particular loft shape that is trying to be created and for some reason it just is not working out, model the shape first in IronCAD and then select the part that the loft shape is in. On the File menu go to Export and select Export Part. From the list of available exports choose Visual Basic file (*.bas) which will export

Page 62 of 104

IronCAD Customization: IronCAD Shape Creation a Visual Basic program that creates the part using what has been discussed in this section.

Complex Shape
Unlike its name suggests it is not a shape that has a complex. Its a shape that is placed in a part that does not have a single operation like most shapes. The complex shape has a history component, which allows several IntelliShapes to be added to it. Then, when the complex shape is placed inside of a part, it does not have either an add or subtract operation, instead the shapes in its history component are added to the part which the complex shape is in one at a time. The result is a shape that is capable of adding and removing material at the same time, very similar to the way the Sheet Metal forming shapes work. Next Add-Ons in IronCAD are discussed which become more fun. Someone had to go this far.

Page 63 of 104

IronCAD Customization: IronCAD Add-Ons

IronCAD Add-Ons
Introduction
There are essentially two types of Add-Ons that can be placed in the catalog. The first is placing a shape in the catalog which has events associated such as drop associated with a Visual Basic object, so that when the shape is dropped out of a catalog a method on the object associated with the shape is invoked. The other is an empty catalog entry which does not have a shape associated with it. Instead when dropped onto another shape in the scene, a Visual Basic object associated with the catalog entry has a method invoked on it and the shape that the catalog entry was dropped on is passed to the Visual Basic object. Both of these methods will be discussed in the following parts.

Creating Catalog Entries


This part refers to the project AddOns.vbp in the Example 8 directory in the accompanying source code.

The first step in creating an Add-On tool that is catalog based is creating the catalog entry for the Add-On tool. There are typically two ways this is done, the first is to create a shape with an Add-On component and place the shape in the catalog. An Add-On component is a component that holds on to a Class ID of a Visual Basic object. Depending on what the UI behavior of the shape is set to, if the shape is dropped from a catalog a call will be made to the Visual Basic object notifying it that the shape was dropped. There are several other events that are raised which can be received as well. The second way of creating a catalog entry is to place an Add-On component into the catalog, without placing a shape into the catalog. Once again a Class ID will be associated with the Add-On component, however no shape will be dropped out into the scene. This is useful when a tool needs to be created where the user would like to just drag and drop the catalog entry onto a shape that needs to be modified by the tool. The first approach of placing a shape with an Add-On component in the catalog will be discussed first. The Add-On component may be placed on any type of shape. Generally, it is usually placed on an empty part that is then placed into the catalog. The reason an empty part is used is because the majority of the time a tool would create something based on where the user dropped the tool at, so by dropping an empty part it allows the position of where the user dropped the tool at to be retrieved. The empty part also allows the parent of the shape that the tool was dropped in to be set. For instance, if a user drops the tool into an assembly, it is then possible to find out the parent that the empty part was dropped in to. Since there are no IntelliShapes in the part, it is very quick to drop it since regeneration does not Page 64 of 104

IronCAD Customization: IronCAD Add-Ons need to happen and it provides a nice hook into IronCAD . Before continuing, be sure to compile the project AddOns.vbp so that the registry entries and Class IDs are created. The code below is taken from the AddOn1 class in the AddOns.vbp project:
Public Sub CreateCatalogEntry(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 Dim Dim Dim Dim Dim Dim Dim objPart As Object objPage As Object objCatalog As Object objGroupSC As Object objAddOnSC As Object objUIBehaviorSC As Object objCatalogEntry As Object

'Make sure there is at least one catalog and one page : If ((Application.Pages.Count > 0) And _ (Application.Catalogs.Count > 0)) Then 'Set the active page and active catalog : Set objPage = Application.ActivePage Set objCatalog = Application.ActiveCatalog 'Get the group shape component of the top assembly : Set objGroupSC = objPage.Shape.Components(triGroup).Item(1) 'Next add a part to the scene : Set objPart = objGroupSC.Shapes(triCompoundShape).Add 'Add the Add-On component and specify the Class ID of 'the Add-On component. '!!! THE CLASS ID USED HERE WILL NOT BE THE SAME ONE 'THAT NEEDS TO BE USED ON OTHER COMPUTERS. COMPILE 'THIS PROJECT THEN LOOK IN THE REGISTRY EDITOR FOR 'THE CLASS ID!!! Set objAddOnSC = objPart.Components(triAddOn).Add objAddOnSC.Variable(triClassID).Value = _ "{602DDC6A-B22E-11D2-9034-00A0240B6602}" 'Now add a UI behavior component and set which events 'should be handled by this object : Set objUIBehaviorSC = objPart.Components(triUIBehavior).Add objUIBehaviorSC.Variable(triDropEvent).Value = triExecuteAddOn 'Now add the empty part to the catalog : Set objCatalogEntry = objCatalog.Entries.Add(objPart) objCatalogEntry.Label = "Add-On 1" 'Delete the part from the scene : objGroupSC.Shapes.Remove objPart End If

End Sub

Page 65 of 104

IronCAD Customization: IronCAD Add-Ons This code is very simple compared to the code seen previously. All the code should be relatively familiar until line 23 when the Add-On component is added to the part. Then the Class ID of the AddOn1 class is set on line 24. Keep in mind that the value shown here WILL NOT be the same since it is machine dependent, so the value needs to be looked up in the Windows Registry Editor before continuing. Next a UI behavior component is added to the part on line 27 and the drop event of the shape is set to call the Add-On which is the object specified by the Class ID set earlier. Then in lines 30 and 31 the part is added to the catalog and a generic label is given to it. Finally on line 33 the dummy part that was created in the scene is removed. Now when the part is dropped from the catalog it will create an instance of the Visual Basic object specified by the Class ID, but now it needs a method to invoke on the Visual Basic object to notify it that a shape has been dropped. There must be a method on the Visual Basic object specified with the following prototype :
Public Sub Drop(Shape As Object, X As Long, Y As Long) End Sub

The parameter Shape will be set to the shape that is being dropped from the catalog, and the X and Y are the logical screen coordinates that the shape is dropped at in case a dialog box needs to be displayed at the drop position. There will be more discussion on the events and how to handle them in the next part on Handling Shape Events, this part focuses mainly on creating the catalog entry. The next approach to creating a catalog based Add-On is placing an Add-On component into the catalog. The component when dropped from the catalog will create an instance of the Visual Basic object specified and once again call the prototype listed above for the Drop method. However, instead of passing the shape that is being dropped from the catalog into the Shape variable, the shape that the catalog entry is dropped on is passed in to the Shape variable. If the catalog entry is dropped on the scene, then the top assembly in a scene is passed to the Drop method. Below is source code taken from the AddOn2 class in the AddOns.vbp project:
Public Sub CreateCatalogEntry(Application As Object) 1 2 3 4 5 6 7 Dim objCatalog As Object Dim objAddonSC As Object Dim objCatalogEntry As Object 'Continue if there is at least one catalog : If (Application.Catalogs.Count > 0) Then 'Set the active catalog : Set objCatalog = Application.ActiveCatalog

Page 66 of 104

IronCAD Customization: IronCAD Add-Ons


8 9 10 11 12 13 14 15 16 17 'Create a new instance of an Add-On component : Set objAddonSC = Application.CreateAddOn 'Set the Class ID of the Add-On and the drop event to 'execute the addon associated with it : objAddonSC.Variable(triClassID).Value = _ "{602DDC6C-B22E-11D2-9034-00A0240B6602}" objAddonSC.Variable(triDropEvent).Value = triExecuteAddOn 'Add the Add-On to the catalog : Set objCatalogEntry = objCatalog.Entries.Add(objAddonSC) objCatalogEntry.Label = "Add-On 2" End If

End Sub

That was much simpler than the first example that placed the Add-On component on a shape then placed the shape in a catalog. The only thing that should be new is line 9. On line 9 the method CreateAddOn on the Application object is called which returns an Add-On component. The component returned is the generic Component object in the IronCAD Type Library. Line 13 assigns the drop event to triExecuteAddon which is a constant defined in the EyeEventActions enum in the IronCAD Type Library. When this catalog entry is dropped from the catalog now, an instance object specified by the Class ID will be created and the Drop prototype on the object will be invoked. If the method is not there then nothing will happen. That is all there is to know about creating the catalog entries for AddOns. The next part will discuss how to handle the events raised by the shapes and how to set which events to handle.

Handling Shape Events


This part refers to the project AddOns.vbp in the Example 8 directory in the accompanying source code.

Setting up which events to handle is a relatively simple task. First the UI behavior component of the shape must be set and from there the 5 basic events can be set so that the Add-On component of the shape handles the events. The object specified by the Class ID in the Add-On component must support the method that the event requires being on the object for the object to be notified. Below is a table of the events defined in the EyeBehaviorComponentVariables enum and the function prototypes required for the event: Shape Events And Required Function Prototypes
triDropEvent triDoubleClickEvent triPreUpdateEvent Public Sub Drop(Shape As Object, X As Long, Y As Long) Public Sub DblClick(Shape As Object, X As Long, Y As Long) Public Sub PreUpdate(Shape As Object)

Page 67 of 104

IronCAD Customization: IronCAD Add-Ons


triUpdateEvent Public Sub Update(Shape As Object) triPostUpdateEvent Public Sub PostUpdate(Shape As Object) Public Sub DroppedOn(Shape As Object, X As Long, Y As Long, DroppedShape As Object)

The last function prototype listed in the table does not have a shape event associated with it that must be set. If the Visual Basic object specified by the Class ID in the Add-On component has this function prototype, then if a shape is dropped on to the shape with the Add-On component the Visual Basic object is notified through that prototype. The shape being dropped from the catalog, as well as the shape that the incoming shape was dropped on are passed as parameters in the function prototype. This event is only raised if the shape with the Add-On component is inside a part at the time of the drop. The following code that assigns all of the shape events to the first selected shape in the active scene is taken from the AddOn3 class in the AddOns.vbp project. Please note once again that before continuing the project must be compiled if it has not already been compiled and the constant CLASSID specified in the code must be set to the Class ID of the object on the machine being used to run this example:
Public Sub AssignEvents(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Const CLASSID = "{602DDC77-B22E-11D2-9034-00A0240B6602}" Dim objPage As Object Dim objShape As Object Dim objAddOnSC As Object Dim objUIBehaviorSC As Object 'Make sure there is at least on page : If (Application.Pages.Count > 0) Then 'Set the page and if there is a selected shape then continue : Set objPage = Application.ActivePage 'If there is a selected shape then continue : If (objPage.SelectedItems(triShape).Count > 0) Then 'Set the UI Behavior component and set the Add-On events : Set objShape = objPage.SelectedItems(triShape).Item(1) 'See if the shape has a UI behavior component already. 'If not then add one : If (objShape.Components(triUIBehavior).Count > 0) Then Set objUIBehaviorSC = _ objShape.Components(triUIBehavior).Item(1) Else Set objUIBehaviorSC = objShape.Components(triUIBehavior).Add End If 'Assign all of the events to notify this object : Dim iBehavior As Integer iBehavior = triExecuteAddon

Page 68 of 104

IronCAD Customization: IronCAD Add-Ons


24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 objUIBehaviorSC.Variable(triDropEvent).Value = iBehavior objUIBehaviorSC.Variable(triDoubleClickEvent).Value = iBehavior objUIBehaviorSC.Variable(triPreUpdateEvent).Value = iBehavior objUIBehaviorSC.Variable(triUpdateEvent).Value = iBehavior objUIBehaviorSC.Variable(triPostUpdateEvent).Value = iBehavior 'Now see if the shape has an Add-On component and if 'so use the current one else add one : If (objShape.Components(triAddOn).Count > 0) Then Set objAddOnSC = objShape.Components(triAddOn).Item(1) Else Set objAddOnSC = objShape.Components(triAddOn).Add End If 'Specify the Class ID of this object : objAddOnSC.Variable(triClassID).Value = CLASSID End If End If

End Sub

The code should all be familiar by now. Lines 1 through 13 make sure there is an active page and if so set the first selected shape. Then lines 15 through 20 check to see if there is a UI Behavior component, if so it uses the current one or else it adds a UI Behavior component to the shape. The all the events are assigned to notify the Visual Basic object specified in lines 31 through 37 which assign the Add-On component if one does not already exist on the shape and specify the Class ID. Basically, the code assigns the Class ID of itself to the Add-On component and also inside of the AddOn3 class all the events prototypes are handled as well. Below is the code that handles the events, a message box is simply displayed with the name of the shape :
Public Sub Drop(Shape As Object, X As Long, Y As Long) MsgBox "AddOn3 - Drop(" & Shape.Name & ")" End Sub Public Sub DblClick(Shape As Object, X As Long, Y As Long) MsgBox "AddOn3 - DblClick(" & Shape.Name & ")" End Sub Public Sub PreUpdate(Shape As Object) MsgBox "AddOn3 - PreUpdate(" & Shape.Name & ")" End Sub Public Sub Update(Shape As Object) MsgBox "AddOn3 - Update(" & Shape.Name & ")" End Sub Public Sub PostUpdate(Shape As Object) MsgBox "AddOn3 - PostUpdate(" & Shape.Name & ")" End Sub

Page 69 of 104

IronCAD Customization: IronCAD Add-Ons


Public Sub DroppedOn(Shape As Object, X As Long, Y As Long, _ DroppedShape As Object) MsgBox "AddOn3 - DroppedOn(" & Shape.Name & "," & DroppedShape.Name & ")" End Sub

One thing worth mentioning is that if a shape has an AddOn component, and the double click event is set to execute the Add-On, then when a user right clicks on the shape there is a new menu item appended to the right click menu which is Add-on Properties. When this menu item is selected the DblClick prototype on the Visual Basic object specified by the Add-On components Class Id is invoked and the shape passed in will be the shape that the user right clicked. This provides an easy mechanism for users to activate the Add-On instead of just double clicking the shape. That about wraps up all there is about catalog based Add-Ons as well. The code that is being used by now should be understood even though the components are new. The next section discusses how to create custom Sheet Metal punch and form shapes which is closely related to the way Add-Ons work so an understanding of this section is critical for the next section.

Page 70 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture

IronCAD Sheet Metal Architecture


Introduction
Creating custom Sheet Metal punch and form shapes works very similarly to the way Add-Ons are created. A shape is created and placed into the catalog with an Add-On component and as the user performs certain operations on the Sheet Metal shape, events are raised and the Visual Basic object associated with the Sheet Metal shape is notified of the events. Up until this point the only Type Library that has been referenced is the IronCAD Type Library, but to create a custom Sheet Metal shape two more Type Libraries need to be referenced. In the References dialog, look for two more entries, one is labeled IronCAD - Sheet Metal Definitions and the other is labeled IronCAD - Sheet Metal Utilities. Both of these type libraries must be referenced to create a custom Sheet Metal shape whether that shape is a punch or a forming shape. The tool table file is also a very important part of Sheet Metal. The tool table file is called tooltbl.txt and should be located in the directory that IronCAD is installed in. This file will be referred to frequently in the following parts so it may help to open the file now.

Tooling File
The purpose of the tooling file is to provide a mechanism, which allows the standards of a punch or form shape to be edited. The way that Sheet Metal shapes work in general is that each shape is first assigned a Table ID. The Table ID must be defined in the tooling file as a Tool Table. The format of the tooling file is fairly simple, essentially it is just a list of values that are the standards of a particular Sheet Metal shape, but these values could also be the most frequently used values by an end user of the Sheet Metal shape. The tooling file is a public file meaning any user should be able to edit it and change the values so the desired standards are available in the Tooling Properties dialog for any Sheet Metal shape. It is important however to note that the fields in the tooling file are tab delimited and that the fields are not separated by spaces, but tabs. At the top of the tooling file a description of all the fields are given so that will not be discussed here since creating a Sheet Metal shape is much more fun than reading about one!

Punch Shapes
This part refers to the SheetMetal1.vbp project in the Example 9 directory in the accompanying source code

Between punch and forming shapes, punch shapes are without a doubt the easiest to create. Below the basic steps in creating a punch shape: Page 71 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture

Create a new entry in the tooling file with a unique Table ID Create the initial state of the punch shape and place it in a catalog Implement the ISMExtrude interface to handle the events for the punch The first part, which is creating a new entry in the tooling file with a unique Table ID is the simple part. Next the initial state of the punch shape needs to be created. This means that a punch shape should be created with the parameters equal to the values in the first row in the tooling file for the specified Table ID that the punch corresponds to. Also, a Class ID of a Visual Basic object that needs to be notified must be specified in the Add-On component of the Sheet Metal Shape. Finally the ISMExtrude interface needs to be implemented on the Visual Basic object assigned to the punch shape in the previous step. The ISMExtrude interface is defined in the IronCAD - Sheet Metal Utilities Type Library. To the right a picture of the punch that will be created in this part is displayed. The geometry is fairly simple and there are two user- specified values. With all that said and done it is time to create the punch. The first step is to place a new entry in the tooling file for the punch shape. Below is the text that should be entered into the tooling file. Numbers have been placed next to the lines below for the purpose of this discussion but should not be placed in the tooling file: 1 2 3 4 5 6 7 8 9 10 11 12 Begin TableID Title Units ColHead Measure ToolTable 2000 "SheetMetal1 - Punch" English Length Height Distance Distance 0.500 0.250 1.000 0.250 1.000 0.500 1.500 0.500 1.500 0.750 ToolTable

End

The Table ID specified here on line 2 is 2000. Be sure that the ID is unique, if the ID is already used choose another ID and be sure to change it throughout the rest of this discussion when the ID is used. On line 3 the title is set to SheetMetal1 Punch which is the name of this example. The title is used no where other than the tooling file and is simply a convenience for editing the tooling file so that it is easy to see which sheet metal shape the tool table represents. Then on lines 5

Page 72 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture through 11 the standard values of the punch shape are set to be in English units and the columns are for the length and height of the punch respectively. Now that the entry in the tool table has been made it is time to create the initial punch shape to place in the catalog. Before continuing be sure to compile the project so that the registry entries for the Class IDs are created. The code below is taken from the Punch class in the SheetMetal1.vbp project, be sure that when the code is run that the user units in IronCAD are set to inches and degrees:
Public Sub CreatePunchShape(Application As Object) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 Const CLASSID = "{9A3B1EC0-B39D-11D2-9035-00A0240B6602}" Dim cSMPunch As ICSMExtrudeShape Dim objShape As Object Dim objPath As Object Dim objAddonSC As Object Dim objAnchorSC As Object Dim objSMExtrudeSC As Object Dim objCatalogEntry As Object 'Make sure there is an active page and catalog then continue : If ((Application.Pages.Count > 0) And _ (Application.Catalogs.Count > 0)) Then 'Create a new instance of a sheet metal extrude shape... Set cSMPunch = New ICSMExtrudeShape 'Set the parameters... cSMPunch.UserName = "Punch" cSMPunch.SheetMetalType = SheetMetalType_Punch 'Create it... Set objShape = cSMPunch.Create(Application.ActivePage.Shape) 'Add a path and draw the outline... Set objPath = cSMPunch.PathComponents.Add objPath.SetStartPoint -0.25, 0 objPath.AddArcTo 0.25, 0, 0.5 objPath.AddLineTo -0.25, 0 'Now finish the shape... cSMPunch.Finish 'Specify the Class ID of this object to recieve the 'event notifications Set objAddonSC = objShape.Components(triDefAddOn).Add objAddonSC.Variable(triClassID).Value = CLASSID 'Initialize it's table ID... Set objSMExtrudeSC = objShape.Components(triSMExtrude).Item(1) objSMExtrudeSC.TableUsed = True objSMExtrudeSC.TableId = 2000 objSMExtrudeSC.RowIndex = 0

Page 73 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


34 35 36 37 38 39 40 41 43 43 44 45 'Initialize the anchor... Set objAnchorSC = objShape.Components(triAnchor).Item(1) objAnchorSC.Variable(triRotX).Value = 1 objAnchorSC.Variable(triRotY).Value = 0 objAnchorSC.Variable(triRotZ).Value = 0 objAnchorSC.Variable(triRotAngle).Value = 180 'Place the punch in the catalog and label it : Set objCatalogEntry = Application.ActiveCatalog.Entries.Add(objShape) objCatalogEntry.Label = "Punch" 'Release ICSMExtrudeShape... Set cSMPunch = Nothing End If

End Sub

First of all make sure that the Class ID on line 1 is replaced with the Class ID of the Punch class on the machine that this example is being done on. On line 2 a new variable is used that has not been seen yet ICSMExtrudeShape. This is another Visual Basic object defined in the IronCAD - Tool Utilities Type Library. To use this variable the IronCAD Tool Utilities Type Library must be referenced by the project that is using it. Essentially it just takes care of a lot of the redundant things involved in shape creation such as sizebox, position and anchor initialization. It creates an IronCAD Sheet Metal extrude shape and sets the property PathComponents to the path components of the Sheet Metal extrude shape created. The property will return an enumeration of PathComponent objects object in the IronCAD Type Library so that it is very simple to create a new Sheet Metal extrude shape. There is also another one of these derived objects for Sheet Metal form shapes which will be discussed in the next part. On line 14 a name for the punch is specified then on line 15 the derived Sheet Metal extrude shape is set to be a punch. The reason this needs to be done is because there are also Sheet Metal extrude shapes which are stock shapes which add material and punch shapes remove material so the distinction needs to be made. There are a few other differences such as punch shapes have a tool table associated with them and stock shapes do not. The ICSMExtrudeShape object takes care of initializing all of this data. On line 17 the Create method is invoked on the ICSMExtrudeShape object and the top assembly of the page is passed in. The ICSMExtrudeShape object is smart enough to realize that an assembly was passed in and first it will create a Sheet Metal part to place the extrude shape in internally. It will then return the Page 74 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture SMExtrudeShape object in the IronCAD Type Library which is also the only shape in the IronCAD Type Library which is its own shape object, instead of the generic Shape object. Then lines 19 through 22 add a path component to the Sheet Metal extrude shape and draw the cross section of the punch. Line 24 calls the method Finish on the ICSMExtrudeShape object which takes care of updating the shape and initializing the sizebox of the shape. Next an Add-On component needs to be added to the Sheet Metal extrude shape so that the shape knows that when the geometry needs to be generated that a call to a Visual Basic object needs to be made. However, the component added is not the triAddon component that is usually added, it is triDefAddon. This is still an Add-On component, however it instructs IronCAD to add the component on the definition shape, not the instance shape which the component is usually placed on. This is so that if links of a Sheet Metal punch or form shape are created, they are all updated by making one call to the Visual Basic object controlling the geometry for the Sheet Metal shape, along with other reasons. Lines 30 through 33 initialize the table of the punch shape. First the Sheet Metal extrude component is set, which then in turn returns the SMExtrudeComponent object in the IronCAD Type Library. The Table ID of the shape is set to 2000 which was the entry that was added, so now the shape knows that it is associated with those values in the tooling file. The TableUsed property is then set to TRUE so that the punch knows that the values it currently has is a table value. Next on line 33 the RowIndex property is set to 0 since the first entry in the tooling file for the punch corresponds to the standard that the shape is at was initially created at to place into the catalog. Lines 35 through 39 are very important for punches. The anchor must be set to be rotated about the XAxis 180 so that when the punch is dropped on a surface it will remove material. If this is not done then when a punch is dropped on to a Sheet Metal stock it will just sit on top of the sheet metal stock as if a solid block had been dropped on top. To the left is a picture of the two cases. In lines 41 and 42 the punch is added to the catalog and then the ICSMExtrudeShape object is released. The next step in the 3 basic steps is to implement the ISMExtrude interface in the Punch class since that is the object assigned to the shape. The ISMExtrude interface is defined in the IronCAD - Sheet Metal Utilities Type Library. To implement the interface, the following line of code needs to be placed at the top of the Visual Basic class that is specified by the Add-On component of the Sheet Metal shape:

Page 75 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture

This places a new item in the drop box on the left at the top of the Visual Basic environment named ISMExtrude. When this item is selected there are two methods which appear in the drop box to the right. The first method is OnEdit and the second is OnUpdate. These are the two methods that the Visual Basic object must have. When the two methods are selected for the first time, the methods will be added to the Visual Basic class and look like the following:
Private Function ISMExtrude_OnEdit(Shape As Object) As Long End Function Private Function ISMExtrude_OnUpdate(Shape As Object) As Long End Function

However the methods MUST be changed to public instead of private so that IronCAD can invoke these methods, once changed the code should look like:
Public Function ISMExtrude_OnEdit(Shape As Object) As Long End Function Public Function ISMExtrude_OnUpdate(Shape As Object) As Long End Function

The reason it is done this way is that so unlike the shape events, it is very easy to see which events there are if an Add-On is associated with a Sheet Metal shape. Unlike a normal Add-On though, all of these events must be handled and they are not optional. To give an idea when the methods are called, the OnEdit method is called when a user right clicks and selects the Tooling Properties menu. The OnUpdate method is called when a user selects one of the up or down arrows on the punch shape, or when an undo or redo operation happens. For this reason no dialogs should ever be displayed inside of an OnUpdate method. The only thing that should happen is that the geometry of the shape be updated. Now the two events need to be handled. Inside of the IronCAD - Sheet metal Definitions Type Library there is an object called CPunch. This object makes it extremely easy to create a Sheet Metal punch shape. It takes care of displaying the dialog, handling expressions in the dialog and converting all of the units to user units so cross section creation is simple. This object has events, meaning that it must be declared with events as a private member of the Visual Basic object it is in. It is usually placed underneath the Implements ISMExtrude line in the source code and should look something like this :
Private WithEvents m_cPunch As CPunch

Page 76 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture Declaring it with events simply means that it will ask for things periodically and notify the Visual Basic object it was placed on when things need to happen. Just like the ISMForm interface had 2 methods that needed to be implemented, this variable has 3 methods that need to be implemented since it raises events: GetDiagramPicture, UpdateGeometry and ValidateField. When each of these methods are selected for the first time, the following functions are added to the Visual Basic object:
Private Sub m_cPunch_GetDiagramPicture(Picture As stdole.Picture) End Sub Private Sub m_cPunch_UpdateGeometry(PathComponents As Object, _ Dimensions As CDimensionTable) End Sub Private Sub m_cPunch_ValidateField(Field As Long, Value As Double, _ ExpressionServer As CExpressionServer, _ ValueOK As Boolean) End Sub

Now, everything is implemented that needs to be. There are a few variable types above that have not been discussed yet, but they will be when the 3 methods above are handled. But first the OnEdit and OnUpdate events need to be handled on the ISMExtrude interface. Start by handling the OnUpdate event since it is the easiest. The code below is taken from the Punch class in the SheetMetal1.vbp project:
Public Function ISMExtrude_OnUpdate(Shape As Object) As Long 1 2 3 4 5 6 7 8 9 10 'Create a new instance of the private punch class: Set m_cPunch = New CPunch 'Try to initialize the punch from the incoming shape : If (m_cPunch.InitializeUpdate(Shape)) Then 'Set that the two columns are length units : m_cPunch.FieldUsesPageLengthUnits(FIELD_LENGTH) = True m_cPunch.FieldUsesPageLengthUnits(FIELD_HEIGHT) = True 'Update the punch : m_cPunch.Update End If

End Function

That is the only code that needs to go there. On line 4 the private CPunch object is attempted to be initialized. If it is initialized, then TRUE is returned and code Page 77 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture execution continues. Lines 6 and 7 are very important since they tell the CPunch object that the values in the length and height column defined in the tooling file should be displayed in user units. The constants used on the line, FIELD_LENGTH and FIELD_WIDTH are defined at the top of the Punch class file to be 1 and 2 respectively. This correspons to the fact that the length column is the first column in the tooling file and the height column is the second column in the tooling file. The other property on the CPunch object the FieldUsesPageAngleUnits property, which sets whether the column is an angle and should be displayed in the user angle units. Then on line 9 the Update method of the CPunch object is invoked, but what is this doing? What happens is that all the data from the shape is collected and then the UpdateGeometry event is now raised. The UpdateGeometry event has two parameters PathComponents and Dimensions. PathComponents is the enumeration of PathComponent objects in the IronCAD Type Library. The CPunch object will remove all the current paths from the punch shape and then pass the Path Components so that the updated paths can be redrawn. The Dimensions parameter is a CDimensionTable object which is defined in the IronCAD - Sheet Metal Utilities Type Library. It is nothing more than an array of numbers, and contains the values for the fields that the user has specified. Below is code taken from the Punch class in the SheetMetal1.vbp project where this is event is handled:
Private Sub m_cPunch_UpdateGeometry(PathComponents As Object, _ Dimensions As CDimensionTable) 1 2 3 4 5 6 7 8 9 10 Dim objPathSC As Object Dim dLength As Double, dHeight As Double 'Get the values of the length and height : dLength = Dimensions.GetValue(1, FIELD_LENGTH) dHeight = Dimensions.GetValue(1, FIELD_HEIGHT) 'Add a new path and draw the 'D': Set objPathSC = PathComponents.Add objPathSC.SetStartPoint -(dLength / 2), 0 objPathSC.AddArcTo (dLength / 2), 0, (dHeight / dLength) objPathSC.AddLineTo -(dLength / 2), 0

End Sub

On lines 3 and 4 the dimensions that the punch need to be created at are extracted. It is important to note though that if the dimension extracted is an angle, the value will always be in degrees to provide a common unit for shape creation. The GetValue method of the CDimensionTable object takes a row and a column. The row in this case will always be 1 since the array will never be a two dimensional array. On lines 7 through 10 a path added then drawn to the specified dimensions. It is important to notice that no shapes are ever updated. The reason is because as user clicks on the up and down arrows on a punch or forming shape, the OnUpdate method will be called so that a sketch of the profile Page 78 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture can be drawn. If the shape is updated then that will slow down how long it takes to click the up and down arrows. For this reason the shape is not even passed to this event, only the path components. So far the OnUpdate event has been implemented fully. If the code is compiled and run, then the user would be able to do everything with the punch shape except bring up the Punch Properties dialog. The next part then is adding code to the OnEdit event of the ISMExtrude interface so that a dialog is displayed and the user can edit the properties through the Punch Properties dialog. The code below once again is taken from the Punch class in the SheetMetal1.vbp project:
Public Function ISMExtrude_OnEdit(Shape As Object) As Long 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 'Create a new instance of the private punch class: Set m_cPunch = New CPunch 'Try to initialize the punch for editing: If (m_cPunch.InitializeEdit(Shape)) Then 'Specify that the fields use page length units: m_cPunch.FieldUsesPageLengthUnits(FIELD_LENGTH) = True m_cPunch.FieldUsesPageLengthUnits(FIELD_HEIGHT) = True 'Specify user names for the fields : m_cPunch.FieldUserName(FIELD_LENGTH) = "Length" m_cPunch.FieldUserName(FIELD_HEIGHT) = "Height" 'Specify field variable names : m_cPunch.FieldVariableName(FIELD_LENGTH) = "L" m_cPunch.FieldVariableName(FIELD_HEIGHT) = "H" 'Specify field descriptions : m_cPunch.FieldDescription(FIELD_LENGTH) = "L: Length of strait edge" m_cPunch.FieldDescription(FIELD_HEIGHT) = "H: Height of arc" 'Return the outcome of the edit : ISMExtrude_OnEdit = m_cPunch.Edit End If

End Function

Essentially the code is the same as the code in the OnUpdate event, except for all the UI initialization stuff. On the first line once again a new instance of the private CPunch object variable is created. Then instead of calling the InitializeUpdate method on the CPunch object, the InitilizeEdit method is called instead since different initialization must happen when editing a shape. One lines 4 and 5 both fields are once again set to be displayed in user length units. The rest of the code until line 16 just initializes the field names, field variables and field descriptions displayed on the form so that the user is able to write expressions from one field Page 79 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture to another. For this reason it is very important that none of the field variable names specified on lines 10 and 11 are the same since the expression solver will not know what to do with to fields that have the same variable name. On line 16 the Edit method on the CPunch object is called and the value it returns is returned to the OnEdit event. The Edit method on the CPunch object returns whether an undo transaction needs to be created. If the user did not change any of the values on the form then it returns that no undo transaction needs to be created. But if values on the Punch Properties dialog did change, it returns that an undo transaction needs to be created. When values change on the form, the CPunch object then raises the UpdateGeometry event that was handled earlier, so no code has to be written to update the geometry when values on the form have changed since the same event is used. As a reminder, if an undo transaction is created and the user undoes the action, the OnUpdate event is raised which was the first event handled. At this point the punch is fully operational. A user can access the Punch Properties dialog, click the up and down arrows to increment through the standards and successfully perform an undo or redo. There are two events that have not been handled yet, the first one is the GetDiagramPicture event raised by the CPunch object. This event is raised when the Edit method of the CPunch object is called and the Punch Properties dialog is displayed. A handle to a picture in a resource file or image list needs to be returned by reference. This picture will be displayed in the picture box in the upper left-hand corner of the dialog. It should generally contain a detailed picture of the punch along with showing the dimensions that the fields represent. The other event which has not been handled is the ValidateField event raised by the CPunch object. This event is very important since it gives the opportunity to validate the fields when the user clicks the OK button so that invalid dimensions are not set. Below is code taken from the Punch class in the SheetMetal1.vbp project that handles the event:
Private Sub m_cPunch_ValidateField(Field As Long, Value As Double, _ ExpressionServer As CExpressionServer, _ ValueOK As Boolean) 1 2 3 4 5 6 7 8 9 10 11 12 13 'Initialize the value to be OK : ValueOK = True 'Based on which field is being evaluated, validate it : Select Case Field Case FIELD_LENGTH If (Value <= 0) Then ValueOK = False MsgBox "The field length must be greater than zero.", _ vbInformation, "Punch" End If Case FIELD_HEIGHT 'Make sure the height is not zero : If (Value = 0) Then ValueOK = False

Page 80 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


14 15 16 MsgBox "The height can not be zero.", vbInformation, "Punch" End If End Select

End Sub

The first new thing exists in the event variables passed in, the ExpressionServer variable. The ExpressionServer variable is a CExpressionServer object, which is defined in yet another Type Library called IronCAD - Tool Expression Server. The CExpressionServer object is the expression manager for the Punch Properties dialog being displayed. It handles the expressions from one field to another on the dialog and most importantly it allows the validation code to find out what the value of another field is by using the FieldValue property. The FieldValue property takes one parameter, which is an index to a field to retrieve the value of. If perhaps the length field was being validated and for some reason the value of the length could not be more than twice the height, then the following lines of code show how to get the value of the height:
... Dim dHeight As Double dHeight = ExpressionServer.FieldValue(FIELD_HEIGHT) ...

It is important to keep in mind that the Value variable passed in contains the value to the field with the index Field that is passed in. To retrieve the value of any other field the technique above must be used. One important thing to note however is that for values that are angles, if perhaps the angle can not be greater than or equal to 90, there can not be a simple check to see if the value is less than 90. Since user units may be in radians, for fields that are angles multiply the value of the field by the AngleToDegreeRatio property on the CPunch object to convert the value from what ever angle units it is in, to degrees. This must be done regardless of whether the value is used is the Value variable passed in or the value was retrieved from the FieldValue property on the ExpressionServer variable. There is also an AngleToDegreeRatio property on the CForm object, which is discussed in the next part. Simple checking is then done from lines 4 to 16 and if a value is not OK then FALSE must be returned by referenced to the ValueOK variable in the event. That is really all there is to create a punch. The CPunch object greatly reduces the amount of work that needs to be done to retrieve the all the information from the shape and make sure all the units are in user units. The source code is public and available for the CPunch object and the rest of the Sheet Metal shapes. If perhaps a custom dialog needs to be created, the source code for the CPunch object can be looked at to see how the values are retrieved and set from the Sheet Metal shape. However the majority of the time the

Page 81 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture CPunch object will probably be used so the source code to the CPunch object is not discussed. Now that everyone is an expert at punch shapes, forming shapes are going to be discussed. The similarities between the forming shape versus the punch shape interface are almost exactly the same. As a suggestion it will be helpful to truly understand the way the punch shape interface works first before continuing to the forming shape interface due to the similarities. Forming shapes do add a small twist however since a forming shape is not just one shape, it is many shapes. Buckle in, it is time to talk about forming shapes now.

Forming Shapes
This part refers to the SheetMetal1.vbp project in the Example 9 directory in the accompanying source code

The basic steps to creating forming shapes closely mimic the steps to creating punch shapes and are as follows: Create a new entry in the tooling file with a unique Table ID Create the initial state of the forming shape and place it in a catalog Implement the ISMForm interface to handle the events for the form Well, according to the list above the first thing that needs to be done is for a new entry to be made in the tooling file for the forming shape. To the right is a picture of the forming shape that will be created in this example. Once again numbers have been placed next to the lines below for the purpose of discussion only and should not be placed in the tooling file:
1 2 3 4 5 6 7 8 9 10 11 12 Begin TableID Title Units ColHead Measure ToolTable 2001 "SheetMetal2 English Length Distance 0.500 1.000 1.000 1.500 1.500 ToolTable

- Form" Height Distance 0.250 0.250 0.500 0.500 0.750 Width Distance 0.250 0.375 0.500 0.625 0.750 MinThickness Distance 0.063 0.063 0.063 0.063 0.063 MaxThickness Distance 1.000 1.000 1.000 1.000 1.000

End

The Table ID specified this time is 2001 and once again if that value is already being used be sure to change it to a unique Table ID. There are also threw new columns now, one of which is for the width of the D shape. The last two are the minimum and maximum thickness that a row is valid for. These values are not Page 82 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture used right now but need to be included. Other than that the new entry in the tooling file should not be much of a surprise. Now before continuing make sure that the SheetMetal1.vbp project has been compiled so that the Class ID of the Form class is generated and can be set from the Windows Registry. The code below is taken from the Form class in the SheetMetal1.vbp project and be sure that the user units are set to inches and degrees before running the example:
Public Sub CreateFormShape(Application As Object) 1 2 3 4 6 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 Const CLASSID = "{9A3B1EC2-B39D-11D2-9035-00A0240B6602}" Const PI = 3.14159265358979 'Initial values for the first row: Const LENGTH = 0.5 Const HEIGHT = 0.25 Const WIDTH = 0.25 Const SHEET_THICKNESS = 0.05 'The derived form shape and normal shape object : Dim cSMForm As ICSMFormingShape Dim objFormShape As Object 'The shapes inside the forming shape: Dim objRemoveShape As Object, objAddShape As Object 'Components : Dim objProfileSC As Object, objPathSC As Object Dim objAddonSC As Object, objSMFormSC As Object 'Various variables : Dim i As Integer, objCatalogEntry As Object, objCatalog As Object 'If there is at least on page and catalog then continue : If ((Application.Pages.Count > 0) And _ (Application.Catalogs.Count > 0)) Then 'Create a new instance of the sheet metal forming 'shape and set the name of it: Set cSMForm = New ICSMFormingShape cSMForm.UserName = "Form" 'Create it: Set objFormShape = cSMForm.Create(Application.ActivePage.Shape) 'Initialize the sizebox and anchor: cSMForm.InitializeSizebox LENGTH, WIDTH, (HEIGHT + SHEET_THICKNESS) cSMForm.InitializeAnchor (LENGTH / 2), (WIDTH / 2), 0 'Add a shape which will remove material first, then add the shape 'which creates the 'D' shape : i = cSMForm.AddFormingShape(triExtrudeShape) Set objRemoveShape = cSMForm.GetFormingShape(CLng(i)) i = cSMForm.AddFormingShape(triExtrudeShape)

Page 83 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 Set objAddShape = cSMForm.GetFormingShape(CLng(i)) 'Initialize the anchor, sizebox and position for the remove shape: cSMForm.InitializeFormingShapePosition 1, (LENGTH / 2), _ (WIDTH / 2), 0 cSMForm.InitializeFormingShapeSizebox 1, LENGTH, _ WIDTH, _ SHEET_THICKNESS cSMForm.InitializeFormingShapeAnchor 1, 0, 0, 0 objRemoveShape.Rotate triY, PI 'Initialize the anchor, sizebox and position for the add shape: cSMForm.InitializeFormingShapePosition 2, (LENGTH / 2), _ WIDTH, _ -SHEET_THICKNESS cSMForm.InitializeFormingShapeSizebox 2, LENGTH, _ (HEIGHT+ SHEET_THICKNESS), _ WIDTH cSMForm.InitializeFormingShapeAnchor 2, 0, 0, 0 objAddShape.Rotate triX, (PI / 2) 'Set the operation type of the first shape to remove material : cSMForm.FormingShapeOperation(1) = triSubtract 'Get the profile for the remove material shape and draw 'its cross section: Set objProfileSC = objRemoveShape.Components(triProfile).Item(1) Set objPathSC = objProfileSC.Profile.Components(triPath).Add objPathSC.SetStartPoint -(LENGTH / 2), (WIDTH / 2) objPathSC.AddLineTo (LENGTH / 2), (WIDTH / 2) objPathSC.AddLineTo (LENGTH / 2), -(WIDTH / 2) objPathSC.AddLineTo -(LENGTH / 2), -(WIDTH / 2) objPathSC.AddLineTo -(LENGTH / 2), (WIDTH / 2) 'Get the profile of the add material shape and draw 'its cross section: Set objProfileSC = objAddShape.Components(triProfile).Item(1) Set objPathSC = objProfileSC.Profile.Components(triPath).Add objPathSC.SetStartPoint -(LENGTH / 2), SHEET_THICKNESS objPathSC.AddArcTo (LENGTH / 2), SHEET_THICKNESS, (HEIGHT / LENGTH) objPathSC.AddLineTo (LENGTH / 2), 0 objPathSC.AddArcTo -(LENGTH / 2), 0, -(HEIGHT / LENGTH) objPathSC.AddLineTo -(LENGTH / 2), SHEET_THICKNESS 'All the geometry is complete, so finish the forming shape: cSMForm.Finish 'Add the Add-On component to specify this class to be 'the Add-On object: Set objAddonSC = objFormShape.Components(triDefAddOn).Item(1) objAddonSC.Variable(triClassID).Value = CLASSID 'Get the sheet metal form component and initialize the 'Table ID and the row index: Set objSMFormSC = objFormShape.Components(triSMForm).Item(1) objSMFormSC.TableId = 2001 objSMFormSC.TableUsed = True

Page 84 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


77 78 79 80 81 82 objSMFormSC.RowIndex = 0 'Add the form shape to the catalog : Set objCatalog = Application.ActiveCatalog Set objCatalogEntry = objCatalog.Entries.Add(objFormShape) objCatalogEntry.Label = "Form" End If

End Sub

Well it did not take as many lines to create this shape as it did to create the loft shape in the previous section, but there are still quite a few lines of code. First things first make sure the Class ID on line 1 is replace with the correct Class ID. Lines 2 through 7 define constants that get used throughout the code. These are the values specified in the first standard in the tool table for the form shape. On line 7 there is a constant called SHEET_THICKNESS defined to be 0.05. When creating form shapes, there will always be a dimension of a shape that is depends on the thickness of the sheet. It is okay to hard code the sheet thickness to any arbitrary value for creation purposes, because when the shape is dropped on to a piece of sheet metal the thickness of the forming shape is updated regardless. On line 9 a variable is declared to be an ICSMFormingShape object. This object is closely related to the ICSMExtrudeShape object, except this object is used to do all the redundant tasks involved with creating a Sheet Metal form shape. On line 19 a simple check is performed once again to make sure there is a page and catalog open, if so code execution continues. Line 22 creates a new instance of the ICSMFormingShape object then the user name of it is set to Form since that is a pretty good description of what it is. Even though nothing up to this point has been done, line 25 calls the Create method on the ICSMFormingShape object. The reason this is done is to add the shape to the scene so shapes can be inserted into it. A Sheet Metal forming shape is internally derived off of a complex shape, so shapes get added to its history component which is why the Create method is called before anything can happen. The Create method returns a Shape object from the IronCAD Type Library, which is the forming shape that has been created. Lines 27 and 28 initialize the sizebox and anchor of the forming shape, which should be a familiar task by now. The only difference here is that there are nice utility methods on the ICSMFormingShape object that take care of getting the components and then set the values passed in. Then lines 31 through 34 add two extrude shapes to the forming shape. Line 31 adds an extrude shape and the index that the extrude shape was added at is returned. Then the GetFormingShape method on the ICSMFormingShape object is called which returns the Shape object in the IronCAD Type Library. The reason two shapes are added is because material needs to be removed and added to the sheet metal to produce a form shape. So the first shape added will cut away the material from the Sheet Metal stock and the second shape will be the shape that adds material. Lines 35 to 44 initialize the sizebox, anchor and position of the two shapes that were added to the ICSMFormingShape object. Positioning shapes Page 85 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture that are added to a forming shape is no different than positioning shapes inside any other part, so do not be misled simply because it is a forming shape. Essentially, a forming shape is really a part. Line 46 then sets the operation type of the first shape added to remove material. Lines 50 to 56 draw the cross section of the shape that will be removing material, it is a simple rectangle. Then lines 59 through 65 draw the cross section of the add material shape which is the D. On line 67 the Finish method on the ICSMFormingShape is called which will take care of shape regeneration and making sure any other necessary data is initialized correctly for the forming shape. Lines 70 and 71 set the Class ID of the Form class to the forming shapes definition Add-On component just like previously with the punch shape, then the Table ID for the forming shape is initialized in lines 74 through 77. Finally in lines 79 to 81 the forming shape is added to the catalog and now the most difficult part of creating any Sheet Metal shape is done. The next step is to implement the ISMForm interface. This interface is defined in the IronCAD - Sheet Metal Utilities Type Library along with the ISMExtrude interface. Once again this interface has the two events OnUpdate and OnEdit, but there is also one more event in the interface, OnUpdateThickness. The

OnUpdate and OnEdit events still get called at the same times they were previously for punch shapes, but the new event called OnUpdateThickness gets called when the forming shape is dropped out of the catalog onto a Sheet Metal Part. Previously there was no event when a punch was dropped from a catalog because IronCAD took care of making sure that the extrusion depth of the punch was equal to the thickness of the Sheet Metal part. IronCAD can not set an extrusion depth for a forming shape however due to the complexity of forming shapes, so an event is raised and it is left to the Add-On to determine the correct geometry on drop. Since this dropping must happen when a forming shape is dropped, the OnUpdateThickness method has the shape being dropped as one parameter. But the OnUpdateThickness method also has the dimensions of the forming shape and the thickness of the Sheet Metal part being dropped on as well to make the operation as quick as possible. Some forming shapes in IronCAD are created from 8 separate shapes, which all have to have their geometry updated on drop, so saving time by having everything passed to the OnUpdateThickness event helpful. The implementation looks like the following:
Private Function ISMForm_OnEdit(Shape As Object) As Long End Function Private Function ISMForm_OnUpdate(Shape As Object) As Long End Function Private Function ISMForm_OnUpdateThickness(Shape As Object, _

Page 86 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


Dimensions As CDimensionTable, _ SheetThickness As Double) As

Long End Function

Be sure once again to change all the methods from private to public. Now it is time to start handling the three events. Inside of the IronCAD - Sheet Metal Definitions Type Library there is an object called CForm. It takes care of the majority of the things associated with form shapes just like CPunch took care of the majority of the things that were associated with punches. CForm has events that it raises as well so it needs to be declared with events like the CPunch object was. The declaration of the object should look something like this:
Private WithEvents m_cForm As CForm

This object has 4 events that it raises as well which are: GetDiagramPicture, UpdateGeometry, ValidateField and UpdateThickness. Once all of the events are clicked for the first time, the event protocols should look something like this:
Private Sub m_cForm_GetDiagramPicture(Picture As stdole.Picture) End Sub Private Sub m_cForm_UpdateGeometry(FormingShapeArray As CShapeArray, _ Dimensions As CDimensionTable, _ SheetThickness As Double) End Sub Private Sub m_cForm_UpdateThickness(FormingShapeArray As CShapeArray, _ Dimensions As CDimensionTable, _ SheetThickness As Double) End Sub Private Sub m_cForm_ValidateField(Field As Long, Value As Double, _ ExpressionServer As CExpressionServer, _ ValueOK As Boolean) End Sub

Everything has now been implemented that needs to be and the events from the ISMForm interface can now be handled. To start, below is the code for handling the OnUpdate event of the ISMForm interface:
Public Function ISMForm_OnUpdate(Shape As Object) As Long 1 2 3 'Create a new instance of the CForm class: Set m_cForm = New CForm 'Try to initialize the CForm class, if successful continue:

Page 87 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


4 5 6 7 8 9 10 11 If (m_cForm.InitializeUpdate(Shape)) Then 'Initialize the units : m_cForm.FieldUsesPageLengthUnits(FIELD_LENGTH) = True m_cForm.FieldUsesPageLengthUnits(FIELD_WIDTH) = True m_cForm.FieldUsesPageLengthUnits(FIELD_HEIGHT) = True 'Update the form: m_cForm.Update End If

End Function

The code for handling the OnUpdate event of a form shape is not much different than it was for a punch shape. The CForm object tries to initialize the update on line 4 and if successful then code execution continues. Lines 6 though 8 let the CForm object know that all the fields should be in user units. The constants are all defined privately at the top of the Form class. Their values once again are the indices of the column that the fields represent in the tooling file. Then the Update method on the CForm object is called. When the Update method of the CForm object is called, the CForm object raises its UpateGeometry method just like the CPunch object did. Below is the code taken from the Form class in the SheetMetal1.vbp project where the UpdateGeometry of the CForm object event is handled:
Private Sub m_cForm_UpdateGeometry(FormingShapeArray As CShapeArray, _ Dimensions As CDimensionTable, _ SheetThickness As Double) 'Update all the geometry: UpdateAllGeometry FormingShapeArray, Dimensions, SheetThickness End Sub

That was simple, the code just calls another function in the Form class. Just like in the UpdateGeometry event of the CPunch object, the dimensions for angles in the CDimensionTable object which is passed in will always be in degrees, regardless of user units. So now look at the code inside of the private UpdateAllGeometry method in the class:
Private Sub UpdateAllGeometry(FormingShapeArray As CShapeArray, _ Dimensions As CDimensionTable, _ SheetThickness As Double) 1 2 3 4 5 6 Dim Dim Dim Dim Dim objProfileSC As Object, objPositionSC As Object, objSolidSC As Object dLength As Double, dWidth As Double, dHeight As Double objRemoveShape As Object, objAddShape As Object X As Double, Y As Double, Z As Double objPathSC As Object

'First set the dimensions:

Page 88 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 dLength = Dimensions.GetValue(1, FIELD_LENGTH) dWidth = Dimensions.GetValue(1, FIELD_WIDTH) dHeight = Dimensions.GetValue(1, FIELD_HEIGHT) 'Second set the shapes that make up the forming shape: Set objRemoveShape = FormingShapeArray.GetShape(1) Set objAddShape = FormingShapeArray.GetShape(2) 'Remove all the geometry on the add and remove material 'shapes so new geometry can be created: RemoveGeometry objRemoveShape RemoveGeometry objAddShape 'Now reconstruct the geometry for the remove shape: Set objProfileSC = objRemoveShape.Components(triProfile).Item(1) Set objPathSC = objProfileSC.Profile.Components(triPath).Add objPathSC.SetStartPoint -(dLength / 2), (dWidth / 2) objPathSC.AddLineTo (dLength / 2), (dWidth / 2) objPathSC.AddLineTo (dLength / 2), -(dWidth / 2) objPathSC.AddLineTo -(dLength / 2), -(dWidth / 2) objPathSC.AddLineTo -(dLength / 2), (dWidth / 2) 'Now reconstruct the geometry for the add shape: Set objProfileSC = objAddShape.Components(triProfile).Item(1) Set objPathSC = objProfileSC.Profile.Components(triPath).Add objPathSC.SetStartPoint -(dLength / 2), SheetThickness objPathSC.AddArcTo (dLength / 2), SheetThickness, (dHeight / dLength) objPathSC.AddLineTo (dLength / 2), 0 objPathSC.AddArcTo -(dLength / 2), 0, -(dHeight / dLength) objPathSC.AddLineTo -(dLength / 2), SheetThickness 'Update the position of the add material shape: 'Get the position of the remove material shape: Set objPositionSC = objRemoveShape.Components(triPosition).Item(1) X = objPositionSC.Variable(triX).Value Y = objPositionSC.Variable(triY).Value Z = objPositionSC.Variable(triZ).Value 'Now set the position of the add shape correctly: Set objPositionSC = objAddShape.Components(triPosition).Item(1) objPositionSC.Variable(triX).Value = X objPositionSC.Variable(triY).Value = (Y + (dWidth / 2)) objPositionSC.Variable(triZ).Value = (Z - SheetThickness) 'Set the extrude height of the remove material shape: Set objSolidSC = objRemoveShape.Components(triSweep).Item(1) objSolidSC.Variable(triExtrudeDistUp).Value = SheetThickness 'Set teh extrude height of the add material shape: Set objSolidSC = objAddShape.Components(triSweep).Item(1) objSolidSC.Variable(triExtrudeDistUp).Value = dWidth

End Sub

Unfortunately updating the geometry of a forming shape is not as easy as updating the geometry of a punch, but breaking down the steps should help. The Page 89 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture variable types for the parameters in the UpdateGeometry event should all be familiar except for the CShapeArray object. CShapeArray is an object defined in the IronCAD - Sheet Metal Utilities Type Library. Just like CDimensionTable is an array of numbers, CShapeArray is an array of shapes. It contains the shapes in the forming shape in the order that they were added to the forming shape. So in this case, the first shape in the CShapeArray object will be the remove material shape and the second shape in the CShapeArray object will be the add material shape. Lines 7 through 9 just retrieve the dimensions that the shape needs to be created from and sets them to local variables. Next on lines 11 and 12 the add material and remove material shapes are set from the CShapeArray object that was passed in. Lines 15 and 16 are calls to yet another function inside of the Form class. Below is the code for the RemoveGeometry function inside the Form class:
Private Sub RemoveGeometry(ExtrudeShape As Object) 1 2 3 4 5 6 7 8 9 10 11 12 Dim objProfileSC As Object Dim objPathSC As Object Dim iPaths As Integer, i As Integer, iIndex As Integer 'Set the profile shape component and the number of paths: Set objProfileSC = ExtrudeShape.Components(triProfile).Item(1) iPaths = objProfileSC.Profile.Components(triPath).Count 'Remove all the paths from the extrude shape For i = 1 To iPaths iIndex = ((iPaths + 1) - i) Set objPathSC = objProfileSC.Profile.Components(triPath).Item(iIndex) objProfileSC.Profile.Components(triPath).Remove objPathSC Next

End Sub

What it is doing is removing all of the geometry from the cross section of the extrude shape passed in. Unlike when the CPunch object was being used, the CForm object does not remove the geometry from cross sections since it does not know which shapes need to have their cross sections updated. Because of this a function needs to be written by the Add-On to remove the geometry from the profiles of shapes before new geometry is added. Line 5 sets the profile shape component of the extrude shape and then on line 6 the number of paths, which is the same thing as the number of outlines is set. Then lines 8 through 12 loop through all of the paths in reverse and delete them starting from the last one and going to the first one. The reason this is done in reverse is because suppose there are initially 5 paths. If a loop statement simply loops from 1 to 5 and deletes the path of the index, by the time it gets to 5 there will not be a path with the index 5. What would happen is that when the loop deletes the path at index 1, then the path at index 2 becomes the path with index 1 and then all the subsequent path indices are decrement by 1 as well, so then the highest path index is 4. So now

Page 90 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture there is no longer a path with index 5 so the loop statement would not be able to delete the path at index 5. Hopefully this makes a little sense. Now back to the code in the UpdateGeometry event, the next thing that happens is the cross section of the remove material shape is created in lines 18 through 24. After that is completed the cross section for the add material shape is created in lines 25 through 32. By now this code should be a piece of cake. Then in lines 34 through lines 43 the position of the add material shape is positioned relative to the remove material shape. Since the width may have changed, the position of the add material shape needs to be positioned correctly with the remove material shape. Since the width is known, then the position of the add material shape is known because the position of the add material shape is the same except for it is half of the width further out along the Y-Axis than the remove material shape. The position of the add material shape also needs to be positioned along the Z-Axis which for this shape will always be the Z position of the remove material shape minus the thickness of the Sheet Metal stock. If it is not clear what the positioning is doing try altering one of position variables to see the effect. Next on lines 45 and 46 the extrusion depth of the remove material shape is set to be equal to the sheet thickness and finally on lines 48 and 49 the extrusion depth of the add material shape is set to be the width. There is a lot of positioning code above that mentioned earlier try altering the positions of the results occur if it is not clear what is happening. space is not the easiest thing to understand so take code above further if it is not understood. may not be clear now. As shapes slightly to see what Positioning in 3-Dimensional some time to investigate the

Now the OnUpdate event of the ISMForm interface has been fully handled. Since the OnUpdateThickness event is very similar to the OnUpdate event, it will be handled next. Below is the code taken from the Form class where the OnUpdateThickness event of the ISMForm interface is handled:
Public Function ISMForm_OnUpdateThickness(Shape As Object, _ Dimensions As CDimensionTable, _ SheetThickness As Double) As Long 1 2 3 4 'Create a new instance of the CForm class: Set m_cForm = New CForm 'Try to initialize the CForm class, if successful continue: If (m_cForm.InitializeUpdateThickness(Shape, _ Dimensions, _ SheetThickness)) Then 'Initialize the units : m_cForm.FieldUsesPageLengthUnits(FIELD_LENGTH) = True m_cForm.FieldUsesPageLengthUnits(FIELD_WIDTH) = True m_cForm.FieldUsesPageLengthUnits(FIELD_HEIGHT) = True

5 6 7 8

Page 91 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


9 10 11 'Update the form: m_cForm.UpdateThickness End If

End Function

It is barely different from the code in the OnUpdate event, except that the InitializeUpdateThickness method on the CForm object is called instead of the InitailizeUpdate method. The biggest difference as mentioned before is the fact that the dimensions which the forming shape need to be created at, along with the thickness of the sheet metal part are passed in as parameters to the event. The reason for doing this is so that the information is immediately available which makes the code execution quicker when dropping the forming shape. On line 10 the UpdateThickness method on the CForm object is called, which then makes the CForm object raise the UpdateThickness event. Below is the code taken from the Form class where the UpdateThickness event is handled:
Private Sub m_cForm_UpdateThickness(FormingShapeArray As CShapeArray, _ Dimensions As CDimensionTable, _ SheetThickness As Double) 'Update all the geometry : UpdateAllGeometry FormingShapeArray, Dimensions, SheetThickness End Sub

Just like the UpdateGeometry event of the CForm object, all angle dimensions in the CDimensionTable object that are passed in will be in degrees, regardless of user units. Once again the method UpdateAllGeometry on the class is called. This particular forming shape that is being used must update everything when the thickness changes so nothing can be done to optimize the code unfortunately. There will be forming shapes in which the code differs significantly for the events OnUpdate and OnUpdateThickness. The majority of the time if only the thickness changes, much of the positioning code does not need to be done, along with some profile creation code. If it is possible always try to optimize the code in the OnUpdateThickness event since this code is executed every time the form shape is dropped on a Sheet Metal part. There is one last event to handle in the ISMForm interface and that is the OnEdit event. This event is handled in the exact same way that it was handled for punch shapes. Below is the code that handles this event in the Form class:
Public Function ISMForm_OnEdit(Shape As Object) As Long 1 2 'Create a new instance of the CForm class: Set m_cForm = New CForm

Page 92 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture


3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 'Try to initialize the CForm class, if successful continue: If (m_cForm.InitializeEdit(Shape)) Then 'Initialize the units : m_cForm.FieldUsesPageLengthUnits(FIELD_LENGTH) = True m_cForm.FieldUsesPageLengthUnits(FIELD_WIDTH) = True m_cForm.FieldUsesPageLengthUnits(FIELD_HEIGHT) = True 'Initialize the field names: m_cForm.FieldUserName(FIELD_LENGTH) = "Length" m_cForm.FieldUserName(FIELD_WIDTH) = "Width" m_cForm.FieldUserName(FIELD_HEIGHT) = "Height" 'Initialize the field variable names: m_cForm.FieldVariableName(FIELD_LENGTH) = "L" m_cForm.FieldVariableName(FIELD_WIDTH) = "W" m_cForm.FieldVariableName(FIELD_HEIGHT) = "H" 'Initialize field descriptions: m_cForm.FieldDescription(FIELD_LENGTH) = "L: Length of form" m_cForm.FieldDescription(FIELD_WIDTH) = "W: Width of form" m_cForm.FieldDescription(FIELD_HEIGHT) = "H: Height of arc" 'Return the result of editing to IronCAD : ISMForm_OnEdit = m_cForm.Edit End If

End Function

The code is identical to the code in the OnEdit event for the Punch class except for the fact that there is one more variable, which is the width. On line 4 the CForm object tries to initialize itself for an edit and if it is successful then code execution continues. The field names, variable names and field descriptions are set up in lines 10 through 20. Then on line 22 the Edit method of the CForm object is called and the value it returns is returned to the function which contains information for whether an undo transaction needs to be created. If the values in the fields change, the UpdateGeometry event on the CForm object is raised, so there is not any code that needs to be written other than the code that has already been written to handle the UpdateGeometry event of the CForm object. At this point the forming shape is fully functional. When the forming shape is dropped onto a Sheet Metal part the thickness of it should be updated once dropped. The up and down arrows should work and the Forming Properties dialog can be displayed and values can be changed on the dialog. There are still two events that have not been handled yet and they are the GetDiagramPicture and ValidateField events raised by the CForm object. The GetDiagramPicture event should be treated exactly as it was when CPunch object raised the event. Pass a handle to an image in a resource file or images list back by reference. The ValidateField event should be treated in the exact same way it was treated for a punch. It provides the ability for the Add-On to verify that the values the user Page 93 of 104

IronCAD Customization: IronCAD Sheet Metal Architecture entered for the fields are valid. Below is code taken from the Form class where the ValidateField event is handled:
Private Sub m_cForm_ValidateField(Field As Long, Value As Double, _ ExpressionServer As CExpressionServer, _ ValueOK As Boolean) 1 2 3 4 5 6 7 8 9 10 11 12 'Initialize the value to be OK: ValueOK = True 'All of the fields need to be greater than zero, do it the easy way: Select Case Field Case FIELD_LENGTH Case FIELD_WIDTH Case FIELD_HEIGHT If (Value <= 0) Then MsgBox "Must be greater than zero.", vbInformation, "Form" ValueOK = False End If End Select

End Sub

The validation code simply makes sure that the field being validated has a value greater than zero. When validating angles, be sure to multiply the value of the angle by the AngleToDegreeRatio property on the CForm object to get the value of the angle in degrees, otherwise the value will be in what the user angle units have been set to. This is the conclusion of the Sheet Metal Architecture section. Only two examples of Sheet Metal shapes have been provided here, but the Visual Basic source code which created the Sheet Metal catalog in IronCAD along with all the code for the Add-Ons that handle each shape is available. The shapes used in these examples are relatively simple Sheet Metal shapes without much geometry involved in creating them. The majority of the Sheet Metal forming shapes used in IronCAD are created from more than 4 shapes, so it would be a good idea to take a look at the source code for the Sheet Metal shapes in IronCAD for follow up.

Page 94 of 104

IronCAD Customization: BOM Customization

IronCAD BOM Customization


Introduction
There are two ways to customize a BOM in IronCAD , the first is by adding a custom export option to the BOM table. This is done the same way an Add-On tool is added to the Tools menu in IronCAD, by specifying the Program ID of a Visual Basic object and a method on the object to call, which must take a single argument that is an object. The menu text for the export option is also specified and when the menu item is clicked, the object will be invoked. The other way of customizing a BOM table is to assign a Visual Basic object to a column. When the BOM table is updated, if a column has a Visual Basic object associated with it then a call to the Visual Basic object is made and it is left to the Visual Basic object to place the values in the column. When using this approach the method specified on the Visual Basic object must take two arguments an object and a long. In both of the cases above the tool information is saved in the BOM table, so when a new BOM table is created it will not have the Add-On tools associated with it that were added in a different BOM. If there is standard export option, or a standard column handling technique it is best if a BOM template is made and saved with the Add-Ons added to the template. When a custom export or column filling technique needs to be done, then open the template saved so that the AddOn tool does not need to be added to the BOM table again each time the custom export or column filling technique needs to be performed.

Creating Custom BOM Export


This part refers to the CustomBOM.vbp project in the Example 10 directory in the accompanying source code.

The first part to creating a custom BOM export is to add the export option to the BOM table. Before continuing be sure to compile the CustomBOM.vbp project so that the necessary registry entries are created. Next create a BOM table template and right click on the table. When the right click menu comes up select the Add Custom Export Addon item. A dialog will then come up which allows the Visual Basic object and method to be set which need the notification. The method specified must take one argument which is an object. Below is the source code taken from the Export class in the CustomBOM.vbp project:
Public Sub Export(BOMTable As Object)

Page 95 of 104

IronCAD Customization: BOM Customization


1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Const FILENAME = "C:\BOM.txt" Dim Dim Dim Dim Dim Dim lRows As Long, lCols As Long objRow As Object objCell As Object hFile As Long i As Long, j As Long strLine As String

'Get the number of rows and columns in the BOM table: lRows = BOMTable.Rows lCols = BOMTable.Columns 'Create a new file to write the data to: hFile = FreeFile Open FILENAME For Output As #hFile 'First output the column headers: strLine = vbNullString For i = 1 To lCols Set objCell = BOMTable.GetColumn(i).HeaderCell strLine = (strLine & objCell.Value & vbTab) Next Print #hFile, strLine 'Next output all the data in the BOM table: For i = 1 To lRows 'Set the row: Set objRow = BOMTable.GetRow(i) 'Get all the values strLine = vbNullString For j = 1 To lCols Set objCell = objRow.GetCell(j) strLine = (strLine & objCell.Value & vbTab) Next 'Output the line: Print #hFile, strLine

Next

'Close the file: Close #hFile

End Sub

The argument BOMTable in the Export method is a BOMTable object in the IronCAD Type Library. This code simply exports a tab delimited BOM Table to the hard coded file C:\BOM.txt. On line 11 and 12 the number of rows and columns in the BOM table are set. Lines 18 through 21 loop through each column in the BOM table and get the value of the header cell. The header cell is the header for that particular column and is a CBOMTableCell object in the IronCAD Type Library. Next on lines 24 through 35 the values in the BOM table are retrieved and the values are exported to the file. On line 26 a row in the BOM table is set, Page 96 of 104

IronCAD Customization: BOM Customization this returns a CBOMTableRow object in the IronCAD Type Library. Then on line 30 the cell for the particular row and column is set then the value of it is added to the line that is being written to the file on line 31 of the source code. The file is then closed on line 37. If an export is done on a template, this code will fail on line 26 since there are now shapes associated with the rows. This code must only be used on a BOM table that has been generated from an existing scene.

Creating Custom BOM Columns


Creating custom BOM columns works much in the same way that creating a custom export is done. Instead of providing a custom export hook however, with column customization when the BOM table is updated if a column is associated with an Add-On a call to the Add-On is made so that it can fill the column. This provides a nice way of allowing a Visual Basic object to determine which values need to be in a column. To assign a Visual Basic object to column right click on the header for the column and select the Edit Column Header menu item. Then a dialog will be displayed where the Program ID and the method of a Visual Basic object needs to be specified. The method specified here must have two arguments, the first must be an object an the second must be a long. The reason is because when the method on the Visual Basic object is invoked, the Visual Basic object must be passed a BOMTable object as well as the index of the column that requires updating. Below is source code taken from the Column1 class in the CustomBOM.vbp project simply fills the cells in the column with the row index of the cell:
Public Sub UpdateColumn(BOMTable As Object, Column As Long) 1 2 3 4 5 6 7 8 9 10 11 Dim i As Long Dim objCell As Object Dim objColumn As Object 'Get the column for the index that needs updating: Set objColumn = BOMTable.GetColumn(Column) 'Now for each row in the column set the value of 'the cell to be the index of the row the colum is: For i = 1 To objColumn.Cells Set objCell = objColumn.GetCell(i) objCell.Value = CStr(i) Next

Page 97 of 104

IronCAD Customization: BOM Customization


End Sub

The purpose of the code above is just to demonstrate how to hook a Visual Basic object into a column and receive notification of the update. It also demonstrates how to set the value of a cell in the BOM table on line 10. The following part demonstrates how to retrieve a cost property on a shape and sum up a list of costs for cost analysis. To make the BOM table update, all of the views of the drawing must be updated by selecting Update All Views from the Tools menu in IronCAD.

Custom BOM Columns Using Shape Properties


Since this part uses part properties, the part properties type library for IronCAD must be referenced by selecting the IronCAD Part Properties 1.0 Type Library from the available list of references. A BOMTableRow object has a property called Shapes on it which return the Shapes object in IronCAD. This object is usually an enumeration of Shape objects in IronCAD, but when dealing with BOM the Shapes object is an enumeration of TreeShape objects in the IronCAD Type Library. A TreeShape object is just another object used to represent a Shape object and the Shape object it represents by retrieved from the InstanceShape property, which returns the Shape object for the TreeShape object. The reason an enumeration of TreeShape objects is returned is so that properties can be read from a shape which the TreeShape object allows through the DataObject property on the TreeShape object. For the purpose of discussing shape properties, the data type argument of the property will be set to the Class ID of the Part Properties Object and the IsMaster argument will be set to TRUE. When the data type argument is set to 0, a CPPropCollection object in the IronCAD Part Properties 1.0 Type Library is returned. This object is a collection of CPPropObj objects which is a part property. The source code below goes to each shape associated with a row in a BOM table and looks for a property called Cost on the shape. If the property is found then the value of the property is added to the total cost for that row then displayed. The code is taken from the Column2 class in the CustomBOM.vbp project:
Public Sub FillCosts(BOMTable As Object, Column As Long)

Page 98 of 104

IronCAD Customization: BOM Customization


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 Next Next 'Display the total cost of the row in the column: Set objCell = objRow.GetCell(Column) objCell.Value = CStr(dTotalCost) Next Dim Dim Dim Dim Dim Dim Dim Dim i As Integer, j As Integer, k As Integer objRow As Object objCell As Object objShape As Object objShapes As Object dTotalCost As Double objProperties As Object objProperty As Object

'A constant which is the ClassID of the Part Properties Object : Const CLSID_PROPERTIES = "{3DE10049-922D-11CF-AC2E-00A024581E5C}" 'Loop through all of the of the rows and set the column value: For i = 1 To BOMTable.Rows 'Set the current row and get the shapes for the row: Set objRow = BOMTable.GetRow(i) Set objShapes = objRow.Shapes 'For each shape associated with the row, look for cost: dTotalCost = 0 For j = 1 To objShapes.Count 'Get the part properties of the shape: Set objShape = objShapes.Item(j) Set objProperties = objShape.DataObject(0, True) 'Now for each property on the shape, check for cost: For k = 1 To objProperties.Count 'See if it is a cost property, if so then add 'the cost and exit the for statement: For Each objProperty In objProperties If (LCase(objProperty.Name) = "cost") Then dTotalCost = (dTotalCost + CDbl(objProperty.Value)) Exit For End If Next

End Sub

When retrieving properties from the shape, the Class ID of the object associated with the properties needs to be specified. For that reason on line 10 the Class ID of the CPPropCollection object is set. Right now this is the only object which is currently available and the CPPropCollection object is returned. It will be possible in the future for there to be user defined objects on a shape. The constant listed Page 99 of 104

IronCAD Customization: BOM Customization above is not in the Type Library so it is important when using Part Properties that the constant above used for CLSID_PROPERTIES is copied and pasted into other code. The next release should have an enumeration of CLSIDs for objects associated with shapes, but for now only the constant above is mentioned. Next the code loops through all the rows in the BOM table and on line 14 it sets the row for the current row in the loop. Then on line 15 the shapes associated with the row are set to the objShapes variable. This variable is now an enumeration of TreeShape objects. Next, for each shape in the row it looks to see if there is a cost property on the shape in lines 26 through 31. If so then it the cost of the part is added to the total cost of the parts in the row, then on line 36 the value in the column is set to the cost of the shapes in the row. This is a very handy piece of code to keep around for starting the foundation of a cost analysis utility to associate with a BOM column. It could be extended to total all the lengths for each row then display the sum of the totals for the rows at the end. This example provides a good overview of how to access the shape properties and customize a BOM column at the same time. That also wraps up BOM and in the last section the IronCAD Utilities will be discussed.

Page 100 of 104

IronCAD Customization: IronCAD Utilities Reference

IronCAD Utilities Reference


Introduction
There are three utilities that are made available that can be used when creating Add-On tools or automating IronCAD . They can all be found in the available references and must be referenced to use. They are listed below with a brief explanation of each following: IronCAD - Tool Utilities IronCAD - Tool Expression Server IronCAD - Tool Selection Helper The first one is the IronCAD - Tool Utilities. This library contains several utility classes for doing some of the most common things when dealing with IronCAD automation. The next one is the IronCAD - Tool Expression Server. This classes is used to evaluate expressions and manage expressions on a form from one field to another. There is an example of a project implementing this tool to demonstrate how it is used. Finally the last utility is the IronCAD - Tool Selection Helper. This provides Add-Ons with the ability to have a user select a shape or face even though the Add-On dialogs are modal.

IronCAD - Tool Utilities


The IronCAD - Tool Utilities is a library of several classes that ease some of the more tedious tasks when working with the IronCAD automation system. Some of the classes in the library are seldom used while others are extremely helpful and are worth learning how to use. Below is a listing of all the classes and a brief description of their purpose: AppUtils DialogUtils IC2DArray ICCurve ICExports Used for retrieving information concerning IronCAD. This object is considered OBSOLETE and may be removed in the future. Mainly used by the Tools, it also contains methods for getting the Class ID of an object from its Program ID. Class for passing 2-Dimensional array of doubles which has several methods and properties for array manipulation. Contains all information about a curve. Used by ICOutline which is used by ICProfile. Used by IronCAD. Not intended for end user use.

Page 101 of 104

IronCAD Customization: IronCAD Utilities Reference ICExtrudeShape Utility class for easing the creation of extrude shapes. When creating extrude shapes it will automatically add a part to place the extrude shape in if none exists. ICImports Used by IronCAD. Not intended for end user use. ICInvoluteCurve Class for generating points along an involute curve. This class is currently used by the Gears Tool for generating true involute teeth for the gears. Once the points on the curve are generated, there is a method provided on the object to draw the curve on a path fit by a B-Spline. The user can specify the number of points to calculate along the curve. ICMatrix4d 4x4 Matrix used for transformations and translations in 3Dimensional space. ICOutline Contains all the information about a loop in a profile. Used by ICProfile. ICPosition Utility class for simple positioning of shapes. The Shape property on it must be set to the shape being positioned. ICProfile Used mainly for copying a cross section of one profile and placing it on another profile. Also contains geometry information concerning profiles. ICShape Simple utility class for getting basic properties of a shape. ICSMBendShape Utility class for creating Sheet Metal bend shapes. ICSMExtrudeShape Utility class for creating Sheet Metal punch and stock shapes. ICSMFormingShape Utility class for creating Sheet Metal forming shapes. ICSurfaceFinish Utility class for easily assigning and retrieving surface finish information from a shape specified by its Shape property. ICTransform Created to closely mimic the way IronCAD handles rotations and positions. Used for calculating shape position transformations, but does not actually position shapes. ICTreeView Utility for getting a list of all shapes in the specified scene. Also returns the depths of a shape in the shape tree and paths of shapes. ICVector4d 3-Dimensional vector rotation and transformation class used I calculating point transformations in 3D space. SceneUtils Has several useful methods for obtaining the true parent of a shape, a shape path and deleting a shape. UnitUtils Used for converting user units to system units and vice versa. This object is considered OBSOLETE with the addition of the UnitsScale property on the Page object and may be removed in the future.

Page 102 of 104

IronCAD Customization: IronCAD Utilities Reference There are a few classes which will probably be used most and are the most helpful. The ICProfile class is extremely helpful when copying the geometry of one profile to another. As a suggestion experiment with the classes and the methods and properties on the classes to get a better feel of what they do, this is only intended to be a quick reference to these classes.

IronCAD - Tool Expression Server


This part refers to the Expression.vbp project in the Example 11 directory in the accompanying source code.

The IronCAD Tool Expression Server is an expression solver and also manages expressions on a form from one field to another. This is the expression solver that all of the Tools use in IronCAD and has been made available to the public so that when system variables in IronCAD are possible all Add-Ons can use the system variables in IronCAD. The expression solver takes international settings into account as well as the locale. Visual Basic 6.0 is required to implement it since it makes needs to be implemented on the Validate event of a control. Instead of describing how it works an example of a simple dialog has been provided which implements the expression solver so the way which it works can be understood. The Expression.vbp project inside of the Example 11 directory shows a simple implementation of the CExpressionServer class.

IronCAD - Tool Selection Helper


The IronCAD - Tool Selection Helper utility provides a mechanism for AddOns to allow a user to select a shape or face while maintaining all the data that needs to be held on to in the Add-On dialog. The main class that is used is the ICSelectionDialog class. The CallbackData property is an object that can be set to an object which contains information that needs to be returned when the selection is finished. The CallbackObject is a string that represents the Program ID of the class that needs to be invoked when the selection is completed. The object specified by the Program ID above must implement the ICSelectionInterface defined in the utility as well. The Page property on the ICSelectionDialog must be set to a Page object in the IronCAD Type Library so the utility knows which scene to monitor the selection state of. Then finally the SelectionParameters property needs to be set to a newly created instance of the ICSelectionInfo class which contains the information on which type of shapes or faces can be selected along with how many. Once all of the properties have been set then call the Show method on the ICSelectionDialog class and unload the DLL that the call was made in so the dialog is not modal anymore. This utility is a multithreaded ActiveX EXE so by unloading the DLL that invoked the selection dialog, it will not stop the selection. The DLL or form that did invoke it must unload so that the user can interact in the scene. When the user selects what Page 103 of 104

IronCAD Customization: IronCAD Utilities Reference needs to be and clicks the <Finish> button, a call back to the object specified by the Program ID will be made.

Page 104 of 104

S-ar putea să vă placă și