コード例 #1
0
ファイル: hacdHACD.cpp プロジェクト: mackron/GTGameEngine
    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();
			}
		}
コード例 #2
0
ファイル: hacdHACD.cpp プロジェクト: Bredoto/Bullet
    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;
		}