Example #1
0
File: main.cpp Project: Sebu/CG2
// naja der name sagt es schon tasten abfragen
// "normale tasten"
GLvoid keyboard ( unsigned char key, int x, int y ) 
{
  switch ( key ) {
    case 27:        
      exit(0);
      break;       
	case 'a':  
      apoint.z -= 6.2f; 
      break;
    case 'y':  
      apoint.z += 6.2f; 
      break;
	 case 'o':  
      optimize(*model2, *model);
      cout << "qual: " << model2->erep/model2->crep << endl;
      break;
    case 's':  
      swapEdge(model2->edges[number], *model2, *model);
      break;
    case 'c':  
      collapseEdge(model2->edges[number], *model2, *model );
      cout << number << endl;
      break;
    case 'd':  
      splitEdge(model2->edges[number], *model2, *model );
      break;      
    case 'w':  
      roty += 5.5f; 
      break;
      
    default: 
		break;

  }
}
Example #2
0
File: HMesh.cpp Project: 3dcv/3dcv
void HMesh::removeHeckBertShit(size_t amount)
{
	map<double, pair<int, Edge*> > shortest_edges;
	for(int i = 0; i < vertices_.size(); i++)
	{
		for(Edge* edgy : vertices_[i]->in_edges)
		{
			Vertex* v1 = edgy->start;
			Vertex* v2 = edgy->end;
			Vertex v_neu = (*v1 + *v2) * 0.5;
			Vertex v_b1 = v_neu - *v1;
			Vector3f ev_b1 = Vector3f(v_b1.x, v_b1.y, v_b1.z);
		    double heck_meck = 0;
		    for(int i = 0;i < v1->out_edges.size();i++)
		    {
				Face* plane = v1->out_edges[i]->face;
				if(plane != NULL)
				{
					Vertex s1 = (*plane->startEdge_->end - *plane->startEdge_->start);
					Vertex s2 = (*plane->startEdge_->next->end - *plane->startEdge_->start);
					Vector3f stv1 = Vector3f(s1.x, s1.y, s1.z);
					Vector3f stv2 = Vector3f(s2.x, s2.y, s2.z);
					Vector3f normal = stv1.cross(stv2);
					heck_meck += pow((normal.dot(ev_b1)), 2);
				} 
			}
			Vertex v_b2 = v_neu - *v2;
			Vector3f ev_b2 = Vector3f(v_b2.x, v_b2.y, v_b2.z);
		    for(int i = 0;i < v2->out_edges.size();i++)
		    {
				Face* plane = v2->out_edges[i]->face;
				if(plane != NULL)
				{
					Vertex s1 = (*plane->startEdge_->end - *plane->startEdge_->start);
					Vertex s2 = (*plane->startEdge_->next->end - *plane->startEdge_->start);
					Vector3f stv1 = Vector3f(s1.x, s1.y, s1.z);
					Vector3f stv2 = Vector3f(s2.x, s2.y, s2.z);
					Vector3f normal = stv1.cross(stv2);
					heck_meck += pow((normal.dot(ev_b2)), 2);
				} 
			}
			shortest_edges.insert(pair<double, pair<int, Edge*> >(heck_meck, pair<int, Edge*>(i,edgy)));
		}
	}
	collapseEdge(shortest_edges.begin()->second.second);
	int i = shortest_edges.begin()->second.first;
	auto elem = find(vertices_[i]->in_edges.begin(), vertices_[i]->in_edges.end(), shortest_edges.begin()->second.second) ;
	if(elem != vertices_[i]->in_edges.end())
	{
		vertices_[i]->in_edges.erase(elem);
	}
	elem = find(vertices_[i]->out_edges.begin(), vertices_[i]->out_edges.end(), shortest_edges.begin()->second.second) ;
	if(elem != vertices_[i]->out_edges.end())
	{  
		vertices_[i]->out_edges.erase(elem);
	}
}
Example #3
0
File: HMesh.cpp Project: 3dcv/3dcv
void HMesh::removeShortestShit(size_t amount)
{
	map<double, Edge*> shortest_edges;
	
	for(int i = 0; i < vertices_.size(); i++)
	{
		for(Edge* edgy : vertices_[i]->out_edges)
		{
			if(edgy != NULL)
				shortest_edges.insert(pair<double, Edge*>((*edgy->end - *edgy->start).length(), edgy));
		}
	}
	collapseEdge(shortest_edges.begin()->second);
	for(int i = 0; i < vertices_.size(); i++)
	{
		auto elem = find(vertices_[i]->out_edges.begin(), vertices_[i]->out_edges.end(), shortest_edges.begin()->second) ;
		if(elem != vertices_[i]->out_edges.end())
		{  
			vertices_[i]->out_edges.erase(elem);
		}
	}
}
Example #4
0
File: HMesh.cpp Project: 3dcv/3dcv
void HMesh::removeMelaxShit(size_t amount)
{
	map<double, pair<int, Edge*> > shortest_edges;
	for(int i = 0; i < vertices_.size(); i++)
	{
		for(Edge* edgy : vertices_[i]->in_edges)
		{
			Vertex* u = edgy->start;
			Vertex* v = edgy->end;
			double uv_length = (*v - *u).length();
		    vector<Vector3f> uv_planes;
		    vector<Vector3f> u_planes;
		    for(int i = 0;i < u->out_edges.size();i++)
		    {
				Face* plane = u->out_edges[i]->face;
				if(plane != NULL)
				{
					Vertex s1 = (*plane->startEdge_->end - *plane->startEdge_->start);
					Vertex s2 = (*plane->startEdge_->next->end - *plane->startEdge_->start);
					Vector3f stv1 = Vector3f(s1.x, s1.y, s1.z);
					Vector3f stv2 = Vector3f(s2.x, s2.y, s2.z);
					Vector3f normal = stv1.cross(stv2);
					uv_planes.push_back(normal);
					u_planes.push_back(normal);
				}
			}
		    for(int i = 0;i < v->out_edges.size();i++)
		    {
			    Face* plane = v->out_edges[i]->face;
			    if(plane != NULL)
			    {
					Vertex s1 = (*plane->startEdge_->end - *plane->startEdge_->start);
					Vertex s2 = (*plane->startEdge_->next->end - *plane->startEdge_->start);
					Vector3f stv1 = Vector3f(s1.x, s1.y, s1.z);
					Vector3f stv2 = Vector3f(s2.x, s2.y, s2.z);
					Vector3f normal = stv1.cross(stv2);
					uv_planes.push_back(normal);
				}
			}
			double max_val = 0;
			for(int j = 0; j < u_planes.size(); j++)
			{
				Vector3f normal_a = u_planes[j];
				double min_val = 1000000;
				for(int k = 0; k < uv_planes.size(); k++)
				{
					double step = (1 - (normal_a.dot(uv_planes[k])));
					if(step < min_val)
						min_val = step;
				}
				if(min_val > max_val)
					max_val = min_val;
			}
			double mex_meck = uv_length * max_val;
			shortest_edges.insert(pair<double, pair<int, Edge*> >(mex_meck, pair<int, Edge*>(i,edgy)));
		}
	}
	collapseEdge(shortest_edges.begin()->second.second);
	int i = shortest_edges.begin()->second.first;
	auto elem = find(vertices_[i]->in_edges.begin(), vertices_[i]->in_edges.end(), shortest_edges.begin()->second.second) ;
	if(elem != vertices_[i]->in_edges.end())
	{
		vertices_[i]->in_edges.erase(elem);
	}
	elem = find(vertices_[i]->out_edges.begin(), vertices_[i]->out_edges.end(), shortest_edges.begin()->second.second) ;
	if(elem != vertices_[i]->out_edges.end())
	{  
		vertices_[i]->out_edges.erase(elem);
	}
}
Example #5
0
bool DecimationMesh::decimate()
{
  EdgeCollapse * collapse = static_cast<EdgeCollapse *>(mHeap.pop());
  if (collapse == NULL) return false;

  // Stop the collapse when we only have two triangles left
  // (the smallest entity representable)
  if (mFaces.size() - mNumCollapsedFaces == 2) return false;

  unsigned int e1 = collapse->halfEdge;
  unsigned int e2 = mEdges[e1].pair;

  unsigned int v1 = mEdges[e1].vert;
  unsigned int v2 = mEdges[e2].vert;
  unsigned int v3 = mEdges[mEdges[e1].prev].vert;
  unsigned int v4 = mEdges[mEdges[e2].prev].vert;

  unsigned int f1 = mEdges[e1].face;
  unsigned int f2 = mEdges[e2].face;

  std::cout << "Collapsing faces " << f1 << " and " << f2 << std::endl;
  std::cout << "Collapsing edges " << e1 << ", " << mEdges[e1].next << ", " << mEdges[e1].prev;
  std::cout << ", " << e2 << ", " << mEdges[e2].next << " and " << mEdges[e2].prev << std::endl;
  std::cout << "Collapsing vertex " << v1 << std::endl;


  // Verify that the collapse is valid, exit if not so
  if (!isValidCollapse(collapse)) {
    delete collapse;
    mHalfEdge2EdgeCollapse[e1] = NULL;
    mHalfEdge2EdgeCollapse[e2] = NULL;
    std::cout << "failed..." << std::endl;
    return false;
  }


  // We want to remove v1, so we need to connect all of v1's half-edges to v2
  unsigned int edge = mVerts[v1].edge;
  do {
    mEdges[edge].vert = v2;
    edge = mEdges[mEdges[edge].pair].next;
  } while (edge != mVerts[v1].edge);

  // Make sure v2 points to a valid edge
  while (mEdges[mVerts[v2].edge].face == f1 || mEdges[mVerts[v2].edge].face == f2)
    mVerts[v2].edge = mEdges[mEdges[ mVerts[v2].edge ].pair].next;

  // Make sure v3 points to a valid edge
  while (mEdges[mVerts[v3].edge].face == f1)
    mVerts[v3].edge = mEdges[mEdges[ mVerts[v3].edge ].pair].next;

  // Make sure v4 points to a valid edge
  while (mEdges[mVerts[v4].edge].face == f2)
    mVerts[v4].edge = mEdges[mEdges[ mVerts[v4].edge ].pair].next;

  // Redirect pair pointers
  mEdges[mEdges[mEdges[e1].next].pair].pair = mEdges[mEdges[e1].prev].pair;
  mEdges[mEdges[mEdges[e1].prev].pair].pair = mEdges[mEdges[e1].next].pair;

  mEdges[mEdges[mEdges[e2].next].pair].pair = mEdges[mEdges[e2].prev].pair;
  mEdges[mEdges[mEdges[e2].prev].pair].pair = mEdges[mEdges[e2].next].pair;

  // Move v2 to its new position
  mVerts[v2].pos = collapse->position;

  // One edge collapse further removes 2 additional collapse
  // candidates from the heap
  if (mHalfEdge2EdgeCollapse[mEdges[e1].prev] != NULL)
    delete mHeap.remove(mHalfEdge2EdgeCollapse[mEdges[e1].prev]);
  mHalfEdge2EdgeCollapse[mEdges[mEdges[e1].prev].pair] = mHalfEdge2EdgeCollapse[mEdges[e1].next];

  if (mHalfEdge2EdgeCollapse[mEdges[e2].next] != NULL)
    delete mHeap.remove(mHalfEdge2EdgeCollapse[mEdges[e2].next]);
  mHalfEdge2EdgeCollapse[mEdges[mEdges[e2].next].pair] = mHalfEdge2EdgeCollapse[mEdges[e2].prev];

  // Make sure the edge collapses point to valid edges
  if (mHalfEdge2EdgeCollapse[mEdges[e1].next] != NULL)
    mHalfEdge2EdgeCollapse[mEdges[e1].next]->halfEdge = mEdges[mEdges[e1].prev].pair;
  if (mHalfEdge2EdgeCollapse[mEdges[e2].prev] != NULL)
    mHalfEdge2EdgeCollapse[mEdges[e2].prev]->halfEdge = mEdges[mEdges[e2].next].pair;

  delete collapse;

  // Collapse the neighborhood
  collapseFace(f1);
  collapseFace(f2);

  collapseEdge(e1);
  collapseEdge(mEdges[e1].next);
  collapseEdge(mEdges[e1].prev);

  collapseEdge(e2);
  collapseEdge(mEdges[e2].next);
  collapseEdge(mEdges[e2].prev);

  collapseVertex(v1);

  // Finally, loop through neighborhood of v2 and update all edge collapses
  // (and remove possible invalid cases)
  updateVertexProperties(v2);
  edge = mVerts[v2].edge;
  do {
    unsigned int face = mEdges[edge].face;
    unsigned int vert = mEdges[mEdges[edge].pair].vert;
    if (!isFaceCollapsed(face))    updateFaceProperties(face);
    if (!isVertexCollapsed(vert))  updateVertexProperties(vert);

    collapse = mHalfEdge2EdgeCollapse[edge];
    if (collapse != NULL) {
      if (!isValidCollapse(collapse)) {
        delete mHeap.remove(collapse);
        mHalfEdge2EdgeCollapse[edge] = NULL;
        mHalfEdge2EdgeCollapse[mEdges[edge].pair] = NULL;
        std::cout << "Removed one invalid edge collapse" << std::endl;
      }
      else {
        computeCollapse(collapse);
        mHeap.update(collapse);
      }
    }

    edge = mEdges[mEdges[edge].pair].next;
  } while (edge != mVerts[v2].edge);


  //mHeap.print(std::cout);

  return true;
}
uint32_t ApexQuadricSimplifier::simplify(uint32_t subdivision, int32_t maxSteps, float maxError, IProgressListener* progressListener)
{
	float maxLength = 0.0f;

	uint32_t nbCollapsed = 0;

	if (subdivision > 0)
	{
		maxLength = (mBounds.minimum - mBounds.maximum).magnitude() / subdivision;
	}

	uint32_t progressCounter = 0;
	uint32_t maximum = maxSteps >= 0 ? maxSteps : mHeap.size();

	HierarchicalProgressListener progress(100, progressListener);
	progress.setSubtaskWork(90, "Isomesh simplicifaction");
#if TESTING
	testHeap();
#endif

	while (maxSteps == -1 || (maxSteps-- > 0))
	{

		if ((++progressCounter & 0xff) == 0)
		{
			const int32_t percent = (int32_t)(100 * progressCounter / maximum);
			progress.setProgress(percent);
		}

		bool edgeFound = false;
		QuadricEdge* e = NULL;
		while (mHeap.size() - mNumDeletedHeapElements > 1)
		{
			e = mHeap[1];

			if (maxError >= 0 && e->cost > maxError)
			{
				// get me out of here
				edgeFound = false;
				break;
			}

			if (legalCollapse(*e, maxLength))
			{
				heapRemove(1, false);
#if TESTING
				testHeap();
#endif
				edgeFound = true;
				break;
			}
			uint32_t vNr0 = e->vertexNr[0];
			uint32_t vNr1 = e->vertexNr[1];
			QuadricVertex* qv0 = mVertices[vNr0];
			QuadricVertex* qv1 = mVertices[vNr1];
			heapRemove(1, qv0->bDeleted == 0 && qv1->bDeleted == 0);
#if TESTING
			testHeap();
#endif
		}

		if (!edgeFound)
		{
			break;
		}

		collapseEdge(*e);
		nbCollapsed++;
	}

	progress.completeSubtask();
	progress.setSubtaskWork(10, "Heap rebuilding");

	progressCounter = mNumDeletedHeapElements;
	while (mNumDeletedHeapElements > 0)
	{
		if ((mNumDeletedHeapElements & 0x7f) == 0)
		{
			const int32_t percent =  (int32_t)(100 * (progressCounter - mNumDeletedHeapElements) / progressCounter);
			progress.setProgress(percent);
		}
#if TESTING
		testHeap();
#endif
		mNumDeletedHeapElements--;
		heapUpdate(mHeap.size() - 1 - mNumDeletedHeapElements);
	}

	progress.completeSubtask();
#if TESTING
	testHeap();
#endif
	return nbCollapsed;
}
Example #7
0
bool NTriangulation::simplifyToLocalMinimum(bool perform) {
    BoundaryComponentIterator bit;
    unsigned long nTriangles;
    unsigned long iTriangle;
    // unsigned long nEdges;
    // unsigned long iEdge;
    // std::deque<NEdgeEmbedding>::const_iterator embit, embbeginit, embendit;

    bool changed = false;   // Has anything changed ever (for return value)?
    bool changedNow = true; // Did we just change something (for loop control)?

    { // Begin scope for change event span.
        ChangeEventSpan span(this);

        while (changedNow) {
            changedNow = false;
            ensureSkeleton();

            // Crush edges if we can.
            if (countVertices() > components().size() &&
                    countVertices() > boundaryComponents_.size()) {
                for (NEdge* edge : edges())
                    if (collapseEdge(edge, true, perform)) {
                        changedNow = changed = true;
                        break;
                    }
                if (changedNow) {
                    if (perform)
                        continue;
                    else
                        return true;
                }
            }

            // Look for internal simplifications.
            for (NEdge* edge : edges()) {
                if (threeTwoMove(edge, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
                if (twoZeroMove(edge, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
                if (twoOneMove(edge, 0, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
                if (twoOneMove(edge, 1, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
            }
            if (changedNow) {
                if (perform)
                    continue;
                else
                    return true;
            }
            for (NVertex* vertex : vertices())
                if (twoZeroMove(vertex, true, perform)) {
                    changedNow = changed = true;
                    break;
                }
            if (changedNow) {
                if (perform)
                    continue;
                else
                    return true;
            }

            // Look for boundary simplifications.
            if (hasBoundaryTriangles()) {
                for (bit = boundaryComponents_.begin();
                        bit != boundaryComponents_.end(); bit++) {
                    // Run through triangles of this boundary component looking
                    // for shell boundary moves.
                    nTriangles = (*bit)->countTriangles();
                    for (iTriangle = 0; iTriangle < nTriangles; iTriangle++) {
                        if (shellBoundary((*bit)->triangle(iTriangle)->
                                front().tetrahedron(),
                                true, perform)) {
                            changedNow = changed = true;
                            break;
                        }
                    }
                    if (changedNow)
                        break;
                }
                if (changedNow) {
                    if (perform)
                        continue;
                    else
                        return true;
                }
            }
        }
    } // End scope for change event span.

    return changed;
}
Example #8
0
void AutoTriangleMesh<PointType>::ensureEdgeLength(const typename AutoTriangleMesh<PointType>::BasePoint& center,double radius,double minEdgeLength)
	{
	double radius2=radius*radius;
	
	/* Iterate through all triangles: */
	FaceIterator faceIt=BaseMesh::beginFaces();
	while(faceIt!=BaseMesh::endFaces())
		{
		/* Check quickly (ha!) if face overlaps area of influence: */
		bool overlaps=false;
		Edge* e=faceIt->getEdge();
		do
			{
			if(sqrDist(*e->getStart(),center)<=radius2)
				{
				overlaps=true;
				break;
				}
			
			/* Go to next edge: */
			e=e->getFaceSucc();
			}
		while(e!=faceIt->getEdge());
		
		if(overlaps)
			{
			/* Calculate face's minimum edge length: */
			Edge* shortestEdge=0;
			double shortestEdgeLength2=minEdgeLength*minEdgeLength;
			Edge* e=faceIt->getEdge();
			do
				{
				/* Calculate edge's squared length: */
				#if 1
				double edgeLength2=sqrDist(*e->getStart(),*e->getEnd());
				#else
				/* Calculate normal vectors for edge's vertices: */
				float normal1[3],normal2[3];
				calcNormal(e->getStart(),normal1);
				calcNormal(e->getEnd(),normal2);
				float dist1=0.0f;
				float dist2=0.0f;
				float edgeLength2=0.0f;
				float normal1Length2=0.0f;
				float normal2Length2=0.0f;
				for(int i=0;i<3;++i)
					{
					float dist=(*e->getEnd())[i]-(*e->getStart())[i];
					normal1Length2+=normal1[i]*normal1[i];
					normal2Length2+=normal2[i]*normal2[i];
					dist1+=dist*normal1[i];
					dist2+=dist*normal2[i];
					edgeLength2+=dist*dist;
					}
				dist1=fabsf(dist1)/sqrtf(normal1Length2);
				dist2=fabsf(dist2)/sqrtf(normal2Length2);
				float edgeLength=sqrtf(edgeLength2)+5.0f*(dist1+dist2);
				edgeLength2=edgeLength*edgeLength;
				#endif
				if(shortestEdgeLength2>edgeLength2&&canCollapseEdge(e))
					{
					shortestEdge=e;
					shortestEdgeLength2=edgeLength2;
					}
				
				/* Go to next edge: */
				e=e->getFaceSucc();
				}
			while(e!=faceIt->getEdge());
			
			/* Go to next triangle: */
			++faceIt;
			
			/* Check whether the shortest collapsible triangle edge is too short: */
			if(shortestEdge!=0)
				{
				/* Skip next face if it will be removed by edge collapse: */
				if(faceIt==shortestEdge->getOpposite()->getFace())
					++faceIt;
				
				/* Collapse shortest collapsible edge: */
				collapseEdge(shortestEdge);
				}
			}
		else
			{
			/* Go to the next triangle: */
			++faceIt;
			}
		}
	}