// Uses the 4 Tire Temp sensors to draw a color gradient tire void redrawTireTemp(screenItemInfo * item, volatile dataItem * data, double currentValue){ uint16_t fillColor = tempColor(data->value); uint16_t x = item->x; uint16_t y = item->y; uint16_t width = item->size / 4; uint16_t height = item->size * 2; fillCircleSquare(x,y,width*2,height,width,tempColor(data[0].value)); fillCircleSquare(x+(2*width),y,width*2,height,width,tempColor(data[3].value)); fillRect(x+width,y,width,height,tempColor(data[1].value)); fillRect(x+(2*width),y,width,height,tempColor(data[2].value)); }
// Uses the 4 Tire Temp sensors to draw a color gradient tire double redrawTireTemp(screenItemInfo * item, volatile dataItem * data, double currentValue){ volatile dataItem** dataArray = (volatile dataItem**) data; uint16_t fillColor = tempColor(data->value); uint16_t x = item->x; uint16_t y = item->y; uint16_t width = item->size / 4; uint16_t height = item->size * 2; fillCircleSquare(x,y,width*2,height,width,tempColor(dataArray[0]->value)); fillCircleSquare(x+(2*width),y,width*2,height,width,tempColor(dataArray[3]->value)); fillRect(x+width,y,width,height,tempColor(dataArray[1]->value)); fillRect(x+(2*width),y,width,height,tempColor(dataArray[2]->value)); return dataArray[0]->value; }
Sphere::Sphere(){ c(0, 0, 0); r = 0.0; RGBAPixel tempColor(0,255,0); material(tempColor, 1, 1); material.directScale = 1.0; calculateBBox(); }
Sphere::Sphere(const Point3D& p, const double radius){ c(p); r = radius; RGBAPixel tempColor(0,255,0); material(tempColor, 1, 1); material.directScale = 0.2; calculateBBox(); }
QVariant QDbfSqlModel::data(const QModelIndex &index, int role) const { QVariant value = QSqlQueryModel::data(index, role); int i,j,k; QByteArray tempDateArray; QDate tempDate; QTime tempTime; quint32 l; qint32 l1; qint64 l2; double db; bool ok; QString currency; //QLocale clocale(QLocale::German); QLocale clocale(QLocale::C); quint8 r,g,b; QByteArray tempByteArray; //QList<int> charFields; for (i=0;i<charFields.count();i++) { if (index.column() == charFields.at(i)) { switch (role) { case Qt::DisplayRole: break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignLeft | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(charFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> currencyFields; for (i=0;i<currencyFields.count();i++) { if (index.column() == currencyFields.at(i)) { switch (role) { case Qt::DisplayRole: tempDateArray = value.toByteArray(); tempDateArray = QByteArray::fromHex(tempDateArray); l2 = *(qint64 *)tempDateArray.data(); db = l2; currency.setNum(db/10000,'f',4); value = clocale.toString(db/10000,'f',4); break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(currencyFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> numericFields; for (i=0;i<numericFields.count();i++) { if (index.column() == numericFields.at(i)) { switch (role) { case Qt::DisplayRole: currency=value.toString().simplified(); k=currency.count()-1; j=0; ok=false; while (k>0) { if (currency.at(k) == '.') { ok = true; break; } k--; j++; } if (!ok) j=0; value = clocale.toString(currency.toDouble(&ok),'f',j); break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(numericFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> dateFields; for (i=0;i<dateFields.count();i++) { if (index.column() == dateFields.at(i)) { switch (role) { case Qt::DisplayRole: value = value.toDate().toString("dd.MM.yyyy"); break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(dateFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> timeFields; for (i=0;i<timeFields.count();i++) { if (index.column() == timeFields.at(i)) { switch (role) { case Qt::DisplayRole: tempDateArray = value.toByteArray(); tempDateArray = QByteArray::fromHex(tempDateArray); l = *(quint32 *)tempDateArray.data(); tempDate = QDate::fromJulianDay(l); l = *(quint32 *)(tempDateArray.data()+4); tempTime.setHMS(0,0,0); tempTime = tempTime.addMSecs(l); value = tempDate.toString("dd.MM.yyyy")+" "+tempTime.toString("hh:mm:ss.zzz"); break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(timeFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> doubleFields; for (i=0;i<doubleFields.count();i++) { if (index.column() == doubleFields.at(i)) { switch (role) { case Qt::DisplayRole: tempDateArray = value.toByteArray(); tempDateArray = QByteArray::fromHex(tempDateArray); db = *(double *)tempDateArray.data(); value = db; //value = clocale.toString(db,'f',4); break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(doubleFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> intFields; for (i=0;i<intFields.count();i++) { if (index.column() == intFields.at(i)) { switch (role) { case Qt::DisplayRole: tempDateArray = value.toByteArray(); tempDateArray = QByteArray::fromHex(tempDateArray); l1 = *(quint32 *)tempDateArray.data(); value = l1; break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(intFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> logicalFields; for (i=0;i<logicalFields.count();i++) { if (index.column() == logicalFields.at(i)) { switch (role) { case Qt::DisplayRole: break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(logicalFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> memoFields; for (i=0;i<memoFields.count();i++) { if (index.column() == memoFields.at(i)) { switch (role) { case Qt::DisplayRole: break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(memoFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> memo4Fields; for (i=0;i<memo4Fields.count();i++) { if (index.column() == memo4Fields.at(i)) { switch (role) { case Qt::DisplayRole: tempDateArray = value.toByteArray(); tempDateArray = QByteArray::fromHex(tempDateArray); l = *(quint32 *)tempDateArray.data(); value = l; break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(memo4FieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } //QList<int> generalFields; for (i=0;i<generalFields.count();i++) { if (index.column() == generalFields.at(i)) { switch (role) { case Qt::DisplayRole: break; case Qt::TextAlignmentRole: value = QVariant(Qt::AlignRight | Qt::AlignVCenter); break; case Qt::TextColorRole: tempByteArray.append(generalFieldColorString); tempByteArray = QByteArray::fromHex(tempByteArray); r = tempByteArray.at(0); g = tempByteArray.at(1); b = tempByteArray.at(2); QColor tempColor(r,g,b); value = qVariantFromValue(tempColor); break; } } } return value; }
void Coloring(Model& integ) { //CalculateDistance(integ); CalculateDistance_AllVoxel(integ); cout << "CalculateNormal: " << endl; // CalculateNormal(integ); // vector<cv::Mat> UpSilhouette(ImageNum); ReadSilhouette(ImageNum, directory[1], model, pose[0], UpSilhouette); vector<cv::Mat> DownSilhouette(ImageNum); ReadSilhouette(ImageNum, directory[1], model, pose[1], DownSilhouette); vector<cv::Mat> UpImage(ImageNum); ReadColorImage(ImageNum, directory[0], model, pose[0], UpImage); vector<cv::Mat> DownImage(ImageNum); ReadColorImage(ImageNum, directory[0], model, pose[1], DownImage); cv::Point temp; int R, G, B; int step = UpImage[0].step; int width = UpSilhouette[0].cols; int height = UpSilhouette[0].rows; CColor tempColor(0.0, 0.0, 0.0); Color_hue tempColorH; vector<Color_hue> VoxColor; CVector3d Point_Image; short templum; //short thre(50); short thre(123); Color_hue tempBackColor; tempBackColor.r = integ.BackColor.r; tempBackColor.g = integ.BackColor.g; tempBackColor.b = integ.BackColor.b; tempBackColor.CalcHue(); integ.SurfColors.reserve(integ.SurfNum); // int ring1[][2] = { {0, 0}, {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} }; // // // integ.Voxel_colors = new CColor **[integ.num[0]]; for (int i(0); i < integ.num[0]; i++) { integ.Voxel_colors[i] = new CColor *[integ.num[1]]; for (int k(0); k < integ.num[1]; k++) integ.Voxel_colors[i][k] = new CColor[integ.num[2]]; } cout << "\nCheck visable voxels which can be seen\n" << endl; for (int x = 1; x < integ.num[0] - 1; x++) { for (int y = 1; y < integ.num[1] - 1; y++) { for (int z = 1; z < integ.num[2] - 1; z++) { // if (integ.Voxels[x][y][z].surf) { // VoxColor.clear(); for (int i = 0; i < ImageNum; i++) { CanSee(integ, x, y, z, CameraPosUp[i], "UP"); //true(UP) //UP if (integ.Flags[x][y][z].upCan) { integ.Voxels[x][y][z].line.push_back(CameraPosUp[i] - integ.Voxels[x][y][z].center); temp = integ.Voxels[x][y][z].CalcImageCoordofCenter(ART[i]); //� // for (int n = 0; n < 9; n++) { templum = (short)(UpSilhouette[i].data[width * (temp.y + ring1[n][1]) + temp.x + ring1[n][0]]); if (templum < thre) continue; //opencv tempColorH.Clear(); B = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3]; G = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 1]; R = UpImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 2]; tempColorH.b = B / 255.0; tempColorH.g = G / 255.0; tempColorH.r = R / 255.0; tempColorH.CalcHue(); tempColorH.CalcLuminance(); //if( fabs(tempBackColor.GetHue() - tempColorH.GetHue()) < HueGap_Thres ) //�w�i�F�̐F���ɋ߂��F�͎g�p���Ȃ� // continue; // //�V�}�E�}��p //if(tempColorH.luminance>0.5){ // tempColorH.Set(1.0,1.0,1.0); //} //else{ // tempColorH.Set(0.0,0.0,0.0); //} VoxColor.push_back(tempColorH); } } CanSee(integ, x, y, z, CameraPosDown[i], "DOWN"); //false(DOWN) //DOWN if (integ.Flags[x][y][z].downCan) { integ.Voxels[x][y][z].line.push_back(CameraPosDown[i] - integ.Voxels[x][y][z].center); temp = integ.Voxels[x][y][z].CalcImageCoordofCenter(ARTRTinv[i]); //� // for (int n = 0; n < 9; n++) { templum = (short)(DownSilhouette[i].data[width * (temp.y + ring1[n][1]) + temp.x + ring1[n][0]]); if (templum < thre) // continue; //opencv� tempColorH.Clear(); B = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3]; G = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 1]; R = DownImage[i].data[step * (temp.y + ring1[n][1]) + (temp.x + ring1[n][0]) * 3 + 2]; tempColorH.b = B / 255.0; tempColorH.g = G / 255.0; tempColorH.r = R / 255.0; tempColorH.CalcHue(); tempColorH.CalcLuminance(); //if( fabs(tempBackColor.GetHue() - tempColorH.GetHue()) < HueGap_Thres ) // continue; // //if(tempColorH.luminance>0.5){ // tempColorH.Set(1.0,1.0,1.0); //} //else{ // tempColorH.Set(0.0,0.0,0.0); //} VoxColor.push_back(tempColorH); } } } if (!VoxColor.empty()) { tempColor = GetVoxelColor_hue_mode(VoxColor); //tempColor = GetVoxelColor_lumi_mode(VoxColor); //cout<<tempColor.r <<" "<<tempColor.g<<" "<<tempColor.b<<endl; integ.Voxel_colors[x][y][z] = tempColor; integ.SurfColors.push_back(tempColor); } else { integ.Voxel_colors[x][y][z] = tempColor; integ.SurfColors.push_back(tempColor); //0.0.0.0.0.0 } } } } } // UpSilhouette.clear(); UpSilhouette.shrink_to_fit(); DownSilhouette.clear(); DownSilhouette.shrink_to_fit(); UpImage.clear(); UpImage.shrink_to_fit(); DownImage.clear(); DownImage.shrink_to_fit(); }
void RayTracer::traceRay(Ray *r, int depth, Color* tColor){ if (depth>=m_Depth){ return; } Intersection closest, temp; Material tempM; Color tempColor(0.0,0.0,0.0); Color tempKr(0.0,0.0,0.0); double tempKt=0.0; BRDF closestBRDF; Ray tempRay(glm::dvec3(0), glm::dvec3(0), glm::dvec3(0)); std::vector<Ray*> tempRays; closest = Intersection(glm::dvec3(0), tempM, 100000.0, glm::dvec3(0)); bool foundAny = false; for (unsigned int i = 0; i < myPrims.size(); i++){ if (myPrims[i]->Intersects(r,&temp)){ foundAny = true; if(isCloser(r,temp,closest)){ closest = temp; } } } if(!foundAny){ *tColor += tempColor; return; } // else there is an intersection closestBRDF = closest.GetMaterial().GetBRDF(); // get the BRDF from the closest intersection if (depth == 0){ *tColor += closestBRDF.GetKa(); //add the Ka ambient of material *tColor += closestBRDF.GetKe(); //add the Ke emission of material } // loop through all light sources // for an intersection // cast a shadow ray to all lights at the intersection // & determine if they are visible double shadow =0.0; for (unsigned int i=0; i< myLights.size(); i++){ if (avoidAllLightButKaKe){ continue; } // cast a shadow ray to a light source at the intersection point & put it in tempRay myLights[i]->GenerateLightRays(closest.GetPosition(), &tempRays, closest.GetNormal()); float invSamples = 1.0/tempRays.size(); for(std::vector<Ray*>::iterator it=tempRays.begin(); it!=tempRays.end(); ++it) { // determine if the light is visible foundAny = check4Intersection(*it); if (avoidShadows){ foundAny = false; } if (!foundAny){ shadow=invSamples; // if we didn't find any // do shading calculation for this // light source // Li(Kd max(li*n,0)+Ks(n*hi)^s) stars are dot products // Li = light color // Kd = diffuse // li = light direction // n = surface normal // Ks = specular // hi = half angle vector for the light // s = shininess *tColor += shadow* Shading(myLights[i]->GetColor(),closestBRDF.GetKd(), closestBRDF.GetKs(),(*it)->GetD(), closest.GetNormal(),r->GetD(), closestBRDF.GetS()); } } //shadow = 1 - (shadow / tempRays.size()); shadow=0.0; tempRays.clear(); } // Handle mirror reflections tempKr = closestBRDF.GetKr(); if ( ((tempKr.GetR()>0.0) || (tempKr.GetG()>0.0) || (tempKr.GetB()>0.0)) && avoidReflections == false ) { Ray reflectRay = CreateReflectRay(r->GetD(), closest.GetNormal(), closest.GetPosition()); traceRay(&reflectRay, depth+1, &tempColor); // Make a recursive call to trace the reflected ray tempColor = tempKr*tempColor; *tColor += tempColor; } // Handle refractions tempKt = closestBRDF.GetKt(); if (tempKt>0.0 && avoidRefractions == false){ //std::cout<<tempKt<<std::endl; Ray refractRay = CreateRefractRay(r->GetD(),closest.GetNormal(), closest.GetPosition(),depth); traceRay(&refractRay, depth+1, &tempColor); //recursive call //tempColor *= *tColor += tempColor; } return; }
bool GroundPlaneGenerator::getBoardRects(const QString & boardSvg, QGraphicsItem * board, double res, double keepoutSpace, QList<QRect> & rects) { QByteArray boardByteArray; QString tempColor("#000000"); QStringList exceptions; exceptions << "none" << ""; if (!SvgFileSplitter::changeColors(boardSvg, tempColor, exceptions, boardByteArray)) { return false; } QRectF br = board->sceneBoundingRect(); double bWidth = res * br.width() / FSvgRenderer::printerScale(); double bHeight = res * br.height() / FSvgRenderer::printerScale(); QImage image(bWidth, bHeight, QImage::Format_Mono); // Format_RGB32 image.setDotsPerMeterX(res * GraphicsUtils::InchesPerMeter); image.setDotsPerMeterY(res * GraphicsUtils::InchesPerMeter); image.fill(0xffffffff); QSvgRenderer renderer(boardByteArray); QPainter painter; painter.begin(&image); painter.setRenderHint(QPainter::Antialiasing, false); renderer.render(&painter); painter.end(); #ifndef QT_NO_DEBUG //image.save("getBoardRects.png"); #endif QColor keepaway(255,255,255); int threshold = 1; // now add keepout area to the border QImage image2 = image.copy(); painter.begin(&image2); painter.setRenderHint(QPainter::Antialiasing, false); painter.fillRect(0, 0, image2.width(), keepoutSpace, keepaway); painter.fillRect(0, image2.height() - keepoutSpace, image2.width(), keepoutSpace, keepaway); painter.fillRect(0, 0, keepoutSpace, image2.height(), keepaway); painter.fillRect(image2.width() - keepoutSpace, 0, keepoutSpace, image2.height(), keepaway); for (int y = 0; y < image.height(); y++) { for (int x = 0; x < image.width(); x++) { QRgb current = image.pixel(x, y); int gray = QGRAY(current); if (gray <= threshold) { continue; } painter.fillRect(x - keepoutSpace, y - keepoutSpace, keepoutSpace + keepoutSpace, keepoutSpace + keepoutSpace, keepaway); } } painter.end(); #ifndef QT_NO_DEBUG //image2.save("getBoardRects2.png"); #endif scanLines(image2, bWidth, bHeight, rects, threshold, 1); // combine parallel equal-sized rects int ix = 0; while (ix < rects.count()) { QRect r = rects.at(ix++); for (int j = ix; j < rects.count(); j++) { QRect s = rects.at(j); if (s.bottom() == r.bottom()) { // on same row; keep going continue; } if (s.top() > r.bottom() + 1) { // skipped row, can't join break; } if (s.left() == r.left() && s.right() == r.right()) { // join these r.setBottom(s.bottom()); rects.removeAt(j); ix--; rects.replace(ix, r); break; } } } return true; }
QImage * GroundPlaneGenerator::generateGroundPlaneAux(const QString & boardSvg, QSizeF boardImageSize, const QString & svg, QSizeF copperImageSize, QStringList & exceptions, QGraphicsItem * board, double res, double & bWidth, double & bHeight, double blurBy) { QByteArray boardByteArray; QString tempColor("#ffffff"); if (!SvgFileSplitter::changeColors(boardSvg, tempColor, exceptions, boardByteArray)) { return NULL; } /* QFile file0("testGroundFillBoard.svg"); file0.open(QIODevice::WriteOnly); QTextStream out0(&file0); out0 << boardByteArray; file0.close(); */ QByteArray copperByteArray; if (!SvgFileSplitter::changeStrokeWidth(svg, 50, false, copperByteArray)) { return NULL; } /* QFile file1("testGroundFillCopper.svg"); file1.open(QIODevice::WriteOnly); QTextStream out1(&file1); out1 << copperByteArray; file1.close(); */ double svgWidth = res * qMax(boardImageSize.width(), copperImageSize.width()) / FSvgRenderer::printerScale(); double svgHeight = res * qMax(boardImageSize.height(), copperImageSize.height()) / FSvgRenderer::printerScale(); QRectF br = board->sceneBoundingRect(); bWidth = res * br.width() / FSvgRenderer::printerScale(); bHeight = res * br.height() / FSvgRenderer::printerScale(); QImage * image = new QImage(qMax(svgWidth, bWidth), qMax(svgHeight, bHeight), QImage::Format_Mono); // image->setDotsPerMeterX(res * GraphicsUtils::InchesPerMeter); image->setDotsPerMeterY(res * GraphicsUtils::InchesPerMeter); image->fill(0x0); QSvgRenderer renderer(boardByteArray); QPainter painter; painter.begin(image); painter.setRenderHint(QPainter::Antialiasing, false); renderer.render(&painter, QRectF(0, 0, res * boardImageSize.width() / FSvgRenderer::printerScale(), res * boardImageSize.height() / FSvgRenderer::printerScale())); painter.end(); #ifndef QT_NO_DEBUG image->save("testGroundFillBoard.png"); #endif for (double m = 0; m < .004; m += (1.0 / res)) { QList<QPoint> points; collectBorderPoints(*image, points); #ifndef QT_NO_DEBUG // for debugging double pixelFactor = GraphicsUtils::StandardFritzingDPI / res; QPolygon polygon; foreach(QPoint p, points) { polygon.append(QPoint(p.x() * pixelFactor, p.y() * pixelFactor)); } QList<QPolygon> polygons; polygons.append(polygon); QPointF offset; QString pSvg = makePolySvg(polygons, res, bWidth, bHeight, pixelFactor, "#ffffff", "debug", false, NULL, QSizeF(0,0), 0, QPointF(0, 0)); #endif foreach (QPoint p, points) image->setPixel(p, 0); }
glm::vec3 Ray::trace(glm::vec3 rayOrig, glm::vec3 rayDir, float depth, int bounces) { // ---------------------------------------------- // Compare ray with every object in scene // Find the smallest distance to an object // ---------------------------------------------- float t0, t1, tNear = INF; Surface *s = nullptr; // Pointer to closest object for (auto &o : *scene->objects) { if (o->intersects(rayOrig, rayDir, t0, t1)) { if (t0 < tNear) { tNear = t0; s = o; } } } // ---------------------------------------------- // We have found an object // ---------------------------------------------- if (s != nullptr) { // If the closes object is a light, return light color if (s->isLight()) return s->color; // p is the point of intersection glm::vec3 directIllumination (0.0); glm::vec3 indirectIllumination (0.0); glm::vec3 p = rayOrig + rayDir * tNear; glm::vec3 normal = s->getNormal(p); glm::vec3 r = rayDir - 2 * glm::dot(rayDir, normal) * normal; // reflected direction // ---------------------------------------------- // Indirect illumination // If the object is reflective or refractive, calculate new ray(s) // ---------------------------------------------- if (s->isRefractive()) { // If the object is refractive, create refractive ray // Calculate new refractive ray // Need to do a flip if we are inside the object //glm::vec3 n = normal; //const float index = 1/1.5; //Sphere *temp = static_cast <Sphere*>(s); //if (glm::length(temp->getCenter() - p) < temp->getRadius()) n = -n; //glm::vec3 t = glm::normalize(glm::refract(rayDir, n, index)); Ray ray(scene); //indirectIllumination += ray.trace(p, t, depth, bounces); // Calculate reflective ray for both refracive and reflective materials // Trace reflective ray indirectIllumination += ray.trace(p, r, depth, bounces++); indirectIllumination /= (float)bounces; } // ---------------------------------------------- // Indirect illumination // Material is diffuse, do Monte Carlo stuff // ---------------------------------------------- else if(bounces < scene->maxBounces) { // Russian roulette float r1 = static_cast <float> (rand()) / static_cast <float> (RAND_MAX); float r2 = static_cast <float> (rand()) / static_cast <float> (RAND_MAX); float absorption = 0.5; // Ray is scattered if (static_cast <float> (rand()) / static_cast <float> (RAND_MAX) > absorption) { // New random direction over hemisphere float inclination = 2.0 * M_PI * r1; float azimuth = acos(2.0 * r2 - 1.0); float u = cos(azimuth); float x = sqrt(1 - u * u) * cos(inclination); float y = sqrt(1 - u * u) * sin(inclination); float z = u; // New direction. If it points the wrong way, change direction glm::vec3 newDir(x, y, z); if (glm::dot(normal, newDir) < 0) newDir = -newDir; // pdf - over hemisphere // cos - relationship between normal and the direction reflected light will come from // BRDF - Lambertian or Oren-Nayar float pdf = 1.0 / 2.0 * M_PI; float cos = glm::dot(normal, newDir); float BRDF = s->isOren() ? OrenNayarBRDF(newDir, glm::normalize(-scene->cameraDir), normal) : glm::dot(normal, newDir); Ray ray(scene); indirectIllumination = ray.trace(p, newDir, depth, bounces++) * cos * BRDF / pdf; indirectIllumination /= ((1 - absorption)); } } // ---------------------------------------------- // Direct illumination // Calculate shadow rays // ---------------------------------------------- int shadowRays = 4; for (int i = 0; i < scene->lights->size(); i++) { Sphere *l = scene->lights->at(i); // Pointer to current light glm::vec3 tempColor(0.0); // Total color per light float unobstructedRays = 0.0; for (int j = 0; j < shadowRays; j++) { bool shaded = false; glm::vec3 pDir = findRandomDirection(p, l); // Vector towards light float dist = glm::length(pDir); pDir = glm::normalize(pDir); // Shoot shadow ray(s) to random position on light (not random now though) for (auto &o : *scene->objects) if (o->intersects(p, pDir, t0, t1)) if (t0 < dist && !o->isLight()) shaded = true; if (!shaded) { unobstructedRays++; float lightIntensity = 2.2 * 1.0/255.0; float BRDF = s->isOren() ? OrenNayarBRDF(pDir, glm::normalize(-scene->cameraDir), normal) : glm::dot(normal, pDir); // TODO: N(light) must be calculated properly // radianceTransfer = dot(N(object), shadowRay) * dot(N(light), -shadowRay) float radianceTransfer = glm::dot(normal, pDir) * glm::dot(-pDir, -pDir); float pdfk = 2.0 * M_PI * l->getRadius() * l->getRadius(); // pdf over sphere (lights are halved spheres) float pdfyk = 0.5; // Chance to pick one of the light sources // Direct illumination = light * BRDF * radiance transfer / pdfk * pdfyk tempColor += l->color * lightIntensity * BRDF * radianceTransfer / (pdfk * pdfyk) * s->color; } } directIllumination += tempColor * (1.0f/(float)shadowRays); } // ---------------------------------------------- // Add direct and indirect light and return color // ---------------------------------------------- return (indirectIllumination * 2.0 + directIllumination / M_PI); } // Didn't find any object that intersects return glm::vec3(0.0, 0.0, 0.0); }
QImage * GroundPlaneGenerator::generateGroundPlaneAux(const QString & boardSvg, QSizeF boardImageSize, const QString & svg, QSizeF copperImageSize, QStringList & exceptions, QGraphicsItem * board, double res, double & bWidth, double & bHeight) { QByteArray boardByteArray; QString tempColor("#ffffff"); if (!SvgFileSplitter::changeColors(boardSvg, tempColor, exceptions, boardByteArray)) { return NULL; } //QFile file0("testGroundFillBoard.svg"); //file0.open(QIODevice::WriteOnly); //QTextStream out0(&file0); //out0 << boardByteArray; //file0.close(); QByteArray copperByteArray; if (!SvgFileSplitter::changeStrokeWidth(svg, m_strokeWidthIncrement, false, copperByteArray)) { return NULL; } //QFile file1("testGroundFillCopper.svg"); //file1.open(QIODevice::WriteOnly); //QTextStream out1(&file1); //out1 << copperByteArray; //file1.close(); double svgWidth = res * qMax(boardImageSize.width(), copperImageSize.width()) / FSvgRenderer::printerScale(); double svgHeight = res * qMax(boardImageSize.height(), copperImageSize.height()) / FSvgRenderer::printerScale(); QRectF br = board->sceneBoundingRect(); bWidth = res * br.width() / FSvgRenderer::printerScale(); bHeight = res * br.height() / FSvgRenderer::printerScale(); QImage * image = new QImage(qMax(svgWidth, bWidth), qMax(svgHeight, bHeight), QImage::Format_Mono); // image->setDotsPerMeterX(res * GraphicsUtils::InchesPerMeter); image->setDotsPerMeterY(res * GraphicsUtils::InchesPerMeter); image->fill(0x0); QSvgRenderer renderer(boardByteArray); QPainter painter; painter.begin(image); painter.setRenderHint(QPainter::Antialiasing, false); QRectF boardBounds(0, 0, res * boardImageSize.width() / FSvgRenderer::printerScale(), res * boardImageSize.height() / FSvgRenderer::printerScale()); DebugDialog::debug("boardbounds", boardBounds); renderer.render(&painter, boardBounds); painter.end(); #ifndef QT_NO_DEBUG image->save("testGroundFillBoard.png"); #endif for (double m = 0; m < BORDERINCHES; m += (1.0 / res)) { // 1 mm QList<QPoint> points; collectBorderPoints(*image, points); #ifndef QT_NO_DEBUG /* // for debugging double pixelFactor = GraphicsUtils::StandardFritzingDPI / res; QPolygon polygon; foreach(QPoint p, points) { polygon.append(QPoint(p.x() * pixelFactor, p.y() * pixelFactor)); } QList<QPolygon> polygons; polygons.append(polygon); QPointF offset; this QString pSvg = makePolySvg(polygons, res, bWidth, bHeight, pixelFactor, "#ffffff", false, NULL, QSizeF(0,0), 0, QPointF(0, 0)); */ #endif foreach (QPoint p, points) image->setPixel(p, 0); } #ifndef QT_NO_DEBUG image->save("testGroundFillBoardBorder.png"); #endif // "blur" the image a little QSvgRenderer renderer2(copperByteArray); painter.begin(image); painter.setRenderHint(QPainter::Antialiasing, false); QRectF bounds(0, 0, res * copperImageSize.width() / FSvgRenderer::printerScale(), res * copperImageSize.height() / FSvgRenderer::printerScale()); DebugDialog::debug("copperbounds", bounds); renderer2.render(&painter, bounds); if (m_blurBy != 0) { bounds.moveTo(m_blurBy, 0); renderer2.render(&painter, bounds); bounds.moveTo(-m_blurBy, 0); renderer2.render(&painter, bounds); bounds.moveTo(0, m_blurBy); renderer2.render(&painter, bounds); bounds.moveTo(0, -m_blurBy); renderer2.render(&painter, bounds); bounds.moveTo(m_blurBy, m_blurBy); renderer2.render(&painter, bounds); bounds.moveTo(-m_blurBy, -m_blurBy); renderer2.render(&painter, bounds); bounds.moveTo(-m_blurBy, m_blurBy); renderer2.render(&painter, bounds); bounds.moveTo(m_blurBy, -m_blurBy); renderer2.render(&painter, bounds); } painter.end(); #ifndef QT_NO_DEBUG image->save("testGroundFillCopper.png"); #endif emit postImageSignal(this, image, board); return image; }