OpenCASCADE6.2 and Windows Forms

All samples in the OpenCASCADE distribution are using either MFC, QT of Java/Swing for its GUI. I would be interested if anybody has successfully converted the MakeBottle tutorial to Windows Forms using Visual C++. Two people from this forum have already done this using C# but I would be interested in C++.
I am new to OpenCASCADE, so I'm sorry if this is an obvious question.

Regards, Recage

Sven Jungnickel's picture

Here is some sample code from a small VC++ .NET application I'm currently working on. Most of the problems come from mixing up unmanaged and managed code. Managed class may not have unmanaged classes as members, therefore you have to store OCC Handles as pointers in managed classes. That's the reason why I use the macro OCC_HANDLE.

Hope this helps to get you started.

Sven

Header File:

#pragma once

#include "StdAfx.h"

//////////////////////////////////////////////////////////////////////////////
// OPEN CASCADE Includes
//////////////////////////////////////////////////////////////////////////////

#pragma warning ( disable: 4267 4311 4312 4005 4835 )

#include
#include
#include
#include
#include
#include

#pragma warning ( default: 4267 4311 4312 4005 4835 )

//////////////////////////////////////////////////////////////////////////////
// Local Includes
//////////////////////////////////////////////////////////////////////////////

#include "FileDrawer.h"
#include "IgesFile.h"
#include "AIS2D_Segment.h"

#define OCC_HANDLE(h) (*h)

namespace lgworks_sgs_converter
{
ref class IgesFileDrawer : public FileDrawer
{
public:
IgesFileDrawer(System::String^ path);
~IgesFileDrawer();
!IgesFileDrawer();

virtual void Draw(System::Windows::Forms::Control^ object) override;

private:

// Helper functions
void Init(Control^ object);

private:

IgesFile^ m_IgesFile;

/// Viewer-Handle
Handle(V2d_Viewer)* m_pHandleViewer;

/// View-Handle
Handle(V2d_View)* m_pHandleView;

/// Fenster-Handle
Handle(WNT_Window)* m_pHandleWindow;

/// Grafik-Device
Handle(WNT_GraphicDevice)* m_pHandleGraphicDevice;

/// Grafik-Driver
Handle(WNT_WDriver)* m_pHandleDriver;

/// Interaktiver Kontext
Handle(AIS2D_InteractiveContext)* m_pHandleInteractiveContext;

// 2D-Segment
Handle(AIS2D_Segment)* m_pHandleSegment;
};
}

Implementation File:

//////////////////////////////////////////////////////////////////////////////
// OPEN CASCADE Includes
//////////////////////////////////////////////////////////////////////////////

#pragma warning ( disable: 4267 4311 4312 4005 4835 )

#include
#include
#include
#include

#pragma warning ( default: 4267 4311 4312 4005 4835 )

//////////////////////////////////////////////////////////////////////////////
// Local Includes
//////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "IgesFileDrawer.h"
#include "AIS2D_Segment.h"

//////////////////////////////////////////////////////////////////////////////
// Namespaces
//////////////////////////////////////////////////////////////////////////////

using namespace lgworks_sgs_converter;
using namespace System;
using namespace System::Windows::Forms;

//////////////////////////////////////////////////////////////////////////////
// Defines
//////////////////////////////////////////////////////////////////////////////

// Notwendig da nicht verwaltete Klassen (Handle ist eine Klasse) keine Member
// von verwaltetetn Klassen sein können, das Makro führt die Derefenzierung
// durch

// ===========================================================================

IgesFileDrawer::IgesFileDrawer(System::String^ path)
: m_pHandleViewer(NULL)
, m_pHandleView(NULL)
, m_pHandleWindow(NULL)
, m_pHandleGraphicDevice(NULL)
, m_pHandleInteractiveContext(NULL)
{
m_IgesFile = gcnew IgesFile(path);
}

// ===========================================================================

IgesFileDrawer::~IgesFileDrawer()
{
// Finalizer ausführen (Vermeidung Code-Duplikation)
this->!IgesFileDrawer();

// GarbageCollector signalisieren, dass der Finalizer bereits ausgeführt
// worden ist
System::GC::SuppressFinalize(this);
}

