Raw File
GroupRelationDetector.cpp
#include "GroupRelationDetector.h"

void GroupRelationDetector::detect(QVector<PairRelation>& prRelations)
{
    detectSymmGroupByRefPair( prRelations);
    detectRefSymmGroupByTransPair( prRelations);
    //detectCoplanarGroup( prRelations);
    //mergeCoplanarGroup();
    removeRedundantGroup();
}

void GroupRelationDetector::detectSymmGroupByRefPair(QVector<PairRelation>& prRelations)
{
    int nPrs = prRelations.size();
    for (int i=0; i<nPrs; ++i)
        prRelations[i].tag = false;

    double dotVal1(0.0);
    ///////////
    // build group from REF pair with assumption that no TRANS pair is detected as REF pair
    for (int i=0; i<nPrs; ++i)
    {
		//////////////////// detect group
        PairRelation& pr1 = prRelations[i];
        if ( pr1.tag || REF.compare(pr1.type)) continue;
                
		QSet<QString> ids;
		ids.insert( pr1.n1->id);			ids.insert(pr1.n2->id);
		pr1.tag = true;
		
		for (int j=i+1; j<nPrs; ++j)
        {
            PairRelation& pr2 = prRelations[j];
            if ( pr2.tag || REF.compare(pr2.type)) continue;
            if ( isIntersected(ids, pr2) )
            {
				ids.insert(pr2.n1->id);	ids.insert(pr2.n2->id);
                pr2.tag = true;
			}
		}

		//////////////////// sort
		GroupRelation gr;
		gr.ids.push_back( *ids.begin() );
		ids.erase(ids.begin());		
		
		Structure::Node *n1, *n2;
		while(!ids.isEmpty())
		{
			n1 = graph_->getNode(gr.ids.last());
			Vector_3 v1, v2;
			node2direction(n1,v1); 

			double angle = -2;
			QSet<QString>::iterator itor;
			for ( QSet<QString>::iterator it = ids.begin(); it != ids.end(); ++it)
			{
				n2 = graph_->getNode(*it);
				node2direction(n2,v2); 				
				dotVal1 = v1.dot(v2);
				
				if ( angle < dotVal1)
				{
					angle = dotVal1;
					itor = it;
				}
			}
			gr.ids.push_back( *itor);
			ids.erase(itor);
		}

		//////////////////// detect axis
		int n = gr.ids.size();
		gr.direction = Eigen::Vector3d(0.0,0.0,0.0);
		for (int j=0; j<n; ++j)
		{
			n1 = graph_->getNode(gr.ids[j]);
			n2 = graph_->getNode(gr.ids[(j+1)%n]);

			Vector_3 v1, v2;
			node2direction(n1,v1); node2direction(n2,v2);
            Vector_3 dir = cross_product(v1, v2);
			dir.normalize();
			if ( dir.dot(gr.direction) < 0)
				gr.direction = gr.direction - dir;
			else
				gr.direction = gr.direction + dir;
		}
		gr.direction.normalize();

		////////////////////
        gr.diameter = computeGroupDiameter(gr);
		computeGroupCenter(gr);

        ////////////////
		gr.note = REF;
        gr.deviation = computeAxisSymmetryGroupDeviationSortParts(gr, pointLevel_);
		gr.type = AXIS_SYMMETRY;
		if ( this->logLevel_ > 0)
		{
			logStream_ << gr;
			logStream_ << "Normalized axis gourp deviation: " << gr.deviation / this->normalizeCoef_ << "\n";
		}        
        if ( gr.deviation / this->normalizeCoef_ < thAxisGroup_)
        {			
            groupRelations_.push_back(gr);
        }
        else
        {            
            gr.deviation = computeRefSymmetryGroupDeviation(gr,pointLevel_);
			gr.type = REF_SYMMETRY;
			if ( this->logLevel_ > 0)
			{
				logStream_ << gr;
				logStream_ << "Normalized ref gourp deviation: " << gr.deviation / this->normalizeCoef_ << "\n";
			}
            if ( gr.deviation / this->normalizeCoef_ < thRefGroup_)
            {				
                groupRelations_.push_back(gr);
            }
        }

    }
    ////////////// remove pairs have been put into groups
    prRelations.erase( std::remove_if(prRelations.begin(), prRelations.end(), isTaged), prRelations.end() );
}

