void QgsDetailedItemDelegate::drawHighlight( const QStyleOptionViewItem &theOption, QPainter * thepPainter, int theHeight ) const { QColor myColor1 = theOption.palette.highlight().color(); QColor myColor2 = myColor1; myColor2 = myColor2.lighter( 110 ); //10% lighter QLinearGradient myGradient( QPointF( 0, theOption.rect.y() ), QPointF( 0, theOption.rect.y() + theHeight ) ); myGradient.setColorAt( 0, myColor1 ); myGradient.setColorAt( 0.1, myColor2 ); myGradient.setColorAt( 0.5, myColor1 ); myGradient.setColorAt( 0.9, myColor2 ); myGradient.setColorAt( 1, myColor2 ); thepPainter->fillRect( theOption.rect, QBrush( myGradient ) ); }
void TrafficGraph::drawBeams(QPainter *p, int top, int w, int h, int horizontalScale) { Q_ASSERT(mNiceRange != 0); if(mNiceRange == 0) mNiceRange = 1; double scaleFac = (h-1) / mNiceRange; int xPos = 0; QLinkedList< QList<double> >::Iterator it = mBeamData.begin(); p->setPen(Qt::NoPen); /* In autoRange mode we determine the range and plot the values in * one go. This is more efficiently than running through the * buffers twice but we do react on recently discarded samples as * well as new samples one plot too late. So the range is not * correct if the recently discarded samples are larger or smaller * than the current extreme values. But we can probably live with * this. * * These values aren't used directly anywhere. Instead we call * calculateNiceRange() which massages these values into a nicer * values. Rounding etc. This means it's safe to change these values * without affecting any other drawings * */ if ( mUseAutoRange ) mMinValue = mMaxValue = 0.0; /* mBezierCurveOffset is how many points we have at the start. * All the bezier curves are in groups of 3, with the first of the next group being the last point * of the previous group-> * * Example, when mBezierCurveOffset == 0, and we have data, then just plot a normal bezier curve * (we will have at least 3 points in this case) * When mBezierCurveOffset == 1, then we want a bezier curve that uses the first data point and * the second data point. Then the next group starts from the second data point. * When mBezierCurveOffset == 2, then we want a bezier curve that uses the first, second and third data * */ for (unsigned int i = 0; it != mBeamData.end() && i < mSamples; ++i) { QPen pen; pen.setWidth(1); pen.setCapStyle(Qt::FlatCap); /** * We will plot 1 bezier curve for every 3 points, with the 4th point being the end * of one bezier curve and the start of the second. * This does means the bezier curves will not join nicely, * but it should be better than nothing. */ QList<double> datapoints = *it; QList<double> prev_datapoints = datapoints; QList<double> prev_prev_datapoints = datapoints; QList<double> prev_prev_prev_datapoints = datapoints; if (i == 0 && mBezierCurveOffset>0) { /** * We are plotting an incomplete bezier curve - we don't have all the data we want. * Try to cope */ xPos += horizontalScale*mBezierCurveOffset; if (mBezierCurveOffset == 1) { prev_datapoints = *it; ++it; //Now we are on the first element of the next group, if it exists if (it != mBeamData.end()) { prev_prev_prev_datapoints = prev_prev_datapoints = *it; } else { prev_prev_prev_datapoints = prev_prev_datapoints = prev_datapoints; } } else { // mBezierCurveOffset must be 2 now prev_datapoints = *it; Q_ASSERT(it != mBeamData.end()); ++it; prev_prev_datapoints = *it; Q_ASSERT(it != mBeamData.end()); ++it; //Now we are on the first element of the next group, if it exists if (it != mBeamData.end()) { prev_prev_prev_datapoints = *it; } else { prev_prev_prev_datapoints = prev_prev_datapoints; } } } else { /** * We have a group of 3 points at least. That's 1 start point and 2 control points. */ xPos += horizontalScale*3; it++; if (it != mBeamData.end()) { prev_datapoints = *it; it++; if (it != mBeamData.end()) { prev_prev_datapoints = *it; it++; //We are now on the next set of data points if (it != mBeamData.end()) { // We have this datapoint, so use it for our finish point prev_prev_prev_datapoints = *it; } else { // We don't have the next set, so use our last control point as our finish point prev_prev_prev_datapoints = prev_prev_datapoints; } } else { prev_prev_prev_datapoints = prev_prev_datapoints = prev_datapoints; } } else { prev_prev_prev_datapoints = prev_prev_datapoints = prev_datapoints = datapoints; } } float x0 = w - xPos + 3.0*horizontalScale; float x1 = w - xPos + 2.0*horizontalScale; float x2 = w - xPos + 1.0*horizontalScale; float x3 = w - xPos; float y0 = h -1 + top; float y1 = y0; float y2 = y0; float y3 = y0; int offset = 0; //Our line is 2 pixels thick. This means that when we draw the area, we need to offset double max_y=0; double min_y=0; for (int j = qMin(datapoints.size(), mBeamColors.size())-1; j >=0 ; --j) { if ( mUseAutoRange) { //If we use autorange, then we need to prepare the min and max values for _next_ time we paint //if we are stacking the beams, then we need to add the maximums together double current_maxvalue = qMax(datapoints[j], qMax(prev_datapoints[j], qMax(prev_prev_datapoints[j], prev_prev_prev_datapoints[j]))); double current_minvalue = qMin(datapoints[j], qMin(prev_datapoints[j], qMin(prev_prev_datapoints[j], prev_prev_prev_datapoints[j]))); mMaxValue = qMax(mMaxValue, current_maxvalue); mMinValue = qMin(mMinValue, current_maxvalue); if( mStackBeams ) { max_y += current_maxvalue; min_y += current_minvalue; } } /* * Draw polygon only if enough data points are available. */ if ( j < prev_prev_prev_datapoints.count() && j < prev_prev_datapoints.count() && j < prev_datapoints.count() ) { QPolygon curve( 4 ); /* The height of the whole widget is h+top-> The height of the area we are plotting in is just h. * The y coordinate system starts from the top, so at the bottom the y coordinate is h+top * So to draw a point at value y', we need to put this at h+top-y' */ float delta_y0; delta_y0 = (datapoints[j] - mNiceMinValue)*scaleFac; float delta_y1; delta_y1 = (prev_datapoints[j] - mNiceMinValue)*scaleFac; float delta_y2; delta_y2 = (prev_prev_datapoints[j] - mNiceMinValue)*scaleFac; float delta_y3; delta_y3 = (prev_prev_prev_datapoints[j] - mNiceMinValue)*scaleFac; QPainterPath path; if(mStackBeams && offset) { //we don't want the lines to overdraw each other. This isn't a great solution though :( if(delta_y0 < 3) delta_y0=3; if(delta_y1 < 3) delta_y1=3; if(delta_y2 < 3) delta_y2=3; if(delta_y3 < 3) delta_y3=3; } path.moveTo( x0,y0-delta_y0); path.cubicTo( x1,y1-delta_y1,x2,y2-delta_y2,x3,y3-delta_y3 ); if(mFillBeams) { QPainterPath path2(path); QLinearGradient myGradient(0,(h-1+top),0,(h-1+top)/5); Q_ASSERT(mBeamColorsDark.size() >= j); Q_ASSERT(mBeamColors.size() >= j); QColor c0(mBeamColorsDark[j]); QColor c1(mBeamColors[j]); c0.setAlpha(150); c1.setAlpha(150); myGradient.setColorAt(0, c0); myGradient.setColorAt(1, c1); path2.lineTo( x3,y3-offset); if(mStackBeams) path2.cubicTo( x2,y2-offset,x1,y1-offset,x0,y0-offset); //offset is set to 1 after the first beam is drawn, so we don't trample on top of the 2pt thick line else path2.lineTo(x0,y0-1); p->setBrush(myGradient); p->setPen(Qt::NoPen); p->drawPath( path2 ); } p->setBrush(Qt::NoBrush); Q_ASSERT(mBeamColors.size() >= j); pen.setColor(mBeamColors[j]); p->setPen(pen); p->drawPath( path ); if(mStackBeams) { //We can draw the beams stacked on top of each other. This means that say beam 0 has the value 2 and beam // 1 has the value 3, then we plot beam 0 at 2 and beam 1 at 2+3 = 5. y0-=delta_y0; y1-=delta_y1; y2-=delta_y2; y3-=delta_y3; offset = 1; //see the comment further up for int offset; } } if ( mUseAutoRange && mStackBeams) { mMaxValue = qMax(max_y, mMaxValue); mMinValue = qMin(min_y, mMinValue); } } } }
void VRAY_clusterThis::preProcess(GU_Detail * gdp) { GEO_Point * ppt; long int num_points = (long int) gdp->points().entries(); long int stat_interval = (long int)(num_points * 0.10) + 1; for(uint32 i = gdp->points().entries(); i-- > 0;) { ppt = gdp->points()(i); myPointList.append(i); } // If the user wants to build grids for pre processing // TODO: Should this be an option? There may be functions/features that will depend on this ... discuss! if(!myPreProcess) return; if(myVerbose > CLUSTER_MSG_INFO) cout << "VRAY_clusterThis::preProcess() Pre Processing Voxels" << std::endl; // openvdb::ScalarGrid::Accessor accessor; // openvdb::FloatTree myTree; openvdb::FloatTree::ConstPtr myGeoTreePtr; openvdb::VectorTree::ConstPtr myGeoGradTreePtr; ParticleList paGeoList(gdp, myPreVDBRadiusMult, myPreVDBVelocityMult); openvdb::tools::PointSampler myGeoSampler, geoGradSampler; // openvdb::tools::GridSampling<openvdb::FloatTree> myGridSampler; if(myVerbose == CLUSTER_MSG_DEBUG) std::cout << "VRAY_clusterThis::preProcess() paGeoList.size() ... " << paGeoList.size() << std::endl; if(paGeoList.size() != 0) { hvdb::Interrupter boss("VRAY_clusterThis::preProcess() Converting particles to level set"); Settings settings; settings.mRadiusMin = myPreRadiusMin; settings.mRasterizeTrails = myPreRasterType; settings.mDx = myPreDx; // only used for rasterizeTrails() settings.mFogVolume = myPreFogVolume; settings.mGradientWidth = myPreGradientWidth; // only used for fog volume float background; // background in WS units if(myPreWSUnits) background = myPreBandWidth; // background NOT in WS units else background = myPreVoxelSize * myPreBandWidth; // Construct a new scalar grid with the specified background value. openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(myPreVoxelSize); // openvdb::ScalarGrid::Ptr myGeoGrid = openvdb::ScalarGrid::create(background); myGeoGrid = openvdb::ScalarGrid::create(background); myGeoGrid->setTransform(transform); myGeoGrid->setGridClass(openvdb::GRID_LEVEL_SET); // Perform the particle conversion. this->convert(myGeoGrid, paGeoList, settings, boss); if(myVerbose == CLUSTER_MSG_DEBUG) { std::cout << "VRAY_clusterThis::preProcess() - activeVoxelCount(): " << myGeoGrid->activeVoxelCount() << std::endl; std::cout << "VRAY_clusterThis::preProcess() - background: " << myGeoGrid->background() << std::endl; } // Insert the new grid into the ouput detail. UT_String gridNameStr = "ClusterGrid"; myGeoGrid->insertMeta("float type", openvdb::StringMetadata("averaged_velocity")); myGeoGrid->insertMeta("name", openvdb::StringMetadata((const char *)gridNameStr)); myGeoGrid->insertMeta("VoxelSize", openvdb::FloatMetadata(myPreVoxelSize)); myGeoGrid->insertMeta("background", openvdb::FloatMetadata(background)); UT_Vector3 pos, seed_pos, currVel; // const GA_PointGroup * sourceGroup = NULL; long int pt_counter = 0; float radius = 5.0f; if(myVerbose > CLUSTER_MSG_INFO) std::cout << "VRAY_clusterThis::preProcess() - Massaging data ... " << std::endl; long int pointsFound = 0; GEO_AttributeHandle inst_vel_gah = gdp->getPointAttribute("v"); GEO_AttributeHandle source_vel_gah = gdp->getPointAttribute("v"); GEO_AttributeHandle inst_N_gah = gdp->getPointAttribute("N"); GEO_AttributeHandle source_N_gah = gdp->getPointAttribute("N"); GEO_AttributeHandle inst_Cd_gah = gdp->getPointAttribute("Cd"); GEO_AttributeHandle source_Cd_gah = gdp->getPointAttribute("Cd"); GEO_AttributeHandle inst_Alpha_gah = gdp->getPointAttribute("Alpha"); GEO_AttributeHandle source_Alpha_gah = gdp->getPointAttribute("Alpha"); if(!inst_vel_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Instance velocity handle invalid, exiting ...", 1); if(!source_vel_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Source velocity handle invalid, exiting ...", 1); if(!inst_N_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Instance normal handle invalid, exiting ...", 1); if(!source_N_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Source normal handle invalid, exiting ...", 1); if(!inst_Cd_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Instance color handle invalid, exiting ...", 1); if(!source_Cd_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Source color handle invalid, exiting ...", 1); if(!inst_Alpha_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Instance alpha handle invalid, exiting ...", 1); if(!source_Alpha_gah.isAttributeValid()) throw VRAY_clusterThis_Exception("VRAY_clusterThis::preProcess() Source alpha handle invalid, exiting ...", 1); openvdb::FloatTree::ValueType sampleResult; openvdb::VectorGrid::ValueType gradResult; const openvdb::FloatTree aTree; openvdb::FloatTree& myGeoTree = myGeoGrid->treeRW(); openvdb::tools::Filter<openvdb::FloatGrid> preProcessFilter(*myGeoGrid); // openvdb::tools::Filter<openvdb::FloatGrid> barFilter(myGeoGrid); if(myPreVDBMedianFilter) preProcessFilter.median(); if(myPreVDBMeanFilter) preProcessFilter.mean(); if(myPreVDBMeanCurvatureFilter) preProcessFilter.meanCurvature(); if(myPreVDBLaplacianFilter) preProcessFilter.laplacian(); // if(myVDBReNormalizeFilter) // float r = barFilter.renormalize(3, 0.1); if(myPreVDBOffsetFilter) preProcessFilter.offset(myPreVDBOffsetFilterAmount); myGradientGrid = openvdb::VectorGrid::create(); // openvdb::VectorGrid::Ptr myGradientGrid = openvdb::VectorGrid::create(); myGradientGrid->setTransform(transform); // myGradientGrid->setGridClass(openvdb::GRID_FOG_VOLUME ); myGradientGrid->setGridClass(openvdb::GRID_LEVEL_SET); openvdb::tools::Gradient<openvdb::ScalarGrid> myGradient(*myGeoGrid); myGradientGrid = myGradient.process(); openvdb::VectorTree& myGeoGradTree = myGradientGrid->treeRW(); gridNameStr = "ClusterGradientGrid"; myGradientGrid->insertMeta("vector type", openvdb::StringMetadata("covariant (gradient)")); myGradientGrid->insertMeta("name", openvdb::StringMetadata((const char *)gridNameStr)); myGradientGrid->insertMeta("VoxelSize", openvdb::FloatMetadata(myPreVoxelSize)); myGradientGrid->insertMeta("background", openvdb::FloatMetadata(background)); GA_FOR_ALL_GPOINTS(gdp, ppt) { // myCurrPtOff = ppt->getMapOffset(); // std::cout << "myCurrPtOff: " << myCurrPtOff << std::endl; pos = ppt->getPos(); // Vec3d worldToIndex ( const Vec3d & xyz ) const // openvdb::Vec3R theIndex = // (openvdb::Vec3R(pos[0], pos[1], pos[2])); openvdb::Vec3R theIndex = myGeoGrid->worldToIndex(openvdb::Vec3R(pos[0], pos[1], pos[2])); radius = static_cast<fpreal>(ppt->getValue<fpreal>(myInstAttrRefs.pointVDBRadius, 0)); // std::cout << "radius: " << radius << std::endl; // static bool sample (const TreeT &inTree, const Vec3R &inCoord, typename TreeT::ValueType &sampleResult) const openvdb::Vec3R inst_sample_pos(theIndex[0], theIndex[1], theIndex[2]); bool success = myGeoSampler.sample(myGeoTree, inst_sample_pos, sampleResult); geoGradSampler.sample(myGeoGradTree, inst_sample_pos, gradResult); // // std::cout << "success: " << success << "\tpos: " << pos // << "\tinst_sample_pos: " << inst_sample_pos // << "\tsampleResult: " << sampleResult << std::endl; //ValueType sampleWorld (const Vec3R &pt) const //ValueType sampleWorld (Real x, Real y, Real z) const // if the instanced point is within the vdb volume if(success) { // std::cout << "pos: " << pos << " inst_sample_pos: " // << inst_sample_pos << " sampleResult: " << sampleResult // << " gradResult: " << gradResult << std::endl; // float weight; pointsFound++; inst_vel_gah.setElement(ppt); currVel = inst_vel_gah.getV3(); UT_Vector3 gradVect = UT_Vector3(gradResult[0], gradResult[1], gradResult[2]); ppt->setPos(pos + (myPrePosInfluence *(sampleResult * gradVect))); // ppt->setPos(pos + (sampleResult * myPosInfluence *(currVel / myFPS))); // inst_vel_gah.setV3(currVel * ((1 / sampleResult) * radius)); inst_vel_gah.setV3(currVel + (myPreVelInfluence *(sampleResult * gradVect))); // std::cout << "currVel: " << currVel << " sampleResult " << sampleResult // << " new vel: " << currVel * sampleResult << std::endl; inst_N_gah.setV3(inst_N_gah.getV3() + (myPreNormalInfluence *(sampleResult * gradVect))); // inst_Cd_gah.setElement(ppt); // inst_Cd_gah.setV3(inst_Cd_gah.getV3() * abs(sampleResult)); // // // inst_Alpha_gah.setElement(ppt); // inst_Alpha_gah.setF(inst_Alpha_gah.getF() * abs(sampleResult)); } // if the instanced point is within the vdb volume if(myVerbose == CLUSTER_MSG_DEBUG) { pt_counter++; if((long int)(pt_counter % (stat_interval * myNumCopies * myRecursion)) == 0) { cout << "VRAY_clusterThis::preProcess() Number of points pre processed: " << pt_counter << "\t - Number of points found in vdb grid: " << pointsFound << std::endl; } } }