// ===========================================================================

IgesFileDrawer::!IgesFileDrawer()
{
// Finalizer zur Freigabe der nicht verwaltetetn Resourcen

if ( m_pHandleInteractiveContext != NULL )
{
OCC_HANDLE(m_pHandleInteractiveContext).Nullify();
}

if ( m_pHandleView != NULL )
{
OCC_HANDLE(m_pHandleView).Nullify();
}

if ( m_pHandleViewer != NULL )
{
OCC_HANDLE(m_pHandleViewer).Nullify();
}

if ( m_pHandleWindow != NULL )
{
OCC_HANDLE(m_pHandleWindow).Nullify();
}

if ( m_pHandleGraphicDevice != NULL )
{
OCC_HANDLE(m_pHandleGraphicDevice).Nullify();
}
}

// ===========================================================================

void IgesFileDrawer::Draw(Control^ object)
{
// Ggf. Initialisierung durchführen
if ( m_pHandleGraphicDevice == NULL )
{
Init(object);
}

OCC_HANDLE(this->m_pHandleView)->SetImmediateUpdate(Standard_False);

// Segment zeichnen
OCC_HANDLE(m_pHandleInteractiveContext)->Display(OCC_HANDLE(m_pHandleSegment), Standard_False);

OCC_HANDLE(this->m_pHandleView)->Fitall();
OCC_HANDLE(this->m_pHandleView)->MustBeResized(V2d_TOWRE_ENLARGE_OBJECTS);
OCC_HANDLE(this->m_pHandleView)->SetImmediateUpdate(Standard_True);

OCC_HANDLE(this->m_pHandleView)->Update();
}

// ===========================================================================

void IgesFileDrawer::Init(Control^ object)
{
// Grafik-Device erzeugen
m_pHandleGraphicDevice = new Handle(WNT_GraphicDevice);
OCC_HANDLE(m_pHandleGraphicDevice) = new WNT_GraphicDevice();

// Window-Mapping durchführen
m_pHandleWindow = new Handle(WNT_Window);
OCC_HANDLE(m_pHandleWindow) = new WNT_Window(OCC_HANDLE(m_pHandleGraphicDevice), (HWND)object->Handle.ToPointer());//, Quantity_NOC_WHITE);

// Driver erzeugen
m_pHandleDriver = new Handle(WNT_WDriver);
OCC_HANDLE(m_pHandleDriver) = new WNT_WDriver(OCC_HANDLE(m_pHandleWindow));

// 3D-Viewer erzeugen
m_pHandleViewer = new Handle(V2d_Viewer);
OCC_HANDLE(m_pHandleViewer) = new V2d_Viewer(OCC_HANDLE(m_pHandleGraphicDevice),(short *) "Visu2D");
OCC_HANDLE(m_pHandleViewer)->ActivateGrid(Aspect_GT_Rectangular, Aspect_GDM_Lines);

// 3D-View erzeugen
m_pHandleView = new Handle(V2d_View);
OCC_HANDLE(m_pHandleView) = new V2d_View(OCC_HANDLE(m_pHandleDriver), OCC_HANDLE(m_pHandleViewer));

// Interaktiven Kontext erzeugen
m_pHandleInteractiveContext = new Handle(AIS2D_InteractiveContext);
OCC_HANDLE(m_pHandleInteractiveContext) = new AIS2D_InteractiveContext(OCC_HANDLE(m_pHandleViewer));

// FontMap erzeugen
Handle(Aspect_FontMap) fntmap = new Aspect_FontMap;
Aspect_FontStyle fontstyle(Aspect_TOF_HELVETICA, 1);
Aspect_FontMapEntry fntmapentry (1, fontstyle);
fntmap->AddEntry(fntmapentry);
OCC_HANDLE(m_pHandleViewer)->SetFontMap(fntmap);

// Segmente erzeugen
TColgp_SequenceOfPnt sequence;
this->m_IgesFile->GetSequence(sequence);
m_pHandleSegment = new Handle(AIS2D_Segment);
OCC_HANDLE(m_pHandleSegment) = new AIS2D_Segment(Quantity_NOC_BLACK, sequence);
OCC_HANDLE(m_pHandleSegment)->SetContext(OCC_HANDLE(m_pHandleInteractiveContext));

return;
}