void GroupRelationDetector::detectRefSymmGroupByTransPair(QVector<PairRelation>& prRelations)
{
	if ( this->logLevel_ > 0)
	{
		logStream_ << "GroupRelationDetector::detectSymmGroupByTransPair called! \n";
	}

    int nPrs = prRelations.size();
    for (int i=0; i<nPrs; ++i)
        prRelations[i].tag = false;

    ///////////
    // build group from pair
    for (int i=0; i<nPrs; ++i)
    {
        PairRelation& pr1 = prRelations[i];
        if ( pr1.tag || TRANS.compare(pr1.type)) continue;

        QSet<QString> ids;
        GroupRelation gr;
        gr.type = symmTypeOfTansPair(pr1);
        if ( NONE != gr.type)
        {
            ids.insert( pr1.n1->id);
            ids.insert( pr1.n2->id);
            pr1.tag = true;
        }
        else
            continue;

        ///////////////
        for (int j=i+1; j<nPrs; ++j)
        {
            PairRelation& pr2 = prRelations[j];
            if ( pr2.tag || TRANS.compare(pr2.type)) continue;

            if ( isIntersected(ids, pr2) )
            {
                QString type2 = symmTypeOfTansPair(pr2);
                if ( NONE != type2)
                {
                    if ( REF_SYMMETRY == gr.type)
                    {
                        if ( std::abs( pr1.trans_vec.norm()-pr2.trans_vec.norm() ) >
                            pr1.n1->bbox().diagonal().norm()*thRefGroup_*2 )
                        {
                            continue;
                        }
                    }
                    ids.insert(pr2.n1->id);
                    ids.insert(pr2.n2->id);
                    pr2.tag = true;
                }
            }
        }

        ///////////////
        computeTransGroupInfo(gr, ids);
		gr.note = TRANS;       
        gr.type = REF_SYMMETRY;
		gr.deviation = computeRefSymmetryGroupDeviation(gr, pointLevel_);
		if ( this->logLevel_ > 0)
		{
			logStream_ << gr;
			logStream_ << "Normalized ref gourp deviation: " << gr.deviation / this->normalizeCoef_ << "\n";
		}
        if ( gr.deviation / this->normalizeCoef_ < thRefGroup_)
        {
            groupRelations_.push_back(gr);
        }

    }
    ////////////// remove pairs have been put into groups
    prRelations.erase( std::remove_if(prRelations.begin(), prRelations.end(), isTaged), prRelations.end() );
}

void GroupRelationDetector::removeRedundantGroup()
{
    for ( int i = 0; i < (int) groupRelations_.size(); ++i)
    {
        groupRelations_[i].tag = false;
    }
    for ( int i = 0; i < (int) groupRelations_.size(); ++i)
    {
        if ( groupRelations_[i].tag )
            continue;

        for ( int j = i+1; j < (int) groupRelations_.size(); ++j)
        {
            if ( isSubgroup(groupRelations_[i].ids, groupRelations_[j].ids) )
                groupRelations_[j].tag = true;
        }
    }
    groupRelations_.erase( std::remove_if(groupRelations_.begin(), groupRelations_.end(), isTagedGr), groupRelations_.end() );
}
bool GroupRelationDetector::isIntersected(QSet<QString>& ids, PairRelation& pr2)
{
    for ( QSet<QString>::iterator it = ids.begin(); it != ids.end(); ++it)
    {
        if ( *it == pr2.n1->id || *it == pr2.n2->id)
            return true;
    }
    return false;
}

bool GroupRelationDetector::isSubgroup(QVector<QString>& ids1, QVector<QString>& ids2)
{
    int count(0);
    for ( int i = 0; i < (int) ids2.size(); ++i)
    {
        for ( int j = 0; j < (int) ids1.size(); ++j)
        {
            if ( ids2[i] == ids1[j] )
            {
                ++count;
                break;
            }
        }
    }
    if ( ids2.size() == count)
        return true;
    else
        return false;
}
QString GroupRelationDetector::symmTypeOfTansPair(PairRelation& pr1)
{
    QString result(NONE);
    Vector_3 d1;
    bool iscurve1 = node2direction(pr1.n1, d1);
    if ( iscurve1 )
    {
        result = AXIS_SYMMETRY;
    }
    else
    {
        result = REF_SYMMETRY;
    }

    return result;
}

void vectorId2SetId(QVector<QString>& vec, QSet<QString>& set)
{
	for ( QVector<QString>::iterator it = vec.begin(); it!=vec.end(); ++it)
	{
		set.insert(*it);
	}
}
void setId2VectorId(QSet<QString>& set, QVector<QString>& vec)
{
	for ( QSet<QString>::iterator it = set.begin(); it!=set.end(); ++it)
	{
		vec.push_back(*it);
	}
}
back to top