void TriangleSetTopologyContainer::clear() { clearTrianglesAroundVertex(); clearTrianglesAroundEdge(); clearEdgesInTriangle(); clearTriangles(); clearBorderElementLists(); EdgeSetTopologyContainer::clear(); }
void PolyMesh::triangulate () { clearTriangles(); //int polycount = 0; for (PolyMesh::FaceIter f(this); !f.end(); ++f) { //polycount++; //if (polycount == 10163) //int oooo = 1; PolyMesh::FaceVertIter fv; UintSize numavg[3] = {0,0,0}; UintSize avgi = 0; Vector3 avg[3]; //Split vertices into three groups for (fv.begin(*f); !fv.end(); ++fv, ++avgi) numavg[ avgi % 3 ] += 1; //Exit early if triangle if (avgi == 3) { addTriangle( *f, f->firstHedge()->prevHedge(), f->firstHedge(), f->firstHedge()->nextHedge()); continue; } //Average vertices in each group fv.begin(*f); for (int g=0; g<3; ++g) for (avgi=0; avgi<numavg[g]; ++avgi, ++fv) avg[g] += fv->point; avg[0] /= (Float) numavg[0]; avg[1] /= (Float) numavg[1]; avg[2] /= (Float) numavg[2]; //Define triangulation space Vector3 s1 = (avg[1] - avg[0]).normalize(); Vector3 s2 = (avg[2] - avg[0]).normalize(); Vector3 trigN = Vector::Cross( s2, s1 ).normalize(); Vector3 trigY = Vector::Cross( trigN, s1 ); Vector3 trigX = s1; //Construct world-to-trig matrix Matrix4x4 trigM; trigM.setColumn( 0, trigX ); trigM.setColumn( 1, trigY ); trigM.setColumn( 2, trigN ); trigM.setColumn( 3, fv->point ); trigM = trigM.affineInverse(); //Transform polygon into trig space and find bottom-left point LinkedList< TrigNode > trigNodes; bool minFirst = true; TrigIter minI; for (fv.begin(*f); !fv.end(); ++fv) { TrigNode node; node.vertex = *fv; node.hedge = fv.hedgeToVertex(); node.point = ( trigM * fv->point ).xy(); TrigIter newI = trigNodes.pushBack( node ); if (minFirst) minI = newI; else if (node.point.x < minI->point.x) minI = newI; else if (node.point.x == minI->point.x && node.point.y < minI->point.y) minI = newI; minFirst = false; } //Find orientation for all corners Vector2 prevV, nextV; TrigCyclIter prev, cur, next; bool convex = false, convexInit = false; prev.begin( trigNodes, minI ); --prev; cur.begin( trigNodes, minI ); next.begin( trigNodes, minI ); ++next; for ( ; !cur.end(); ++cur, ++prev, ++next) { findNodeOrientation( *prev, *cur, *next, convex, convexInit ); if (!convexInit) { convex = cur->orientation; convexInit = true; } } //Rest corner iterators prev.begin( trigNodes ); --prev; cur.begin( trigNodes ); next.begin( trigNodes ); ++next; //Cut ears until triangle or no ears found while (trigNodes.size() > 3 && !cur.end()) { //Find next convex node if (cur->orientation == convex) { //Check if a concave node is inside bool isEar = true; for (TrigCyclIter it( cur ); !it.end(); ++it) { if (it == prev || it == cur || it == next) continue; if (it->orientation == convex) continue; if (Vector::InsideTriangle( it->point, prev->point, cur->point, next->point)) { isEar = false; break; } } //Cut an ear if (isEar) { addTriangle( *f, prev->hedge, cur->hedge, next->hedge ); trigNodes.removeAt( cur ); findNodeOrientation( prev, convex, convexInit ); findNodeOrientation( next, convex, convexInit ); cur.begin( next ); ++next; continue; } } //Next corner ++prev; ++cur; ++next; } //Cut the remaining corners while (next != prev) { addTriangle( *f, prev->hedge, cur->hedge, next->hedge ); ++cur; ++next; } }//Walk faces }
void RayDisplayScene::lightenSender(int senderId, const int &angle) { clearRayNumbers(); QVector<QLineF> &senderCollidedRays = clearCollidedRays(senderId); clearTriangles(); QVector<Ray> senderRays; senderRays.reserve(10); for (int i = 1; i < mSidedReceivers.size(); i++) { const int sideIdx = (mSenders.at(senderId).side + i) % mSidedReceivers.size(); for (int j = 0; j < mSidedReceivers.at(sideIdx).size(); j++) { QLineF line(mSenders.at(senderId).r->pos(), mSidedReceivers.at(sideIdx).at(j)->pos()); int lineAngle = int(line.angle()) - mSenders.at(senderId).rotation; if ((lineAngle > -angle / 2 && lineAngle < angle / 2) || (lineAngle - 360 > -angle / 2 && lineAngle - 360 < angle / 2)) { QGraphicsTextItem *rayNumber; rayNumber = addText(QString::number(senderRays.size())); rayNumber->setPos(line.p2()); rayNumber->setZValue(3); mRayNumbers << rayNumber; senderRays << Ray{line, true, (j == 0) || (j == mSidedReceivers.at(sideIdx).size() - 1) /* corner ray */}; } } } for (int i = 0; i < senderRays.size(); i++) { QGraphicsLineItem *r = nullptr; if (!mCollisionEnabled || mCircles.size() <= 1) { r = addLine(senderRays.at(i).line, QPen(QBrush(Qt::blue), 1)); } else { /*const int size = mObstacle.size(); for (int j = 0; j < size; j++) { QLineF obsLine(mObstacle.at(j), mObstacle.at((j + 1) % size)); if (senderRays.at(i).line.intersect(obsLine, nullptr) == QLineF::BoundedIntersection) { senderRays[i].visible = false; break; } }*/ const int size = mCircles.size(); for (int j = 0; j < size; j++) { if (pointToLineDistSquared(mCircles.at(j).center, senderRays.at(i).line) <= mCircles.at(j).radius * mCircles.at(j).radius) { senderRays[i].visible = false; break; } } if (senderRays.at(i).visible) { r = addLine(senderRays.at(i).line, QPen(QBrush(Qt::blue), 1)); } } if (r != nullptr) { mRays.append(r); } } // add border rays of another colour if (senderRays.size() > 0) { QGraphicsLineItem *r = nullptr; // first { r = addLine(senderRays.at(0).line, QPen(QBrush(Qt::yellow), 1)); mRays.append(r); } // last if (senderRays.size() > 1/* && !senderRays.at(senderRays.size() - 1).visible*/) { //senderCollidedRays << senderRays.at(senderRays.size() - 1).line; r = addLine(senderRays.at(senderRays.size() - 1).line, QPen(QBrush(Qt::yellow), 1)); mRays.append(r); } // on every state change for (int i = 1; i < senderRays.size() - 1; i++) { if (!senderRays.at(i).visible && (senderRays.at(i - 1).visible || senderRays.at(i + 1).visible)) { senderCollidedRays << senderRays.at(i).line; r = addLine(senderRays.at(i).line, QPen(QBrush(Qt::red), 1)); mCollidedRaysGraphics[senderId] << r; } } } // ****************************** // -----8<------8<-------8<------ //cv::Mat cvImage = cvtrack1(senderId, senderRays); //cv::imshow(QString(QString("plepleple ")/* + QString::number(senderId)*/).toStdString(), cvImage); /*for (int i = 0; i < mCvPolygons.size(); i++) { for (int j = 0; j < mCvPolygons.at(i).size(); j++) { cv::fillConvexPoly(cvImage, cvPoints.constData(), cvPoints.size(), cv::Scalar(127)); } }*/ //cvTrack2(cvImage); updateCollisions(); }