HOOPS/Winforms Integration Guide

Introduction

The HOOPS/Winforms integration consists a connection between HOOPS/3dGS and the Winforms ‘Panel’ and ‘Form’ GUI objects. This document describes how to use the HOOPS/Winforms integration to build a .NET Winforms application that incorporates the HOOPS/3DF components. Some familiarity with .NET Winforms, HOOPS/3dGS and HOOPS/MVO is assumed.

Developers should start by compiling and running the basic csharp_simple application as the starting point for their application. This is the primary example for .NET developers wishing to incorporate the HOOPS/3DF components into either existing or new .NET applications. The readable source code is located in your <hoops>/demo/dotnet/csharp_simple and <hoops>/demo/dotnet/vb_simple directories.

Compilation and Runtime Information

The following steps are required to compile and run a HOOPS/Winforms based application:

  • Compiling: Your application must reference the HOOPS/3DF C# wrapper classes.

    • hoops_cs.dll

    • hics_cs.dll

    • hoops_mvo_cs.dll

    • hoops_stream_cs.dll

    • hoops_panel.dll

  • Executing: Ensure that the following native .DLLs are in your application’s directory or in your PATH.

    • hoops_vc.dll

    • hcs.dll

    • hics.dll

    • hoops_mvo_mgk_vc.dll

    • hcsmvo.dll

    • hoops_stream_vc.dll

    • hcsstream.dll

    • hoops_panel.dll

The above files are located in your <VISUALIZE_INSTALL_DIR>/bin/nt_x64_v<version> directory.

Component Object Relationships

This section discusses the relationship between .NET Winforms and HOOPS/3DF components. Building an application with both these toolkits minimally involves using the following objects from each component.

Winforms

A .NET Winforms application typically has a master Form object, which contains child forms. Each child form may contain a Panel.

HOOPS/Winforms

There should be at least one set of the HNPanel and HNForm objects, where the panel gets attached to the form. You usually create a custom panel and form derived from HNPanel and HNForm. The HNPanel and HNForm classes are found in <hoops>/Dev_Tools/hoops_winforms/source/.

HOOPS/MVO

HBaseModel, HBaseView, and an operator class derived from HBaseOperator. Applications that want to implement selection of geometry will also need a HSelectionSet object. These objects are all connected by private data members which store pointers to other objects in the following manner:

../../_images/HOOPS_winforms_arch.gif

Steps to Building an Application with .NET Winforms and HOOPS

Programming with an object oriented GUI framework like .NET Winforms involves creating a set of objects and defining the ways in which they are connected, the manner in which they send and receive messages, and then launching the framework’s event loop. Building an application using .NET Winforms and HOOPS/3DF specifically requires creation and initialization of:

Creating and Initializing the Application

A .NET Winforms application usually creates a master Form object which implements the function Main(). The csharp_simple application does this in it’s primary csharp_simple.cs source file as follows:

public class SimpleAppForm : Form
{
   ...

        /*! Entry point for the application*/
        static void Main()
        {
                SimpleAppForm hoops = new SimpleAppForm();
                Application.Run(hoops);
        }

        ...
}

Creating and Initializing HOOPS/Winforms Objects

The HOOPS/Winforms integration consists of a customized .NET Winforms ‘Form’ and ‘Panel’ called HNForm and HNPanel, as diagrammed up above. (Again, the Panel will get attached to the form.) As many pairs of these objects can be created as needed to implement the GUI’s design. Your application should define custom HNForm and HNPanel classes, as shown in csharp_simple source.

Custom HNPanel definition taken from the csharp_simple project’s SimpleHNPanel.cs source file:

public class SimpleHNPanel : HNPanel
{
        // Constructor which calls the Init() method of the class
        public SimpleHNPanel(): base()
        {
                Init();
        }


        // This method will set up the default HOOPS/MVO view for the panel and attach a HOOPS/MVO default operator
        public new void Init()
        {
                // contents reviewed later
        }

        ...
}

Here is custom HNForm definition taken from the csharp_simple project’s SimpleHNForm.cs source file. Note that it creates the custom HNPanel object and initializes the form:

public class SimpleHNForm : HNForm
{
        ...

        // Sets up the panel and window
        public void Init(object sender, EventArgs e)
        {
                // set up the panel that HOOPS will draw into
                m_pHNPanel = new SimpleHNPanel();

                Instance = (this.IsMdiChild) ? ((HForm)this.MdiParent).win_count : 0;

                // first set up the window, then set the axis triad options
                Init_Form();

                m_pHNPanel.m_pHView.Update();
                m_pHNPanel.m_pHView.SetAxisMode(AxisMode.AxisOn);
                m_pHNPanel.m_pHView.AdjustAxisWindow();

                ...
        }

