// Pre-render callback // void refreshCompute::preRenderCB(const MString& panelName, void * data) { refreshCompute *thisCompute = (refreshCompute *) data; if (!thisCompute) return; M3dView view; MStatus status = M3dView::getM3dViewFromModelPanel(panelName, view); if (status != MS::kSuccess) return; int width = 0, height = 0; width = view.portWidth( &status ); if (status != MS::kSuccess || (width < 2)) return; height = view.portHeight( &status ); if (status != MS::kSuccess || (height < 2)) return; unsigned int vx,vy,vwidth,vheight; vx = 0; vy = 0; vwidth = width / 2; vheight = height / 2; status = view.pushViewport (vx, vy, vwidth, vheight); if (thisCompute->mBufferOperation != kDrawDepthBuffer) { M3dView view; MStatus status = M3dView::getM3dViewFromModelPanel(panelName, view); MPoint origin; status = view.drawText( MString("Pre render callback: ") + panelName, origin ); } }
MStatus initializePlugin(MObject obj) { MFnPlugin plugin(obj, "David Kouril", "1.0", "Any"); MStatus status = plugin.registerNode(CustomLocator::typeName, CustomLocator::typeId, CustomLocator::creator, CustomLocator::initialize, MPxNode::kLocatorNode); // is this why it didn't work before????????? yep, looks like it // register startStreamingCommand command status = plugin.registerCommand("startM2CVStreaming", startStreamingCommand::creator); status = plugin.registerCommand("endM2CVStreaming", endStreamingCommand::creator); status = plugin.registerCommand("showM2CVWindow", showStreamingWindowCommand::creator); streamer = new Streamer; // add a custom menu with items: Start streaming, Stop streaming MGlobal::executeCommand("global string $gMainWindow"); MGlobal::executeCommand("setParent $gMainWindow"); MGlobal::executeCommand("menu -label \"MayaToCellVIEW\" mayaToCelViewMenu"); MGlobal::executeCommand("setParent -menu mayaToCelViewMenu"); MGlobal::executeCommand("menuItem -label \"Start Streaming\" -command \"startM2CVStreaming\" startStreamingItem"); MGlobal::executeCommand("menuItem -label \"End Streaming\" -command \"endM2CVStreaming\" -enable false endStreamingItem"); MGlobal::executeCommand("menuItem -label \"Show Streaming Window\" -command \"showM2CVWindow\" -enable true showWindowItem"); if (!status) { status.perror("Failed to register customLocator\n"); return status; } std::cout << "initializePlugin successful." << std::endl; MStatus status1; M3dView viewport = M3dView::active3dView(&status1); std::cerr << "viewport dims: " << viewport.portWidth() << ", " << viewport.portHeight() << std::endl; // just testing the callbacks: MStatus callBackStatus; //MCallbackId callBackId = MUiMessage::add3dViewPostRenderMsgCallback(MString("persp"), &simpleCallBackTest, nullptr, &callBackStatus); MCallbackId callBackId = MUiMessage::add3dViewPostRenderMsgCallback(MString("modelPanel4"), &simpleCallBackTest, nullptr, &callBackStatus); if (callBackId == 0) { std::cerr << "Something's f****d up" << ", status: " << callBackStatus << std::endl; } return status; }
void xorDraw::beginXorDrawing() { // Save the state of these 3 attribtes and restore them later. glGetBooleanv (GL_DEPTH_TEST, depthTest); glGetBooleanv (GL_COLOR_LOGIC_OP, colorLogicOp); glGetBooleanv (GL_LINE_STIPPLE, lineStipple); glDrawBuffer( GL_FRONT ); // Turn Line stippling on. glLineStipple( 1, 0x5555 ); glLineWidth( 1.0 ); glEnable( GL_LINE_STIPPLE ); // Save the state of the matrix on stack glMatrixMode (GL_MODELVIEW); glPushMatrix(); // Setup the Orthographic projection Matrix. glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluOrtho2D( 0.0, (GLdouble) fView->portWidth(), 0.0, (GLdouble) fView->portHeight() ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef(0.375, 0.375, 0.0); // Set the draw color glColor3f(1.0f, 1.0f, 1.0f); // Draw the marquee in XOR mode glDisable (GL_DEPTH_TEST); // Enable XOR mode. glEnable(GL_COLOR_LOGIC_OP); glLogicOp (GL_XOR); }
MStatus viewCapture::doIt( const MArgList& args ) { MStatus status = MS::kSuccess; if ( args.length() != 1 ) { // Need the file name argument // return MS::kFailure; } MString fileName; args.get( 0, fileName ); // Get the active 3D view // M3dView view = M3dView::active3dView(); // Capture the current view // view.refresh(); view.beginGL(); // Set the target for our pixel read to be the front buffer. First, the // current state is saved using the glPushAttrib call. It is important // to leave the OpenGL in the same state that we found it. // glPushAttrib( GL_PIXEL_MODE_BIT ); int width = view.portWidth(); int height = view.portHeight(); // Allocate buffers for the pixel data // GLfloat * red = new GLfloat[width*height]; GLfloat * green = new GLfloat[width*height]; GLfloat * blue = new GLfloat[width*height]; // Read the values from the OpenGL frame buffer // glReadBuffer( GL_FRONT ); glReadPixels( 0, 0, width, height, GL_RED, GL_FLOAT, red ); glReadPixels( 0, 0, width, height, GL_GREEN, GL_FLOAT, green ); glReadPixels( 0, 0, width, height, GL_BLUE, GL_FLOAT, blue ); // Put the gl read target back // glPopAttrib(); view.endGL(); // Write file as a PPM // Pic_Pixel * line = PixelAlloc( width ); int idx; Pic * file = PicOpen( fileName.asChar(), (short) width, (short) height ); if ( NULL != file ) { for ( int row = height - 1; row >= 0; row-- ) { // Covert the row of pixels into PPM format // for ( int col = 0; col < width; col++ ) { // Find the array elements for this pixel // idx = ( row * width ) + ( col ); line[col].r = (Pic_byte)( red[idx] * 255.0 ); line[col].g = (Pic_byte)( green[idx] * 255.0 ); line[col].b = (Pic_byte)( blue[idx] * 255.0 ); } // Write the line // if ( !PicWriteLine( file, line ) ) { status = MS::kFailure; return MS::kFailure; } } PicClose( file ); } delete []red; delete []green; delete []blue; PixelFree( line ); return status; }
MStatus marqueeContext::doRelease( MEvent & event ) // // Selects objects within the marquee box. { MSelectionList incomingList, marqueeList; // Clear the marquee when you release the mouse button #ifdef USE_SOFTWARE_OVERLAYS GLboolean depthTest[1]; GLboolean colorLogicOp[1]; GLboolean lineStipple[1]; event.getPosition( last_x, last_y ); // Save the state of these 3 attribtes and restore them later. glGetBooleanv (GL_DEPTH_TEST, depthTest); glGetBooleanv (GL_COLOR_LOGIC_OP, colorLogicOp); glGetBooleanv (GL_LINE_STIPPLE, lineStipple); // Turn Line stippling on. glLineStipple( 1, 0x5555 ); glLineWidth( 1.0 ); glEnable( GL_LINE_STIPPLE ); // Disable GL_DEPTH_TEST glDisable (GL_DEPTH_TEST); // Enable XOR mode. glEnable(GL_COLOR_LOGIC_OP); glLogicOp (GL_INVERT); // Save the current Matrix onto the stack glMatrixMode (GL_MODELVIEW); glPushMatrix(); // Setup the Orthographic projection Matrix. glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluOrtho2D( 0.0, (GLdouble) view.portWidth(), 0.0, (GLdouble) view.portHeight() ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef(0.375, 0.375, 0.0); // Set the draw color glIndexi (2); // Redraw the marquee so that it will be cleared from the screen // when the mouse is released. glBegin( GL_LINE_LOOP ); glVertex2i( start_x, start_y ); glVertex2i( p_last_x, start_y ); glVertex2i( p_last_x, p_last_y ); glVertex2i( start_x, p_last_y ); glEnd(); #ifndef _WIN32 glXSwapBuffers( view.display(), view.window() ); #else SwapBuffers( view.deviceContext() ); #endif // Restore saved Matrix from stack glMatrixMode( GL_MODELVIEW ); glPopMatrix(); glDisable(GL_COLOR_LOGIC_OP); // Restore the previous state of these attributes if (colorLogicOp[0]) glEnable (GL_COLOR_LOGIC_OP); else glDisable (GL_COLOR_LOGIC_OP); if (depthTest[0]) glEnable (GL_DEPTH_TEST); else glDisable (GL_DEPTH_TEST); if (lineStipple[0]) glEnable( GL_LINE_STIPPLE ); else glDisable( GL_LINE_STIPPLE ); #else // If HW overlays enabled, then clear the overlay plane // such that the marquee is no longer drawn on screen. view.clearOverlayPlane(); view.endOverlayDrawing(); #endif view.endGL(); // Get the end position of the marquee event.getPosition( last_x, last_y ); // Save the state of the current selections. The "selectFromSceen" // below will alter the active list, and we have to be able to put // it back. MGlobal::getActiveSelectionList(incomingList); // If we have a zero dimension box, just do a point pick // if ( abs(start_x - last_x) < 2 && abs(start_y - last_y) < 2 ) { MGlobal::selectFromScreen( start_x, start_y, MGlobal::kReplaceList ); } else { // Select all the objects or components within the marquee. MGlobal::selectFromScreen( start_x, start_y, last_x, last_y, MGlobal::kReplaceList ); } // Get the list of selected items MGlobal::getActiveSelectionList(marqueeList); // Restore the active selection list to what it was before // the "selectFromScreen" MGlobal::setActiveSelectionList(incomingList, MGlobal::kReplaceList); // Update the selection list as indicated by the modifier keys. MGlobal::selectCommand(marqueeList, listAdjustment); return MS::kSuccess; }
MStatus marqueeContext::doDrag( MEvent & event ) // // Drag out the marquee (using OpenGL) // { event.getPosition( last_x, last_y ); #ifdef USE_SOFTWARE_OVERLAYS GLboolean depthTest[1]; GLboolean colorLogicOp[1]; GLboolean lineStipple[1]; // Save the state of these 3 attribtes and restore them later. glGetBooleanv (GL_DEPTH_TEST, depthTest); glGetBooleanv (GL_COLOR_LOGIC_OP, colorLogicOp); glGetBooleanv (GL_LINE_STIPPLE, lineStipple); #endif // Turn Line stippling on. glLineStipple( 1, 0x5555 ); glLineWidth( 1.0 ); glEnable( GL_LINE_STIPPLE ); // Save the state of the matrix on stack glMatrixMode (GL_MODELVIEW); glPushMatrix(); // Setup the Orthographic projection Matrix. glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluOrtho2D( 0.0, (GLdouble) view.portWidth(), 0.0, (GLdouble) view.portHeight() ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef(0.375, 0.375, 0.0); // Set the draw color glIndexi (2); // If we are using software overlays then we need to draw the marquee // in XOR mode #ifdef USE_SOFTWARE_OVERLAYS glDisable (GL_DEPTH_TEST); // Enable XOR mode. glEnable(GL_COLOR_LOGIC_OP); glLogicOp (GL_XOR); // We erase the previously drawn rubber band on the screen by // redrawing it in XOR OpenGL mode. if (fsDrawn) { glBegin( GL_LINE_LOOP ); glVertex2i( start_x, start_y ); glVertex2i( p_last_x, start_y ); glVertex2i( p_last_x, p_last_y ); glVertex2i( start_x, p_last_y ); glEnd(); } fsDrawn = true; #else // If HW overlays enabled then we will clear the overlay plane // so that the previously drawn marquee does not appear on the screen // anymore view.clearOverlayPlane(); #endif // Draw the rectangular marquee // glBegin( GL_LINE_LOOP ); glVertex2i( start_x, start_y ); glVertex2i( last_x, start_y ); glVertex2i( last_x, last_y ); glVertex2i( start_x, last_y ); glEnd(); #ifdef _WIN32 SwapBuffers( view.deviceContext() ); #elif defined (OSMac_) ::aglSwapBuffers(view.display()); #else glXSwapBuffers( view.display(), view.window() ); #endif // Restore the state of the matrix from stack glMatrixMode( GL_MODELVIEW ); glPopMatrix(); #ifdef USE_SOFTWARE_OVERLAYS // Store the current x and y coordinates such that in the next iteration // we can erase this marquee by redrawing it in XOR mode. p_last_x = last_x; p_last_y = last_y; // Restore the previous state of these attributes if (colorLogicOp[0]) glEnable (GL_COLOR_LOGIC_OP); else glDisable (GL_COLOR_LOGIC_OP); if (depthTest[0]) glEnable (GL_DEPTH_TEST); else glDisable (GL_DEPTH_TEST); if (lineStipple[0]) glEnable( GL_LINE_STIPPLE ); else glDisable( GL_LINE_STIPPLE ); #endif return MS::kSuccess; }
void ProxyViz::draw( M3dView & view, const MDagPath & path, M3dView::DisplayStyle style, M3dView::DisplayStatus status ) { if(!m_enableCompute) return; MObject thisNode = thisMObject(); updateWorldSpace(thisNode); MPlug mutxplug( thisNode, axmultiplier); MPlug mutyplug( thisNode, aymultiplier); MPlug mutzplug( thisNode, azmultiplier); setScaleMuliplier(mutxplug.asFloat(), mutyplug.asFloat(), mutzplug.asFloat() ); MPlug svtPlug(thisNode, adisplayVox); setShowVoxLodThresold(svtPlug.asFloat() ); MDagPath cameraPath; view.getCamera(cameraPath); if(hasView() ) updateViewFrustum(thisNode); else updateViewFrustum(cameraPath); setViewportAspect(view.portWidth(), view.portHeight() ); MPlug actp(thisNode, aactivated); if(actp.asBool()) setWireColor(.125f, .1925f, .1725f); else setWireColor(.0675f, .0675f, .0675f); _viewport = view; fHasView = 1; view.beginGL(); double mm[16]; matrix_as_array(_worldInverseSpace, mm); glPushMatrix(); glMultMatrixd(mm); ExampVox * defBox = plantExample(0); updateGeomBox(defBox, thisNode); drawWireBox(defBox->geomCenterV(), defBox->geomScale() ); Matrix44F mat; mat.setFrontOrientation(Vector3F::YAxis); mat.scaleBy(defBox->geomSize() ); mat.glMatrix(m_transBuf); drawCircle(m_transBuf); drawGridBounding(); // drawGrid(); if ( style == M3dView::kFlatShaded || style == M3dView::kGouraudShaded ) { drawPlants(); } else drawWiredPlants(); if(hasView() ) drawViewFrustum(); drawBrush(view); drawActivePlants(); drawGround(); glPopMatrix(); view.endGL(); std::cout<<" viz node draw end"; }
// Post-render callback // void refreshCompute::postRenderCB(const MString& panelName, void * data) { refreshCompute *thisCompute = (refreshCompute *) data; if (!thisCompute) return; // Get the view if any for the panel M3dView view; MStatus status = M3dView::getM3dViewFromModelPanel(panelName, view); if (status != MS::kSuccess) return; view.popViewport(); if (thisCompute->mBufferOperation == kDrawDepthBuffer) { int width = 0, height = 0; width = view.portWidth( &status ) / 2 ; if (status != MS::kSuccess || (width < 2)) return; height = view.portHeight( &status ) / 2 ; if (status != MS::kSuccess || (height < 2)) return; unsigned int numPixels = width * height; float *depthPixels = new float[numPixels]; if (!depthPixels) return; unsigned char *colorPixels = new unsigned char[numPixels * 4]; if (!colorPixels) { delete depthPixels; delete colorPixels; } // Read into a float buffer status = view.readDepthMap( 0,0, width, height, (unsigned char *)depthPixels, M3dView::kDepth_Float ); if (status != MS::kSuccess) { delete depthPixels; delete colorPixels; return; } // Find depth range and remap normalized depth range (-1 to 1) into 0...255 // for color. float *dPtr = depthPixels; unsigned int i = 0; float zmin = 100.0f; // *dPtr; float zmax = -100.0f; // *dPtr; for(i=0; i<numPixels; i++) { float val = *dPtr; // * 2.0f - 1.0f; if(val < zmin) { zmin = *dPtr; } if(val > zmax) { zmax = *dPtr; } dPtr++; } float zrange = zmax - zmin; //printf("depth values = (%g, %g). Range = %g\n", zmin, zmax, zrange); unsigned char *cPtr = colorPixels; dPtr = depthPixels; for(i=0; i < numPixels; i++) { float val = *dPtr; // * 2.0f - 1.0f; //unsigned char depth = (unsigned char)(255.0f * (( (*dPtr)-zmin) / zrange) + zmin ); unsigned char depth = (unsigned char)(255.0f * (( (val)-zmin) / zrange) ); //unsigned char depth = (unsigned char)(255.0f * val); *cPtr = depth; cPtr++; *cPtr = depth; cPtr++; *cPtr = depth; cPtr++; *cPtr = 0xff; cPtr++; dPtr++; } MImage image; image.setPixels( colorPixels, width, height ); // Uncomment next line to test writing buffer to file. //image.writeToFile( "C:\\temp\\dumpDepth.iff" ); // Write all pixels back. The origin of the image (lower left) // is used status = view.writeColorBuffer( image, 5, 5 ); if (depthPixels) delete depthPixels; if (colorPixels) delete colorPixels; } // Do a simple color invert operation on all pixels // else if (thisCompute->mBufferOperation == kInvertColorBuffer) { // Optional to read as RGBA. Note that this will be slower // since we must swizzle the bytes around from the default // BGRA format. bool readAsRGBA = true; // Read the RGB values from the color buffer MImage image; status = view.readColorBuffer( image, readAsRGBA ); if (status != MS::kSuccess) return; status = view.writeColorBuffer( image, 5, 5 ); unsigned char *pixelPtr = (unsigned char*)image.pixels(); if (pixelPtr) { unsigned int width, height; image.getSize( width, height ); MImage image2; image2.create( width, height ); unsigned char *pixelPtr2 = (unsigned char*)image2.pixels(); unsigned int numPixels = width * height; for (unsigned int i=0; i < numPixels; i++) { *pixelPtr2 = (255 - *pixelPtr); pixelPtr2++; pixelPtr++; *pixelPtr2 = (255 - *pixelPtr); pixelPtr2++; pixelPtr++; *pixelPtr2 = (255 - *pixelPtr); pixelPtr2++; pixelPtr++; *pixelPtr2 = 255; pixelPtr2++; pixelPtr++; } // Write all pixels back. The origin of the image (lower left) // is used status = view.writeColorBuffer( image2, 5, short(5+height/2) ); } } }
bool SceneShapeUI::snap( MSelectInfo &snapInfo ) const { MStatus s; if( snapInfo.displayStatus() != M3dView::kHilite ) { MSelectionMask meshMask( MSelectionMask::kSelectMeshes ); if( !snapInfo.selectable( meshMask ) ) { return false; } } // early out if we have no scene to draw SceneShape *sceneShape = static_cast<SceneShape *>( surfaceShape() ); const IECore::SceneInterface *sceneInterface = sceneShape->getSceneInterface().get(); if( !sceneInterface ) { return false; } IECoreGL::ConstScenePtr scene = sceneShape->glScene(); if( !scene ) { return false; } // Get the viewport that the snapping operation is taking place in. M3dView view = snapInfo.view(); // Use an IECoreGL::Selector to find the point in world space that we wish to snap to. // We do this by first getting the origin of the selection ray and transforming it into // NDC space using the OpenGL projection and transformation matrices. Once we have the // point in NDC we can use it to define the viewport that the IECoreGL::Selector will use. MPoint localRayOrigin; MVector localRayDirection; snapInfo.getLocalRay( localRayOrigin, localRayDirection ); Imath::V3d org( localRayOrigin[0], localRayOrigin[1], localRayOrigin[2] ); MDagPath camera; view.getCamera( camera ); MMatrix localToCamera = snapInfo.selectPath().inclusiveMatrix() * camera.inclusiveMatrix().inverse(); view.beginSelect(); Imath::M44d projectionMatrix; glGetDoublev( GL_PROJECTION_MATRIX, projectionMatrix.getValue() ); view.endSelect(); double v[4][4]; localToCamera.get( v ); Imath::M44d cam( v ); Imath::V3d ndcPt3d = ( (org * cam ) * projectionMatrix + Imath::V3d( 1. ) ) * Imath::V3d( .5 ); Imath::V2d ndcPt( std::max( std::min( ndcPt3d[0], 1. ), 0. ), 1. - std::max( std::min( ndcPt3d[1], 1. ), 0. ) ); view.beginGL(); glMatrixMode( GL_PROJECTION ); glLoadMatrixd( projectionMatrix.getValue() ); float radius = .001; // The radius of the selection area in NDC. double aspect = double( view.portWidth() ) / view.portHeight(); Imath::V2f selectionWH( radius, radius * aspect ); std::vector<IECoreGL::HitRecord> hits; { IECoreGL::Selector selector( Imath::Box2f( ndcPt - selectionWH, ndcPt + selectionWH ), IECoreGL::Selector::IDRender, hits ); IECoreGL::State::bindBaseState(); selector.baseState()->bind(); scene->render( selector.baseState() ); } view.endGL(); if( hits.empty() ) { return false; } // Get the closest mesh hit. float depthMin = std::numeric_limits<float>::max(); int depthMinIndex = -1; for( unsigned int i=0, e = hits.size(); i < e; i++ ) { if( hits[i].depthMin < depthMin ) { depthMin = hits[i].depthMin; depthMinIndex = i; } } // Get the absolute path of the hit object. IECore::SceneInterface::Path objPath; std::string objPathStr; sceneInterface->path( objPath ); IECore::SceneInterface::pathToString( objPath, objPathStr ); objPathStr += IECoreGL::NameStateComponent::nameFromGLName( hits[depthMinIndex].name ); IECore::SceneInterface::stringToPath( objPathStr, objPath ); // Validate the hit selection. IECore::ConstSceneInterfacePtr childInterface; try { childInterface = sceneInterface->scene( objPath ); } catch(...) { return false; } if( !childInterface ) { return false; } if( !childInterface->hasObject() ) { return false; } // Get the mesh primitive so that we can query it's vertices. double time = sceneShape->time(); IECore::ConstObjectPtr object = childInterface->readObject( time ); IECore::ConstMeshPrimitivePtr meshPtr = IECore::runTimeCast<const IECore::MeshPrimitive>( object.get() ); if ( !meshPtr ) { return false; } // Calculate the snap point in object space. MPoint worldIntersectionPoint; selectionRayToWorldSpacePoint( camera, snapInfo, depthMin, worldIntersectionPoint ); Imath::V3f pt( worldIntersectionPoint[0], worldIntersectionPoint[1], worldIntersectionPoint[2] ); Imath::M44f objToWorld( worldTransform( childInterface.get(), time ) ); pt = pt * objToWorld.inverse(); // Get the list of vertices in the mesh. IECore::V3fVectorData::ConstPtr pointData( meshPtr->variableData<IECore::V3fVectorData>( "P", IECore::PrimitiveVariable::Vertex ) ); const std::vector<Imath::V3f> &vertices( pointData->readable() ); // Find the vertex that is closest to the snap point. Imath::V3d closestVertex; float closestDistance = std::numeric_limits<float>::max(); for( std::vector<Imath::V3f>::const_iterator it( vertices.begin() ); it != vertices.end(); ++it ) { Imath::V3d vert( *it ); float d( ( pt - vert ).length() ); // Calculate the distance between the vertex and the snap point. if( d < closestDistance ) { closestDistance = d; closestVertex = vert; } } // Snap to the vertex. closestVertex *= objToWorld; snapInfo.setSnapPoint( MPoint( closestVertex[0], closestVertex[1], closestVertex[2] ) ); return true; }