Esempio n. 1
0
    void HACD::ComputeEdgeCost(size_t e)
    {
		GraphEdge & gE = m_graph.m_edges[e];
        long v1 = gE.m_v1;
        long v2 = gE.m_v2;

        if (m_graph.m_vertices[v2].m_ancestors.size()>m_graph.m_vertices[v1].m_ancestors.size())
        {
            gE.m_v1 = v2;
            gE.m_v2 = v1;
			std::swap(v1, v2);
        }
		GraphVertex & gV1 = m_graph.m_vertices[v1];
		GraphVertex & gV2 = m_graph.m_vertices[v2];
#ifdef HACD_DEBUG
		if (v1 == 308 && v2==276)
		{
			gV1.m_convexHull->m_mesh.Save("debug1.wrl");
			gV2.m_convexHull->m_mesh.Save("debug2.wrl");
		}

#endif

        // create the edge's convex-hull
        ICHull  * ch = new ICHull(m_heapManager);
        (*ch) = (*gV1.m_convexHull);
		// update distPoints
#ifdef HACD_PRECOMPUTE_CHULLS
        delete gE.m_convexHull;
        gE.m_convexHull = 0;
#endif
        std::map<long, DPoint> distPoints;
		for(size_t p = 0; p < gV1.m_distPoints.Size(); ++p)
		{
			distPoints[gV1.m_distPoints[p].m_name] = gV1.m_distPoints[p];
		}

		std::map<long, DPoint>::iterator itDP1;
		for(size_t p = 0; p < gV2.m_distPoints.Size(); ++p)
		{
			const DPoint & point =  gV2.m_distPoints[p];
			itDP1 = distPoints.find(point.m_name);
			if (itDP1 == distPoints.end())
			{
				DPoint newPoint(point.m_name, 0, false, point.m_distOnly);
				distPoints.insert(std::pair<long, DPoint>(point.m_name, newPoint));
                if ( !point.m_distOnly )
                {
                    ch->AddPoint(m_points[point.m_name], point.m_name);
                }
			}
            else
            {
                if ( (itDP1->second).m_distOnly && !point.m_distOnly)
                {
                    (itDP1->second).m_distOnly = false;
                    ch->AddPoint(m_points[point.m_name], point.m_name);
                }
            }
		}

		ch->SetDistPoints(&distPoints);
        // create the convex-hull
        while (ch->Process() == ICHullErrorInconsistent)		// if we face problems when constructing the visual-hull. really ugly!!!!
		{
//			if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0);
            ICHull  * chOld = ch;
			ch = new ICHull(m_heapManager);
			CircularList<TMMVertex> & verticesCH = chOld->GetMesh().m_vertices;
			size_t nV = verticesCH.GetSize();
			long ptIndex = 0;
			verticesCH.Next();
			// add noise to avoid the problem
			ptIndex = verticesCH.GetHead()->GetData().m_name;
			ch->AddPoint(m_points[ptIndex]+ m_scale * 0.0001 * Vec3<Real>(rand() % 10 - 5, rand() % 10 - 5, rand() % 10 - 5), ptIndex);
			for(size_t v = 1; v < nV; ++v)
			{
				ptIndex = verticesCH.GetHead()->GetData().m_name;
				ch->AddPoint(m_points[ptIndex], ptIndex);
				verticesCH.Next();
			}
			delete chOld;
		}
#ifdef HACD_DEBUG
		if (v1 == 438 && v2==468)
		{
			const long nPoints = static_cast<long>(m_nPoints);
            std::map<long, DPoint>::iterator itDP(distPoints.begin());
            std::map<long, DPoint>::iterator itDPEnd(distPoints.end());
            for(; itDP != itDPEnd; ++itDP)
            {

				if (itDP->first >= nPoints)
                {
					long pt = itDP->first - nPoints;
					ch->AddPoint(m_extraDistPoints[pt], itDP->first);
				}
				else if (itDP->first >= 0)
                {
					long pt = itDP->first;
					ch->AddPoint(m_points[pt], itDP->first);
                }
                else
                {
					long pt = -itDP->first-1;
					ch->AddPoint(m_facePoints[pt], itDP->first);
					ch->AddPoint(m_facePoints[pt] + 10.0 * m_faceNormals[pt] , itDP->first);
				}
			}
			printf("-***->\n");

			ch->m_mesh.Save("debug.wrl");
		}
#endif
		double surf = gV1.m_surf + gV2.m_surf;
        double concavity = 0.0;
		double surfCH = ch->ComputeArea() / 2.0;
		double volumeCH = ch->ComputeVolume();
		double vol2Surf = volumeCH / surfCH;
		double concavity_flat = sqrt(fabs(surfCH-surf));
		double weightFlat = std::max(0.0, 1.0 - pow(- vol2Surf * 100.0 / (m_scale * m_flatRegionThreshold), 2.0));

//		concavity_flat *= std::max(exp(- vol2Surf * 100.0 / (m_scale * m_flatRegionThreshold)) - exp(-1.0), 0.0);
		concavity_flat *= weightFlat;
		if(!ch->IsFlat())
        {
            concavity = Concavity(*ch, distPoints);
        }
		concavity += concavity_flat;
#ifdef HACD_PRECOMPUTE_CHULLS
        gE.m_convexHull = ch;
#else
        delete ch;
#endif

		// compute boudary edges
		double perimeter = 0.0;
		if (m_alpha > 0.0)
		{
            std::set<unsigned long long> boudaryEdges1;
            for(size_t edV1 = 0; edV1 < gV1.m_boudaryEdges.Size(); ++edV1)
            {
                boudaryEdges1.insert(gV1.m_boudaryEdges[edV1]);
            }
            std::set<unsigned long long> boudaryEdges2;
            for(size_t edV2 = 0; edV2 < gV2.m_boudaryEdges.Size(); ++edV2)
            {
                boudaryEdges2.insert(gV2.m_boudaryEdges[edV2]);
            }
			std::set<unsigned long long> boudaryEdges;
			std::set_symmetric_difference (boudaryEdges1.begin(),
								           boudaryEdges1.end(),
								           boudaryEdges2.begin(),
								           boudaryEdges2.end(),
								           std::inserter( boudaryEdges, boudaryEdges.begin() ) );

			std::set<unsigned long long>::const_iterator itBE(boudaryEdges.begin());
			std::set<unsigned long long>::const_iterator itBEEnd(boudaryEdges.end());
			for(; itBE != itBEEnd; ++itBE)
			{
					perimeter += (m_points[static_cast<long>((*itBE) >> 32)] -
								   m_points[static_cast<long>((*itBE) & 0xFFFFFFFFULL)]).GetNorm();
			}
		}
Esempio n. 2
0
    void HACD::ComputeEdgeCost(size_t e)
    {
		GraphEdge & gE = m_graph.m_edges[e];
        long v1 = gE.m_v1;
        long v2 = gE.m_v2;

        if (m_graph.m_vertices[v2].m_distPoints.size()>m_graph.m_vertices[v1].m_distPoints.size())
        {
            gE.m_v1 = v2;
            gE.m_v2 = v1;
            //std::swap<long>(v1, v2);
			std::swap(v1, v2);
        }
		GraphVertex & gV1 = m_graph.m_vertices[v1];
		GraphVertex & gV2 = m_graph.m_vertices[v2];
	
        // delete old convex-hull
        delete gE.m_convexHull;
        // create the edge's convex-hull
        ICHull  * ch = new ICHull;
        gE.m_convexHull = ch;
        (*ch) = (*gV1.m_convexHull);
        
		// update distPoints
		gE.m_distPoints = gV1.m_distPoints;
		std::map<long, DPoint>::iterator itDP(gV2.m_distPoints.begin());
		std::map<long, DPoint>::iterator itDPEnd(gV2.m_distPoints.end());
		std::map<long, DPoint>::iterator itDP1;
     
		for(; itDP != itDPEnd; ++itDP) 
		{
			itDP1 = gE.m_distPoints.find(itDP->first);
			if (itDP1 == gE.m_distPoints.end())
			{
                gE.m_distPoints[itDP->first].m_distOnly = (itDP->second).m_distOnly;
                if ( !(itDP->second).m_distOnly )
                {
                    ch->AddPoint(m_points[itDP->first], itDP->first);
                }
			}
            else
            {
                if ( (itDP1->second).m_distOnly && !(itDP->second).m_distOnly)
                {
                    gE.m_distPoints[itDP->first].m_distOnly = false;
                    ch->AddPoint(m_points[itDP->first], itDP->first);
                }
            }
		}
		
		ch->SetDistPoints(&gE.m_distPoints);
        // create the convex-hull
        while (ch->Process() == ICHullErrorInconsistent)		// if we face problems when constructing the visual-hull. really ugly!!!!
		{
//			if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0);
			ch = new ICHull;
			CircularList<TMMVertex> & verticesCH = (gE.m_convexHull)->GetMesh().m_vertices;
			size_t nV = verticesCH.GetSize();
			long ptIndex = 0;
			verticesCH.Next();
			for(size_t v = 1; v < nV; ++v)
			{
				ptIndex = verticesCH.GetHead()->GetData().m_name;
				ch->AddPoint(m_points[ptIndex], ptIndex);
				verticesCH.Next();
			}
			delete gE.m_convexHull;
			gE.m_convexHull = ch;
		}
		double volume = 0.0; 
        double concavity = 0.0;
		if (ch->IsFlat())
		{
			bool insideHull;
            std::map<long, DPoint>::iterator itDP(gE.m_distPoints.begin());
            std::map<long, DPoint>::iterator itDPEnd(gE.m_distPoints.end());
            for(; itDP != itDPEnd; ++itDP) 
            {	
                if (itDP->first >= 0)
                {
                    concavity = std::max<double>(concavity, ch->ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], insideHull, false));
                }
			}
		}
        else
        {
            if (m_addNeighboursDistPoints)
            {  // add distance points from adjacent clusters
                std::set<long> eEdges;
                std::set_union(gV1.m_edges.begin(), 
                               gV1.m_edges.end(), 
                               gV2.m_edges.begin(), 
                               gV2.m_edges.end(),
                               std::inserter( eEdges, eEdges.begin() ) );
                
                std::set<long>::const_iterator ed(eEdges.begin());
                std::set<long>::const_iterator itEnd(eEdges.end());
                long a, b, c;
                for(; ed != itEnd; ++ed) 
                {
                    a = m_graph.m_edges[*ed].m_v1;
                    b = m_graph.m_edges[*ed].m_v2;
                    if ( a != v2 && a != v1)
                    {
                        c = a;
                    }
                    else if ( b != v2 && b != v1)
                    {
                        c = b;
                    }
                    else
                    {
                        c = -1;
                    }
                    if ( c > 0)
                    {
                        GraphVertex & gVC = m_graph.m_vertices[c];
                        std::map<long, DPoint>::iterator itDP(gVC.m_distPoints.begin());
                        std::map<long, DPoint>::iterator itDPEnd(gVC.m_distPoints.end());
                        std::map<long, DPoint>::iterator itDP1;
                        for(; itDP != itDPEnd; ++itDP) 
                        {
                            itDP1 = gE.m_distPoints.find(itDP->first);
							if (itDP1 == gE.m_distPoints.end())
							{
								if (itDP->first >= 0 && itDP1 == gE.m_distPoints.end() && ch->IsInside(m_points[itDP->first]))
								{
	                                gE.m_distPoints[itDP->first].m_distOnly = true;
		                        }
								else if (itDP->first < 0 && ch->IsInside(m_facePoints[-itDP->first-1]))
								{
									gE.m_distPoints[itDP->first].m_distOnly = true;
								}
							}
                        }
                    }
                }
            }
            concavity = Concavity(*ch, gE.m_distPoints);
        }
  
		// compute boudary edges
		double perimeter = 0.0;
		double surf    = 1.0;
		if (m_alpha > 0.0)
		{
			gE.m_boudaryEdges.clear();
			std::set_symmetric_difference (gV1.m_boudaryEdges.begin(), 
								  gV1.m_boudaryEdges.end(), 
								  gV2.m_boudaryEdges.begin(), 
								  gV2.m_boudaryEdges.end(),
								  std::inserter( gE.m_boudaryEdges, 
												 gE.m_boudaryEdges.begin() ) );

			std::set<unsigned long long>::const_iterator itBE(gE.m_boudaryEdges.begin());
			std::set<unsigned long long>::const_iterator itBEEnd(gE.m_boudaryEdges.end());
			for(; itBE != itBEEnd; ++itBE)
			{
					perimeter += (m_points[static_cast<long>((*itBE) >> 32)] - 
								   m_points[static_cast<long>((*itBE) & 0xFFFFFFFFULL)]).GetNorm();
			}
			surf    = gV1.m_surf + gV2.m_surf;
		}
