Cocoa_Window throwing exception when built

Hello!

I am extremely new to OpenCascade, but I am trying to get its base functionality integrated into my research. I have a simple Topo_DS_Shape object created, and I would like to open up a window and look at it. I don't need anything fancy for now, just a viewer window. So here is my initial attempt (I am working on a macbook pro, early 2015 with HighSierra). 

int main(int argc, char *argv[])
{

  BRepPrimAPI_MakeTorus TorusGen(1.0, 3.0);
  TopoDS_Shape torus = TorusGen.Shape();
  cout << "torus generated" << endl;

  // create a default display connection
  Handle(Aspect_DisplayConnection) aDispConnection = new Aspect_DisplayConnection();
  // create a Graphic Driver
  Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (aDispConnection, true);

  // creating the Viewer
  Handle(V3d_Viewer) aViewer = new V3d_Viewer (aGraphicDriver);

  cout << "V3d_Viewer created" << endl;
  Standard_Integer thePxLeft = 100;
  Standard_Integer thePxTop = 100;
  Standard_Integer thePxWidth = 100;
  Standard_Integer thePxHeight = 100;
  cout << "Creating Cocoa Window..." << endl;
  Handle(Cocoa_Window) aCocoaWindow;
  aCocoaWindow = new Cocoa_Window("title",thePxLeft, thePxTop, thePxWidth, thePxHeight);
  cout << "Cocoa Window created" << endl;

  // creating a View
  Handle(V3d_View) aView = aViewer->CreateView();

  // the Interactive context
  Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext(aViewer);
  Handle(AIS_Shape) anAISShape = new AIS_Shape(torus);
  aContext->Display(anAISShape, true);

  aView->SetWindow(aCocoaWindow);
  cout << "cocoa window associated with aView" << endl;

  aCocoaWindow->Map();

  return 0;
}

This compiles fine, but when I run it, I get an uncaught exception 

Aspect_WindowDefinitionError 

when the Cocoa_Window is being defined. 

I am sure I am making a totally rookie mistake, but  I would love the help!

Thanks!

Kirill Gavrilov's picture
Aspect_WindowDefinitionError 

I think there should more detailed message in console coming with this exception.
If you will look into source code, you will find only a couple of reasons for this error, and I suppose this one was hit:

  else if (NSApp == NULL)
  {
    throw Aspect_WindowDefinitionError("Cocoa application should be instantiated before window");
    return;
  }

Your code does not perform initialization of GUI application.
There is no Cocoa sample coming with OCCT, but you might find useful an old commit with a sample draft (for older OCCT version):
http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff;h=bea07fd...

Corey Nelson's picture

Hello!

Thanks for getting back to me so quickly. 

The full console message reads:

libc++abi.dylib: terminating with uncaught exception of type Aspect_WindowDefinitionError

which is unfortunately not particularly verbose. 

So it appears that the way this stuff is handled in an AppDelegate. I got what I was looking for cooked up with inspiration from that sample draft you posted.

main.mm:

// main.cpp
// AUTHOR:  Corey Wetterer-Nelson
// DATE:    21-Feb-2018
#import <Cocoa/Cocoa.h>
#import <AppKit/AppKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[])
{
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  NSApplication * application = [NSApplication sharedApplication];

  AppDelegate * appDelegate = [[[AppDelegate alloc] init] autorelease];

  [application setDelegate:appDelegate];
  [application run];

  [pool drain];

  return EXIT_SUCCESS;
}

AppDelegate.h

#import <Cocoa/Cocoa.h>
#include "OpenCascade_includes.h"

@interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate> {
    NSWindow * window;
    Handle(Aspect_DisplayConnection) aDispConnection;
    Handle(OpenGl_GraphicDriver) aGraphicDriver;
    Handle(Cocoa_Window) aCocoaWindow;
    Handle(V3d_Viewer) aViewer;
    Handle(V3d_View) aView;
    Handle(AIS_InteractiveContext) aContext;
}
@end

AppDelegate.mm

#import "AppDelegate.h"
#import <Cocoa/Cocoa.h>

#include "OpenCascade_includes.h"

@implementation AppDelegate : NSObject
- (id)init {
    if (self = [super init]) {
      BRepPrimAPI_MakeTorus TorusGen(3.0, 1.5);
      TopoDS_Shape torus = TorusGen.Shape();
      cout << "torus generated" << endl;
      //////////////////////////////////////////////////////////////////////////
      //create a default display connection
      aDispConnection = new Aspect_DisplayConnection();
      // create a Graphic Driver
      aGraphicDriver = new OpenGl_GraphicDriver (aDispConnection, true);

      //////////////////////////////////////////////////////////////////////////
      // creating the Viewer
      aViewer = new V3d_Viewer (aGraphicDriver);
      aViewer->SetDefaultBackgroundColor (Quantity_NOC_BLACK);
      aViewer->SetDefaultLights();
      aViewer->SetLightOn();
      cout << "V3d_Viewer created" << endl;

      //////////////////////////////////////////////////////////////////////////
      //create cocoaWindow
      aCocoaWindow = new Cocoa_Window("DonutViewer",100, 100, 500, 500);
      cout << "Cocoa Window created" << endl;
      aCocoaWindow->Map();
      // aCocoaWindow->HView() returns the associated NSView object
      //////////////////////////////////////////////////////////////////////////
      // replace content view in the window
      [window setContentView: aCocoaWindow->HView()];

      // make view as first responder in window to capture all useful events
      [window makeFirstResponder: aCocoaWindow->HView()];
      //if (!myCtxAis.IsNull())
      [window setAcceptsMouseMovedEvents: YES];

      // creating a View

      aView = aViewer->CreateView();
      aView->SetWindow(aCocoaWindow);
      cout << "cocoa window associated with aView" << endl;
      // the Interactive context
      aContext = new AIS_InteractiveContext(aViewer);
      Handle(AIS_Shape) anAISShape = new AIS_Shape(torus);
      anAISShape->SetColor(Quantity_NOC_RED);
      anAISShape->SetDisplayMode(1);
      aContext->Display(anAISShape, true);

      aCocoaWindow->Map();
      aView->FitAll(0.1, true);
      aView->Redraw();
    }
    return self;
}

- (void)applicationWillFinishLaunching:(NSNotification *)notification {
    [window makeKeyAndOrderFront:self];
}

- (void)dealloc {
    [window release];
    [super dealloc];
}

@end

And that's it! Just gotta make sure all the libraries and frameworks get linked to the build properly. I am certain there are much better ways to accomplish this, but it works, so I'm happy! Attached is a screenshot of the output.

Thank you so much for the help! Hopefully this example will help others get off the ground with OpenCascade on macOS.

Cheers!