Ejemplo n.º 1
0
	/**
	* @param newTriangleIndexes [out] Indexes of new triangles added to convex hull
	* @param removedTriangleIndexes [out] Indexes of removed triangles from convex hull
	* @return Returns index of point added. If point doesn't make part of convex, result is zero.
	*/
	template<class T> unsigned int ConvexHull3D<T>::addNewPoint(const Point3<T> &newPoint,
			std::vector<unsigned int> &newTriangleIndexes, std::vector<unsigned int> &removedTriangleIndexes)
	{
		std::map<long long, std::pair<unsigned int, unsigned int>> edges;
		constexpr int HALF_SIZE_INDEX = (sizeof(unsigned int) * 8) / 2;

		//deletes all triangles visible by the new point
		for(typename std::map<unsigned int, IndexedTriangle3D<T>>::iterator itTriangle=indexedTriangles.begin(); itTriangle!=indexedTriangles.end();)
		{
			const IndexedTriangle3D<T> indexedTriangle = itTriangle->second;
			const Vector3<T> &triangleNormal = indexedTriangle.computeNormal(points);

			const Point3<T> &point0 = points.find(indexedTriangle.getIndexes()[0])->second;
			const Vector3<T> &triangleToPoint = point0.vector(newPoint);

			if(triangleNormal.dotProduct(triangleToPoint) > 0.0)
			{
				for(int i=0; i<3; i++)
				{ //each edge
					int index1 = indexedTriangle.getIndexes()[i];
					int index2 = indexedTriangle.getIndexes()[(i+1)%3];

					long long idEdge = (std::min(index1, index2) << HALF_SIZE_INDEX) | std::max(index1, index2);
					std::map<long long, std::pair<unsigned int, unsigned int>>::iterator itEdge = edges.find(idEdge);
					if(itEdge==edges.end())
					{
						edges[idEdge] = std::make_pair(index1, index2);
					}else
					{
						edges.erase(itEdge);
					}
				}

				removedTriangleIndexes.push_back(itTriangle->first);
				removeTriangle(itTriangle++);
			}else
			{
				++itTriangle;
			}
		}

		//adds the new triangles
		if(edges.size()>0)
		{
			newTriangleIndexes.reserve(edges.size());
			unsigned int pointIndex = nextPointIndex++;
			points[pointIndex] = newPoint;

			for(std::map<long long, std::pair<unsigned int, unsigned int>>::iterator it = edges.begin(); it!=edges.end(); ++it)
			{
				unsigned int triangleIndex = addTriangle(IndexedTriangle3D<T>(it->second.first, it->second.second, pointIndex));
				newTriangleIndexes.push_back(triangleIndex);
			}

			return pointIndex;
		}

		return 0;
	}
