[vtkusers] Mac OSX fixes

Eugene Kim eugene at salk.edu
Fri Aug 27 16:35:20 EDT 2004


Hello everyone,

	After some tedious work, I think I got the MAC to work.  Along
with the previous fixes I suggested, which I believe David Clunie commited
to CVS, VTK with Java on the Mac should now work.  Here we are:

	1) Memory issues: If you try running Cone examples, you might get
	   to work 1/10 times.  The problem is a pointer that hasn't been
	   assigned yet.  In vtkCocoaRenderWindow.mm, in the function
	   WindowInitialize(), you will see a call to an object
	   vtkCocoaGLView *glview, and later an intialization and
	   allocation of it.  We need to immediately set its other member
	   variables as other functions ask for them very soon.  After
	   the intialization, write in:

		[glView setVTKRenderWindow:this];
		[glview setVTKRenderWindowInteractor:0];

	   and delete these two calls which you'll see further down, (or
	   likewise just move them up).  This should solve 90% of your
	   problems.

	2) NS*** Leaks: If you add a autorelease pool around the entire
	   function of WindowInitialize() in vtkCocoaRenderWindow.mm,
	   you can get rid of those nasty messages popping up on your
	   console.  The way I did it was to add as the first line:

	   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	   and as the last line:

	   [pool release];

	3) If you need vtkPanel or vtkCanvas to work, you'll find you now
	   cannot merge windows into a swing canvas. The fix I suggest
	   here is only a partial one, as further problems keep coming up.
	   Also, it will destroy the functionality of creating stand alone
	   vtk windows, so make sure you note that change if you decide to
	   make it.  The following fix is lengthy and innefficent.  This
	   is simply a rough fix to get things working:

	   At the end of WindowInitialize() in vtkCocoaRenderWindow.mm,
	   you'll find a call this->OpenGLInit();.  Just BEFORE that, add
	   this rather large statment:

	   if(!this->ContextId) {
		NSWindow *coreWin = [(NSView *)this->WindowId window];
		glRect = [(NSView *)this->WindowId bounds];

		glView = [[vtkCocoaGLVIew alloc] initWithFrame:glRect];
		[glView setVTKRenderWindow:this];
		[glView setVTKRenderWindowInteractor:0];

		[(NSView *)this->WindowId addSubview:glView];

		vtkCocoaWindow *window = [[vtkCocoaWindow alloc] init];
		[window setFrame:ctRect display:NO];
		[window setvtkCocoaGLView:glView];
		[window setVTKRenderWindow:this];
		[window setVTKRenderWindowInteractor:0];

		[glView
setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
		[coreWin makeFirstResponder:coreWin];
		[glView setNextResponder:(NSView *)this->WindowId];

		[(NSView *)this->WindowId display];
		[glView display];
		this->WindowId = window;
		this->ContextId = [glView getOpenGLContext];
		this->OwnWindow = 1;
	   }

	   I have to admit, the code is messy.  Basically, I just played
	   with the code until it worked, (I don't really know
	   objective-C).  I realize that much of the code is repeated up
	   above, and it could be done WAY more efficiently as long as we
	   know where a View is coming from.  Basically, this is what i've
	   done.  When you want to paint a vtk window on top of a Java
	   canvas or whatever, vtkJavaAwt assigns the WindowId variable
	   in vtkCocoaRenderWindow.mm.  This means that in that
	   WindowInitialize() function, the chunk of code which intializes
	   everything is bypassed, and specifically the OpenGl properties
	   needed when we call OpenGLInit() are not there, and we crash.
	   OpenGLContext is some sort of object (which i don't
	   understand), that allows for these initializations, so the goal
	   is to set it, as it hasn't been done by WindowInitialize().  We
	   retrieve the pointer to the actual window(called a View) we
	   want to paint on, and also retrieve its parent window (which
	   happens to be your JFrame or whatever you use).  After this,
	   you create all the usual machinery as the normal code does.
	   The trick is to fool the vtkCocoaWindow into not displaying,
	   and to use its properties to link the system correctly.  The
	   most important part is to add you newly created glView as a
	   subview of the actual Java view.  After some other stuff,
	   (which you may not even need, I just left it as was without
	   doing much housekeeping), we set the ContextId variable.

	4) If you plan on using being able to interact with these windows
	   in a Swing application, you'll need to do a few more things.
	   First off, comment out the parts in vtkCocoaWindow.mm which
	   call:

		[self setContentView:myvtkCocoaGLView];
		[self makeFirstResponder:thevtkCocoaGLView];

	   This is a dangerous move, as it will probably remove your
	   ability to make stand alone vtk windows.  I say probably,
	   because I haven't actually tried it.

	   Also, in vtkCocoaGLView.mm, in order to send events all the
	   down to your Java canvas, you'll need to repropagate the event
	   signal.  All you have to do is for the given event you want
	   sent, add as the first line in each function:

		[[self window] makeFirstResponder:[self superview]];

	   I have not yet gotten this to work well with mouseDragged
	   events.  The simple solution here is to add in the
	   NSMouseDragged switch in the mouseDown function, and call
	   to a function which we will define.  First we add a new
	   function to the very end:

		- (void)mouseDragged:(NSEvent *)theEvent {
		  [[self superview] mouseDragged:theEvent];
		}

	   and in that switch case I mentioned, add a call like this:

		[self mouseDragged:theEvent];

	   For me, I decided not to use this functionality as I began
	   to get some REALLY weird bus errors... but it does work to
	   a degree, albiet a very small one.

	As these fixes are messy at best, I have not added them to CVS. I
basically neglected cleaning up any unneeded code and such after it began
to work, so I appolgize for any dumb code.  It has been working quite well
for me for about 1-2 weeks, and it is pretty stable though it still
crashes every once in awhile.  I'm very open to any improvements, (they're
probably obvious), as I would like my mac to be just as good as my linux
machine.  (Also, since this message was long, there might be some typos in
the code as I didn't bother to check!).

Eugene Kim



More information about the vtkusers mailing list