Example #1
0
Graph::~Graph()
{
	ListIterator<NodeArrayBase*> itVNext;
	for(ListIterator<NodeArrayBase*> itV = m_regNodeArrays.begin();
		itV.valid(); itV = itVNext)
	{
		itVNext = itV.succ();
		(*itV)->disconnect();
	}

	ListIterator<EdgeArrayBase*> itENext;
	for(ListIterator<EdgeArrayBase*> itE = m_regEdgeArrays.begin();
		itE.valid(); itE = itENext)
	{
		itENext = itE.succ();
		(*itE)->disconnect();
	}

	ListIterator<AdjEntryArrayBase*> itAdjNext;
	for(ListIterator<AdjEntryArrayBase*> itAdj = m_regAdjArrays.begin();
		itAdj.valid(); itAdj = itAdjNext)
	{
		itAdjNext = itAdj.succ();
		(*itAdj)->disconnect();
	}

	for (node v = m_nodes.begin(); v; v = v->succ()) {
		v->m_adjEdges.~GraphList<AdjElement>();
	}
}
Example #2
0
	List<double> DavidsonHarel::returnEnergyFunctionWeights()
	{
		List<double> weights;
		ListIterator<double> it;
		for(it = m_weightsOfEnergyFunctions.begin(); it.valid(); it = it.succ())
			weights.pushBack(*it);
		return weights;
	}
Example #3
0
	List<string> DavidsonHarel::returnEnergyFunctionNames()
	{
		List<string> names;
		ListIterator<EnergyFunction*> it;
		for(it = m_energyFunctions.begin(); it.valid(); it = it.succ())
			names.pushBack((*it)->getName());
		return names;
	}