Sven Jungnickel's picture

Here is some sample code from a small VC++ .NET application I'm currently working on. Most of the problems come from mixing up unmanaged and managed code. Managed class may not have unmanaged classes as members, therefore you have to store OCC Handles as pointers in managed classes. That's the reason why I use the macro OCC_HANDLE.

Hope this helps to get you started.

Sven

Header File:

#pragma once

#include "StdAfx.h"

//////////////////////////////////////////////////////////////////////////////
// OPEN CASCADE Includes
//////////////////////////////////////////////////////////////////////////////

#pragma warning ( disable: 4267 4311 4312 4005 4835 )

#include
#include
#include
#include
#include
#include

#pragma warning ( default: 4267 4311 4312 4005 4835 )

//////////////////////////////////////////////////////////////////////////////
// Local Includes
//////////////////////////////////////////////////////////////////////////////

#include "FileDrawer.h"
#include "IgesFile.h"
#include "AIS2D_Segment.h"

#define OCC_HANDLE(h) (*h)

namespace lgworks_sgs_converter
{
ref class IgesFileDrawer : public FileDrawer
{
public:
IgesFileDrawer(System::String^ path);
~IgesFileDrawer();
!IgesFileDrawer();

virtual void Draw(System::Windows::Forms::Control^ object) override;

private:

// Helper functions
void Init(Control^ object);

private:

IgesFile^ m_IgesFile;

/// Viewer-Handle
Handle(V2d_Viewer)* m_pHandleViewer;

/// View-Handle
Handle(V2d_View)* m_pHandleView;

/// Fenster-Handle
Handle(WNT_Window)* m_pHandleWindow;

/// Grafik-Device
Handle(WNT_GraphicDevice)* m_pHandleGraphicDevice;

/// Grafik-Driver
Handle(WNT_WDriver)* m_pHandleDriver;

/// Interaktiver Kontext
Handle(AIS2D_InteractiveContext)* m_pHandleInteractiveContext;

// 2D-Segment
Handle(AIS2D_Segment)* m_pHandleSegment;
};
}

Implementation File:

//////////////////////////////////////////////////////////////////////////////
// OPEN CASCADE Includes
//////////////////////////////////////////////////////////////////////////////

#pragma warning ( disable: 4267 4311 4312 4005 4835 )

#include
#include
#include
#include

#pragma warning ( default: 4267 4311 4312 4005 4835 )

//////////////////////////////////////////////////////////////////////////////
// Local Includes
//////////////////////////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "IgesFileDrawer.h"
#include "AIS2D_Segment.h"

//////////////////////////////////////////////////////////////////////////////
// Namespaces
//////////////////////////////////////////////////////////////////////////////

using namespace lgworks_sgs_converter;
using namespace System;
using namespace System::Windows::Forms;

//////////////////////////////////////////////////////////////////////////////
// Defines
//////////////////////////////////////////////////////////////////////////////

// Notwendig da nicht verwaltete Klassen (Handle ist eine Klasse) keine Member
// von verwaltetetn Klassen sein können, das Makro führt die Derefenzierung
// durch

// ===========================================================================

IgesFileDrawer::IgesFileDrawer(System::String^ path)
: m_pHandleViewer(NULL)
, m_pHandleView(NULL)
, m_pHandleWindow(NULL)
, m_pHandleGraphicDevice(NULL)
, m_pHandleInteractiveContext(NULL)
{
m_IgesFile = gcnew IgesFile(path);
}

// ===========================================================================

IgesFileDrawer::~IgesFileDrawer()
{
// Finalizer ausführen (Vermeidung Code-Duplikation)
this->!IgesFileDrawer();

// GarbageCollector signalisieren, dass der Finalizer bereits ausgeführt
// worden ist
System::GC::SuppressFinalize(this);
}

// ===========================================================================