Esempio n. 3
0
    void HACD::InitializeDualGraph()
    {
        long i, j, k;
        Vec3<Real> u, v, w, normal;
		delete [] m_normals;
		m_normals = new Vec3<Real>[m_nPoints];
        if (m_addFacesPoints)
        {
            delete [] m_facePoints;
            delete [] m_faceNormals;

			m_facePoints = new Vec3<Real>[m_nTriangles];
            m_faceNormals = new Vec3<Real>[m_nTriangles];
/*
            m_facePoints = new Vec3<Real>[4*m_nTriangles];
            m_faceNormals = new Vec3<Real>[4*m_nTriangles];
*/
        }
		memset(m_normals, 0, sizeof(Vec3<Real>) * m_nPoints);

        RaycastMesh rm;
        if (m_addExtraDistPoints)
        {
            rm.Initialize(m_nPoints, m_nTriangles, m_points, m_triangles, 15);
            m_extraDistPoints = new Vec3<Real>[m_nTriangles];
            m_extraDistNormals = new Vec3<Real>[m_nTriangles];
        }
        double progressOld = -1.0;
        double progress = 0.0;
		char msg[1024];
		double ptgStep = 1.0;
		m_area = 0.0;
		for(unsigned long f = 0; f < m_nTriangles; f++)
        {
            progress = f * 100.0 / m_nTriangles;
            if (fabs(progress-progressOld) > ptgStep && m_callBack)
            {
				sprintf(msg, "%3.2f %% \t \t \r", progress);
				(*m_callBack)(msg, progress, 0.0,  m_nTriangles);
                progressOld = progress;
            }

			i = m_triangles[f].X();
            j = m_triangles[f].Y();
            k = m_triangles[f].Z();
			m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(i, 0, false, false));
			m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(j, 0, false, false));
			m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(k, 0, false, false));

            ICHull  * ch = new ICHull(m_heapManager);
            m_graph.m_vertices[f].m_convexHull = ch;
            ch->AddPoint(m_points[i], i);
            ch->AddPoint(m_points[j], j);
            ch->AddPoint(m_points[k], k);
			ch->SetDistPoints(0);

			u = m_points[j] - m_points[i];
			v = m_points[k] - m_points[i];
			w = m_points[k] - m_points[j];
			normal = u ^ v;

			m_normals[i] += normal;
			m_normals[j] += normal;
			m_normals[k] += normal;

			m_graph.m_vertices[f].m_surf = normal.GetNorm();
			m_area += m_graph.m_vertices[f].m_surf;
            normal.Normalize();
			m_graph.m_vertices[f].m_boudaryEdges.Insert(GetEdgeIndex(i,j));
			m_graph.m_vertices[f].m_boudaryEdges.Insert(GetEdgeIndex(j,k));
			m_graph.m_vertices[f].m_boudaryEdges.Insert(GetEdgeIndex(k,i));
            if(m_addFacesPoints)
            {
                m_faceNormals[f] = normal;
                m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0;
				m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(-static_cast<long>(f)-1, 0, false, true));
            }
        }

		// Now we have all the points in the KD tree, optimize the distance points insertion by running them in parallel
		// if possible.
		if (m_addExtraDistPoints)
        {
			if (m_callBack)
				(*m_callBack)("++ Also adding distance points\n", 0.0, 0.0, 0);

	        progressOld = -1.0;
			progress = 0.0;
			long completed = 0;

#ifdef THREAD_DIST_POINTS
#pragma omp parallel for
#endif
			for(long f = 0; f < (long)m_nTriangles; f++)
			{
				Vec3<Real> seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0);
				Vec3<Real> hitPoint;
				Vec3<Real> hitNormal;
				normal = -normal;
                size_t faceIndex = m_nTriangles;

				Float dist;
				long hitTriangle;
				if (rm.Raycast(seedPoint,normal,hitTriangle,dist, hitPoint, hitNormal))
				{
					faceIndex = hitTriangle;
				}

                if (faceIndex < m_nTriangles )
                {
					m_extraDistPoints[f] = hitPoint;
					m_extraDistNormals[f] = hitNormal;
					m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(m_nPoints+f, 0, false, true));
				}

				// Atomic update of the progress
				#ifdef THREAD_DIST_POINTS
				#pragma omp critical
				#endif
				{
					completed++;

					progress = completed * 100.0 / m_nTriangles;
					if (fabs(progress-progressOld) > ptgStep && m_callBack)
					{
						sprintf(msg, "%3.2f %% \t \t \r", progress);
						(*m_callBack)(msg, progress, 0.0,  m_nTriangles);
						progressOld = progress;
					}
				}
			}
		}

        for (size_t v = 0; v < m_nPoints; v++)
		{
			m_normals[v].Normalize();
		}
    }
