void TriangleSetTopologyContainer::clear()
{
    clearTrianglesAroundVertex();
    clearTrianglesAroundEdge();
    clearEdgesInTriangle();
    clearTriangles();
    clearBorderElementLists();
    EdgeSetTopologyContainer::clear();
}
Example #2
0
  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
  }
Example #3
0
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();
}