IgesFileDrawer::!IgesFileDrawer()
{
// Finalizer zur Freigabe der nicht verwaltetetn Resourcen

if ( m_pHandleInteractiveContext != NULL )
{
OCC_HANDLE(m_pHandleInteractiveContext).Nullify();
}

if ( m_pHandleView != NULL )
{
OCC_HANDLE(m_pHandleView).Nullify();
}

if ( m_pHandleViewer != NULL )
{
OCC_HANDLE(m_pHandleViewer).Nullify();
}

if ( m_pHandleWindow != NULL )
{
OCC_HANDLE(m_pHandleWindow).Nullify();
}

if ( m_pHandleGraphicDevice != NULL )
{
OCC_HANDLE(m_pHandleGraphicDevice).Nullify();
}
}

// ===========================================================================

void IgesFileDrawer::Draw(Control^ object)
{
// Ggf. Initialisierung durchführen
if ( m_pHandleGraphicDevice == NULL )
{
Init(object);
}

OCC_HANDLE(this->m_pHandleView)->SetImmediateUpdate(Standard_False);

// Segment zeichnen
OCC_HANDLE(m_pHandleInteractiveContext)->Display(OCC_HANDLE(m_pHandleSegment), Standard_False);

OCC_HANDLE(this->m_pHandleView)->Fitall();
OCC_HANDLE(this->m_pHandleView)->MustBeResized(V2d_TOWRE_ENLARGE_OBJECTS);
OCC_HANDLE(this->m_pHandleView)->SetImmediateUpdate(Standard_True);

OCC_HANDLE(this->m_pHandleView)->Update();
}

// ===========================================================================

void IgesFileDrawer::Init(Control^ object)
{
// Grafik-Device erzeugen
m_pHandleGraphicDevice = new Handle(WNT_GraphicDevice);
OCC_HANDLE(m_pHandleGraphicDevice) = new WNT_GraphicDevice();

// Window-Mapping durchführen
m_pHandleWindow = new Handle(WNT_Window);
OCC_HANDLE(m_pHandleWindow) = new WNT_Window(OCC_HANDLE(m_pHandleGraphicDevice), (HWND)object->Handle.ToPointer());//, Quantity_NOC_WHITE);

// Driver erzeugen
m_pHandleDriver = new Handle(WNT_WDriver);
OCC_HANDLE(m_pHandleDriver) = new WNT_WDriver(OCC_HANDLE(m_pHandleWindow));

// 3D-Viewer erzeugen
m_pHandleViewer = new Handle(V2d_Viewer);
OCC_HANDLE(m_pHandleViewer) = new V2d_Viewer(OCC_HANDLE(m_pHandleGraphicDevice),(short *) "Visu2D");
OCC_HANDLE(m_pHandleViewer)->ActivateGrid(Aspect_GT_Rectangular, Aspect_GDM_Lines);

// 3D-View erzeugen
m_pHandleView = new Handle(V2d_View);
OCC_HANDLE(m_pHandleView) = new V2d_View(OCC_HANDLE(m_pHandleDriver), OCC_HANDLE(m_pHandleViewer));

// Interaktiven Kontext erzeugen
m_pHandleInteractiveContext = new Handle(AIS2D_InteractiveContext);
OCC_HANDLE(m_pHandleInteractiveContext) = new AIS2D_InteractiveContext(OCC_HANDLE(m_pHandleViewer));

// FontMap erzeugen
Handle(Aspect_FontMap) fntmap = new Aspect_FontMap;
Aspect_FontStyle fontstyle(Aspect_TOF_HELVETICA, 1);
Aspect_FontMapEntry fntmapentry (1, fontstyle);
fntmap->AddEntry(fntmapentry);
OCC_HANDLE(m_pHandleViewer)->SetFontMap(fntmap);

// Segmente erzeugen
TColgp_SequenceOfPnt sequence;
this->m_IgesFile->GetSequence(sequence);
m_pHandleSegment = new Handle(AIS2D_Segment);
OCC_HANDLE(m_pHandleSegment) = new AIS2D_Segment(Quantity_NOC_BLACK, sequence);
OCC_HANDLE(m_pHandleSegment)->SetContext(OCC_HANDLE(m_pHandleInteractiveContext));

return;
}