Example #4
0
//steps through all energy functions and adds the initial energy computed by each
//function for the start layout
void DavidsonHarel::computeInitialEnergy()
{
	OGDF_ASSERT(!m_energyFunctions.empty());
	ListIterator<EnergyFunction*> it;
	ListIterator<double> it2;
	it2 = m_weightsOfEnergyFunctions.begin();
	for(it = m_energyFunctions.begin(); it.valid() && it2.valid(); it=it.succ(), it2 = it2.succ())
		m_energy += (*it)->energy() * (*it2);
}
Example #5
0
void RadialTreeLayout::Grouping::computeAdd(double &D, double &W)
{
	D = W = 0;

	ListIterator<Group> it;
	for(it = begin(); it.valid(); ++it)
	{
		Group &g = *it;

		D += g.m_sumD;

		if(g.m_leafGroup == true)
			continue;

		W += g.m_sumW;

		ListIterator<Group> itL;

		itL = it.pred();
		if(itL.valid() == false) {
			g.m_leftAdd = 0.0;
		} else {
			ListIterator<Group> itR = itL.pred();
			if(itR.valid() == false)
				g.m_leftAdd = (*itL).m_sumD;
			else
				g.m_leftAdd = (*itL).m_sumD * g.m_sumW / (*itR).m_sumW;
		}

		itL = it.succ();
		if(itL.valid() == false) {
			g.m_leftAdd = 0.0;
		} else {
			ListIterator<Group> itR = itL.succ();
			if(itR.valid() == false)
				g.m_leftAdd = (*itL).m_sumD;
			else
				g.m_leftAdd = (*itL).m_sumD * g.m_sumW / (*itR).m_sumW;
		}
	}
}
Example #6
0
void ENGLayer::simplifyAdjacencies(List<LHTreeNode::Adjacency> &adjs)
{
	AdjacencyComparer cmp;

	if(!adjs.empty()) {
		adjs.quicksort(cmp);

		ListIterator<LHTreeNode::Adjacency> it = adjs.begin();
		ListIterator<LHTreeNode::Adjacency> itNext = it.succ();

		while(itNext.valid()) {
			if((*it).m_u == (*itNext).m_u && (*it).m_v == (*itNext).m_v) {
				(*it).m_weight += (*itNext).m_weight;

				adjs.del(itNext);
				itNext = it.succ();

			} else {
				it = itNext;
				++itNext;
			}
		}
	}
}
Example #7
0
void UpwardPlanRep::computeSinkSwitches()
{
	OGDF_ASSERT(m_Gamma.externalFace() != nullptr);

	if (s_hat == nullptr)
		hasSingleSource(*this, s_hat);
	FaceSinkGraph fsg(m_Gamma, s_hat);
	List<adjEntry> dummyList;
	FaceArray< List<adjEntry> > sinkSwitches(m_Gamma, dummyList);
	fsg.sinkSwitches(sinkSwitches);
	m_sinkSwitchOf.init(*this, nullptr);

	for(face f : m_Gamma.faces) {
		List<adjEntry> switches = sinkSwitches[f];
		ListIterator<adjEntry> it = switches.begin();
		for (it = it.succ(); it.valid(); ++it) {
			m_sinkSwitchOf[(*it)->theNode()] = (*it);
		}
	}
}
Example #8
0
//Connect parts of partial active current CC.
//Note that this only makes sense when the CC parts are
//already correctly embedded. Crossings are already replaced
//by nodes
bool PlanRepInc::makeTreeConnected(adjEntry /* adjExternal */)
{

	//we compute node numbers for the partial CCs in order to
	//identify the treeConnect Edges that can be deleted later
	m_component.init(*this, -1);

	//if there is only one CC, we don't need to connect
	if (isConnected(*this)) return false;
	//We have to insert edges connnecting nodes lying on
	//the "external" face of the active parts

	//First, we activate the CC's parts one by one and compute
	//the 'external' face from the layout information
	//If the PlanRepInc is not embedded corresponding to
	//this layout, we may introduce edges that are non-planar
	//in the drawing, leading to problems when we compute paths
	//in the dual graph

	List<node> isolatedNodes;
	const int numPartialCC = connectedIsolatedComponents(*this,
		isolatedNodes, m_component);

	//CombinatorialEmbedding can cope with unconnected graphs
	//but does not provide faces for isolated nodes
	CombinatorialEmbedding E(*this);
	TopologyModule tm;
	List<adjEntry> extAdjs;
	//we run through all faces searching for all outer faces
	for(face f : E.faces)
	{
		//TODO: check if we should select special adjEntry instead of first
		if (tm.faceSum(*this, *m_pGraphAttributes, f) < 0)
			extAdjs.pushBack(f->firstAdj());

#ifdef OGDF_DEBUG
		cout << "FaceSum in Face " << f->index() << " Groesse " << f->size()
			<< " ist: " << tm.faceSum(*this, *m_pGraphAttributes, f) <<"\n" << flush;
#endif
	}//forallfaces

	//now we have faces for all partial CCs that are not isolated nodes

	OGDF_ASSERT(extAdjs.size() + isolatedNodes.size() == numPartialCC)
	//OGDF_ASSERT(extAdjs.size() > 1) //eigentlich: = #partial CCs
	//OGDF_ASSERT(extAdjs.size() == numPartialCC)

	const int n1 = numPartialCC-1;
	m_eTreeArray.init(0, n1, 0, n1, nullptr);
	m_treeInit = true;

	//Three cases: only CCs, only isolated nodes, and both (where
	//only one CC + isolated nodes is possible

	//now we connect all partial CCs by inserting edges at the adjEntries
	//in extAdjs and adding all isolated nodes
	adjEntry lastAdj = nullptr;
	ListIterator<adjEntry> it = extAdjs.begin();
	while(it.valid())
	{
		//for the case: one external face, multiple isolated nodes
		lastAdj = (*it);
		adjEntry adj = (*it);
		ListIterator<adjEntry> it2 = it.succ();
		if (it2.valid())
		{
			adjEntry adj2 = (*it2);
			edge eTree = newEdge(adj, adj2);
			m_treeEdge[eTree] = true;
			lastAdj = eTree->adjTarget();
			//save the connection edge by CC number index
			//this is used when deleting obsolete edges later
			//after edge reinsertion
			m_eTreeArray(componentNumber(adj->theNode()), componentNumber(adj2->theNode())) =
				m_eTreeArray(m_component[adj2->theNode()], m_component[adj->theNode()])
				= eTree;
		}//if CCs left to connect

		++it;
	}//while
	while (!isolatedNodes.empty())
	{
		node uvw = isolatedNodes.popFrontRet();
		if (lastAdj)
		{
			//same block as above
			edge eTree = newEdge(uvw, lastAdj);
			m_treeEdge[eTree] = true;
			//save the connection edge by CC number index
			//this is used when deleting obsolete edges later
			//after edge reinsertion
			m_eTreeArray(componentNumber(lastAdj->theNode()), componentNumber(uvw)) =
				m_eTreeArray(m_component[uvw], m_component[lastAdj->theNode()])
				= eTree;
			lastAdj = eTree->adjSource();
		}
		else //connect the first two isolated nodes / only iso nodes exist
		{
			//MUST BE #isonodes>1, else we returned already because CC connected
			OGDF_ASSERT(!isolatedNodes.empty())
			node secv = isolatedNodes.popFrontRet();
			//same block as above
			edge eTree = newEdge(uvw, secv);
			m_treeEdge[eTree] = true;
			//save the connection edge by CC number index
			//this is used when deleting obsolete edges later
			//after edge reinsertion
			m_eTreeArray(componentNumber(secv), componentNumber(uvw)) =
				m_eTreeArray(m_component[uvw], m_component[secv])
				= eTree;
			lastAdj = eTree->adjSource();

		}
	}//while isolated nodes

	OGDF_ASSERT(isConnected(*this));


	//List<adjEntry> extAdjs;
	//getExtAdjs(extAdjs);


	return true;
}//makeStarConnected