        ...
}

Finally, we can note that the fileNew and fileOpen methods of main app object (SimpleAppForm, again located in csharp_simple.cs) will create the custom HNForm object:

public class SimpleAppForm : Form
{
                ...

                private void fileNewMenu_Click(object sender, EventArgs e)
                {
                        SimpleHNForm frmchild = new SimpleHNForm();
                        frmchild.MdiParent = this;
                        frmchild.Show();
                        win_count++;
                }


                private void fileOpenMenu_Click(object sender, EventArgs e)
                {
                        OpenFileDialog dlg = new OpenFileDialog();
                        dlg.Title = "Open";
                        dlg.Filter = "HMF/HSF files (*.hmf, *.hsf)|*.hmf;*.hsf" +
                                                 "|All files (*.*)|*.*";

                        if (dlg.ShowDialog() == DialogResult.OK)
                        {
                                SimpleHNForm frmchild = new SimpleHNForm();
                                frmchild.MdiParent = this;
                                frmchild.Show();

                                frmchild.LoadFile(dlg);
                                win_count++;
                        }
                        dlg.Dispose();
                }

                ...
}

Creating and Initializing HOOPS/MVO Objects

HDB

One global pointer to a HOOPS/MVO HDB object should be declared and initialized in your application’s main class. The csharp_simple app does this in the main SimpleAppForm constructor (located in csharp_simple.cs):

public class SimpleAppForm : Form
{
        ...

        // Constructor which initializes hoops database and GUI features of the main window */
        public SimpleAppForm()
        {
                win_count = 1;

                m_pHDB = new HDB();
                m_pHDB.Init();

                ...
        }

        ...
}

HBaseModel

Multiple HBaseModel objects can be created as needed. The csharp_simple app creates one for every SimpleHNPanel object (i.e., there is a one-to-one mapping of HBaseModel to SimpleHNPanel objects) and does so in the SimpleHNPanel::Init:

public class SimpleHNPanel : HNPanel
{
  ...

  public new void Init()
  {
        ...

        m_pHModel = new HSimpleModel();
        m_pHModel.Init();

        ...
  }

}

HBaseView

Multiple HBaseView objects can be created as needed, with one object usually being created for each HNPanel. The HBaseView needs a valid native GUI window id passed to its constructor on object creation; this information is used to connect a HOOPS/3dGS output driver instance to a HNPanel. This requires that the HNPanel, to which the HBaseView will be attached, already exist prior to creating the HBaseView object.

Your app should create the HBaseView object in your overloaded HNPanel::Init method. Here is the csharp_simple example taken from csharp_simple.cs:

public class SimpleHNPanel : HNPanel
{
        ...

        public new void Init()
        {
                ...

                m_pHView = new HSimpleView(m_pHModel, "?picture" + SimpleHNForm.Instance, "opengl", "", winid);
                m_pHView.Init();

                ...
        }

}

HSelectionSet

The HBaseView class and HNPanel class contain pointers to a HSelectionSet object. A selection set class would typically be created and initialized during HNPanel initialization. After creation, it’s important to pass the HSelectionSet operator into HBaseView by calling HBaseView::SetSelection. The csharp_simple app does this in the overloaded method of HNPanel::Init method:

public class SimpleHNPanel : HNPanel
{
        ...

        public new void Init()
        {
                ...

                // view and model initialization goes here, and was discussed previously

                // Set up the custom HSelectionSet object
                m_pHSelection = new HSimpleSelectionSet(m_pHView);
                m_pHView.SetSelection(m_pHSelection);
                m_pHView.GetSelection().Init();

                ...
        }

}

HBaseOperator

The HBaseView class and HNPanel class contains pointers to a HBaseOperator object. A default operator would typically be created and initialized during HNPanel initialization. After creating, you should set it to be the current operator by calling the utility method HNPanel::SetCurrentOperator. The csharp_simple app does this in the overloaded method of HNPanel::Init method:

public class SimpleHNPanel : HNPanel
{
        ...

        public new void Init()
        {
                ...

                // Set the default operator
                m_pHOperator = new HOpCameraManipulate(m_pHView);
                m_pHView.SetCurrentOperator((HBaseOperator)m_pHOperator);

                ...
        }

}