Esempio n. 4
0
    void HACD::InitializeDualGraph()
    {
        long i, j, k;
        Vec3<Real> u, v, w, normal;
		delete [] m_normals;
		m_normals = new Vec3<Real>[m_nPoints];
        if (m_addFacesPoints)
        {
            delete [] m_facePoints;
            delete [] m_faceNormals;
            m_facePoints = new Vec3<Real>[m_nTriangles];
            m_faceNormals = new Vec3<Real>[m_nTriangles];
        }
		memset(m_normals, 0, sizeof(Vec3<Real>) * m_nPoints);
        for(unsigned long f = 0; f < m_nTriangles; f++)
        {
			if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0);
			
			if (gCancelRequest)
				return;

            i = m_triangles[f].X();
            j = m_triangles[f].Y();
            k = m_triangles[f].Z();
		
			m_graph.m_vertices[f].m_distPoints[i].m_distOnly = false;
			m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false;
			m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false;
            
            ICHull  * ch = new ICHull;
            m_graph.m_vertices[f].m_convexHull = ch;
            ch->AddPoint(m_points[i], i);
            ch->AddPoint(m_points[j], j);
            ch->AddPoint(m_points[k], k);
			ch->SetDistPoints(&m_graph.m_vertices[f].m_distPoints);

			u = m_points[j] - m_points[i];
			v = m_points[k] - m_points[i];
			w = m_points[k] - m_points[j];
			normal = u ^ v;

			m_normals[i] += normal;
			m_normals[j] += normal;
			m_normals[k] += normal;

			m_graph.m_vertices[f].m_surf = normal.GetNorm();
			m_graph.m_vertices[f].m_perimeter = u.GetNorm() + v.GetNorm() + w.GetNorm();
            
            normal.Normalize();

			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i,j));
			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j,k));
			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k,i));
            if(m_addFacesPoints)
            {
                m_faceNormals[f] = normal;
                m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0;
                m_graph.m_vertices[f].m_distPoints[-static_cast<long>(f)-1].m_distOnly = true;
            }
            if (m_addExtraDistPoints)	
            {// we need a kd-tree structure to accelerate this part!
                long i1, j1, k1;
                Vec3<Real> u1, v1, normal1;
				normal = -normal;
                double distance = 0.0;
                double distMin = 0.0;
                size_t faceIndex = m_nTriangles;
                Vec3<Real> seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0);
                long nhit = 0;
                for(size_t f1 = 0; f1 < m_nTriangles; f1++)
                {
                    i1 = m_triangles[f1].X();
                    j1 = m_triangles[f1].Y();
                    k1 = m_triangles[f1].Z();
                    u1 = m_points[j1] - m_points[i1];
                    v1 = m_points[k1] - m_points[i1];
                    normal1 = (u1 ^ v1);
                    if (normal * normal1 > 0.0)
                    {
                        nhit = IntersectRayTriangle(Vec3<double>(seedPoint.X(), seedPoint.Y(), seedPoint.Z()),
													Vec3<double>(normal.X(), normal.Y(), normal.Z()),
													Vec3<double>(m_points[i1].X(), m_points[i1].Y(), m_points[i1].Z()),
													Vec3<double>(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()),
													Vec3<double>(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()),
													distance);
                        if ((nhit==1) && ((distMin > distance) || (faceIndex == m_nTriangles)))
                        {
                            distMin = distance;
                            faceIndex = f1;
                        }

                    }
                }
                if (faceIndex < m_nTriangles )
                {
                    i1 = m_triangles[faceIndex].X();
                    j1 = m_triangles[faceIndex].Y();
                    k1 = m_triangles[faceIndex].Z();
                    m_graph.m_vertices[f].m_distPoints[i1].m_distOnly = true;
                    m_graph.m_vertices[f].m_distPoints[j1].m_distOnly = true;
                    m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true;
					if (m_addFacesPoints)
					{
						m_graph.m_vertices[f].m_distPoints[-static_cast<long>(faceIndex)-1].m_distOnly = true;
					}
				}
            }
        }
        for (size_t v = 0; v < m_nPoints; v++) 
		{
			m_normals[v].Normalize();
		}
    }