Ejemplo n.º 2
0
QWidget *WalkmeshManager::buildWalkmeshPage()
{
	QWidget *ret = new QWidget(this);

	ListWidget *listWidget = new ListWidget(ret);
	listWidget->addAction(ListWidget::Add, tr("Ajouter triangle"), this, SLOT(addTriangle()));
	listWidget->addAction(ListWidget::Rem, tr("Supprimer triangle"), this, SLOT(removeTriangle()));

	idToolbar = listWidget->toolBar();
	idList = listWidget->listWidget();

	idVertices[0] = new VertexWidget(ret);
	idVertices[1] = new VertexWidget(ret);
	idVertices[2] = new VertexWidget(ret);

	idAccess[0] = new QSpinBox(ret);
	idAccess[1] = new QSpinBox(ret);
	idAccess[2] = new QSpinBox(ret);

	idAccess[0]->setRange(-32768, 32767);
	idAccess[1]->setRange(-32768, 32767);
	idAccess[2]->setRange(-32768, 32767);

	QHBoxLayout *accessLayout0 = new QHBoxLayout;
	accessLayout0->addWidget(new QLabel(tr("Triangle accessible via la ligne 1-2 :")));
	accessLayout0->addWidget(idAccess[0]);

	QHBoxLayout *accessLayout1 = new QHBoxLayout;
	accessLayout1->addWidget(new QLabel(tr("Triangle accessible via la ligne 2-3 :")));
	accessLayout1->addWidget(idAccess[1]);

	QHBoxLayout *accessLayout2 = new QHBoxLayout;
	accessLayout2->addWidget(new QLabel(tr("Triangle accessible via la ligne 3-1 :")));
	accessLayout2->addWidget(idAccess[2]);

	QGridLayout *layout = new QGridLayout(ret);
	layout->addWidget(listWidget, 0, 0, 7, 1, Qt::AlignLeft);
	layout->addWidget(new QLabel(tr("Point 1 :")), 0, 1);
	layout->addWidget(idVertices[0], 0, 2);
	layout->addWidget(new QLabel(tr("Point 2 :")), 1, 1);
	layout->addWidget(idVertices[1], 1, 2);
	layout->addWidget(new QLabel(tr("Point 3 :")), 2, 1);
	layout->addWidget(idVertices[2], 2, 2);
	layout->addLayout(accessLayout0, 3, 1, 1, 2);
	layout->addLayout(accessLayout1, 4, 1, 1, 2);
	layout->addLayout(accessLayout2, 5, 1, 1, 2);
	layout->setRowStretch(6, 1);

	connect(idList, SIGNAL(currentRowChanged(int)), SLOT(setCurrentId(int)));
	connect(idVertices[0], SIGNAL(valuesChanged(Vertex_s)), SLOT(editIdTriangle(Vertex_s)));
	connect(idVertices[1], SIGNAL(valuesChanged(Vertex_s)), SLOT(editIdTriangle(Vertex_s)));
	connect(idVertices[2], SIGNAL(valuesChanged(Vertex_s)), SLOT(editIdTriangle(Vertex_s)));
	connect(idAccess[0], SIGNAL(valueChanged(int)), SLOT(editIdAccess(int)));
	connect(idAccess[1], SIGNAL(valueChanged(int)), SLOT(editIdAccess(int)));
	connect(idAccess[2], SIGNAL(valueChanged(int)), SLOT(editIdAccess(int)));

	return ret;
}
Ejemplo n.º 3
0
void cMesh::clean()
{
    int nbFaces = getFacesNumber();
    for(int i=0 ; i < nbFaces; i++)
    {
        cTriangle * Triangle = getTriangle(i);

        if (Triangle->getEdgesNumber() < 3 && !Triangle->isTextured())
        {
            //cout <<"remove triangle " << Triangle->getIdx() << " with " << Triangle->getEdgesNumber() << " edges" << endl;

            //cout <<"sommets = " << Triangle->getVertex(0) << " " << Triangle->getVertex(1) << " " << Triangle->getVertex(2) << endl;

            removeTriangle(*Triangle);
            nbFaces--;
            i--;
        }
        /*else if (!Triangle->isTextured())
            cout << "triangle " << i << " nb edges = " << Triangle->getEdgesNumber() << " textured= " << Triangle->isTextured() << endl;*/
    }

    //suppression des points n'appartenant à aucun triangle
    for(int aK=0; aK < getVertexNumber();++aK)
    {
        bool found = false;
        for(int i=0 ; i < nbFaces; i++)
        {
            int vertex1, vertex2, vertex3;
            getTriangle(i)->getVertexesIndexes(vertex1, vertex2, vertex3);

            if ((aK==vertex1) || (aK==vertex2) || (aK==vertex3))
            {
                found = true;
                break;
            }
        }

        if (!found) //remove this point
        {
            mVertexes.erase(std::remove(mVertexes.begin(), mVertexes.end(), mVertexes[aK]), mVertexes.end());

            for(int i=0 ; i < nbFaces; i++)
            {
                cTriangle * tri= getTriangle(i);
                int vertex1, vertex2, vertex3;
                tri->getVertexesIndexes(vertex1, vertex2, vertex3);

                if (vertex1>aK) tri->setVertexIndex(0, vertex1-1);
                if (vertex2>aK) tri->setVertexIndex(1, vertex2-1);
                if (vertex3>aK) tri->setVertexIndex(2, vertex3-1);

            }
        }
    }
}
Ejemplo n.º 4
0
	void Mesh::assertManifold()
	{
		std::map<Vertex*, std::vector<Triangle *> > triRing;

		// for each triangle
		for( std::vector<Triangle *>::iterator tit = triangles.begin(); tit != triangles.end(); ++tit )
		{
			Triangle *t = *tit;

			for( size_t i=0; i<3; ++i )
				triRing[ t->v[i] ].push_back( t );
		}

		for( std::map<Vertex*, std::vector<Triangle *> >::iterator it = triRing.begin(); it != triRing.end(); ++it )
		{
			Vertex *v = it->first;

			if( it->second.size() < 3 )
			{
				printf( "degenerated vertex detected (referenced by less then 3 triangles) -> removed\n" );

				// remove all triangles referencing v
				for( std::vector<Triangle *>::iterator tit = it->second.begin(); tit != it->second.end(); ++tit )
				{
					Triangle *t = *tit;

					// remove triangle from triangleRings from all reference vertices
					for( size_t i =0;i<3; ++i )
						if( t->v[i] != v )
						{
							triRing[t->v[i]].erase( std::find( triRing[t->v[i]].begin(), triRing[t->v[i]].end(), t ) );
							// TODO: check if new degenerate vertices are created
						}

					// remove the triangle
					removeTriangle( t );
				}

				// remove v itsself
				removeVertex( v );
			}
		}


	}