Raw File
WeakVisDecomp.cpp
#pragma once
#include "pch.h"
#include "WeakVisDecomp.h"
#include "Visibility.h"
#include "IOHandling.h"

WeakVisNode::WeakVisNode() {
};
int WeakVisNode::weakVisCounter = 0;

WeakVisNode::WeakVisNode(Arrangement_2& thePolygon, Arrangement_2 previousPolygon,
	int papaId, Halfedge_handle startingEdge, bool computeWeakvis) {
	this->papaId = papaId;
	id = WeakVisNode::weakVisCounter;
	WeakVisNode::weakVisCounter++;

	if (computeWeakvis) {
		//compute own visibility polygon
		CEV weakVisibility(previousPolygon);
		Face_handle ownInterior = weakVisibility.compute_visibility({ startingEdge->curve(), startingEdge->curve().flip() }, ownPolygon);
		boundary = arrangementToPolygon(ownPolygon);

		//draw the weakvispolygon
		/*IOHandling::DrawWeakVis(
			weakVisibility, "/tester/wvpoly-" + to_string(id),
			{ startingEdge->curve(), startingEdge->curve().flip() }, boundary.container());*/


		//Find corresponding edge in ownInterior
		Halfedge_handle ownStartingEdge;
		bool startingFound = false;
		auto eit = ownInterior->outer_ccb();
		do {
			if (eit->target()->point() == startingEdge->target()->point() && eit->source()->point() == startingEdge->source()->point()) {
				ownStartingEdge = eit;
				startingFound = true;
			}
		} while (++eit != ownInterior->outer_ccb());

		//find new halfedges added by own polygon
		vector<Segment_2> newEdges = {};
		auto ownEdge = ownStartingEdge;
		auto bigEdge = startingEdge;
		do {
			//still the same
			if (bigEdge->target()->point() == ownEdge->target()->point())
			{
				bigEdge = bigEdge->next();
				ownEdge = ownEdge->next();
			}
			else {
				if (bigEdge->curve().line().has_on(ownEdge->target()->point())) {
					//ownEdge and bigEdge are parallel: The next edge must be new
					ownEdge = ownEdge->next();
				}
				newEdges.push_back(ownEdge->curve());

				bool sameTarget = false;
				bool ownTargetOnEdge = false;

				while (!sameTarget && !ownTargetOnEdge) {
					bigEdge = bigEdge->next();
					sameTarget = bigEdge->target()->point() == ownEdge->target()->point();
					ownTargetOnEdge = Segment_2(bigEdge->source()->point(), bigEdge->target()->point()).has_on(ownEdge->target()->point());
				}

				if (ownTargetOnEdge && !sameTarget) {
					ownEdge = ownEdge->next();
				}
			}

		} while (ownEdge != ownStartingEdge);

		for (auto& newEdge : newEdges)
		{
			//CGAL::insert_point(thePolygon, newEdge.source());
			Face_handle newFace;
			//Because of "interesting CGAL design", we have to find the face we just created...
			CGAL::insert(thePolygon, newEdge);
			Arrangement_2 arrCopy = previousPolygon; //we check previouspolygon and not thePolygon, because this one is way smaller
			CGAL::insert(arrCopy, newEdge);
			//Find face here
			for (auto fit = arrCopy.faces_begin(); fit != arrCopy.faces_end();fit++) {
				if (fit->has_outer_ccb()) {
					bool originalFaceFound = false;
					//try to find the new face
					eit = fit->outer_ccb();
					do {
						Segment_2 seg(eit->curve().source(), eit->curve().target());
						if (seg.has_on(startingEdge->target()->point()) && seg.has_on(startingEdge->source()->point())) {
							originalFaceFound = true;
							break;
						}
					} while (++eit != fit->outer_ccb());
					if (!originalFaceFound) {
						newFace = fit;
						break;
					}
				}
			}

			//Create polygon for child weakvis node
			Arrangement_2 nextPolygon;
			Halfedge_handle childStartingEdge;
			vector<Segment_2> newArrSegs = {};
			//eit = newFace->outer_ccb();
			do {
				if (newEdge.has_on(eit->target()->point()) && newEdge.has_on(eit->source()->point()))
					childStartingEdge = eit;
				newArrSegs.push_back(eit->curve());
			} while (++eit != newFace->outer_ccb());
			CGAL::insert_non_intersecting_curves(nextPolygon, newArrSegs.begin(), newArrSegs.end());

			children.push_back(shared_ptr<WeakVisNode>(new WeakVisNode(thePolygon, nextPolygon, id, childStartingEdge, computeWeakvis)));
		}
	}
	else {
		ownPolygon = thePolygon;
	}

	//find my face in the polygon
	Face_handle myFace;
	boundary = arrangementToPolygon(ownPolygon);

	for (auto fit = thePolygon.faces_begin(); fit != thePolygon.faces_end();fit++) {
		if (fit->has_outer_ccb()) {
			bool faceFound = false;
			//try to find the face
			auto eit = fit->outer_ccb();
			do {
				Segment_2 seg(eit->curve().source(), eit->curve().target());
				if (eit->source()->point() == startingEdge->source()->point() && eit->target()->point() == startingEdge->target()->point()) {
					faceFound = true;
					break;
				}
			} while (++eit != fit->outer_ccb());
			if (faceFound) {
				myFace = fit;
				break;
			}
		}
	}


	myFace->data().fweakNodeIds = { this->id };
	auto eit = myFace->outer_ccb();
	do {
		eit->source()->data().pweakNodeIds.insert(this->id);
	} while (++eit != myFace->outer_ccb());
}

int WeakVisNode::subTreeSize() {
	int result = children.size();

	//Call all children
	for (auto cit = children.begin(); cit != children.end(); cit++)
		result += (*cit)->subTreeSize();

	return result;
}

vector<shared_ptr<WeakVisNode>> WeakVisNode::subTree() {
	vector<shared_ptr<WeakVisNode>> result;

	//Call all children
	for (auto cit = children.begin(); cit != children.end(); cit++) {
		result.push_back(shared_ptr<WeakVisNode>(*cit));

		vector<shared_ptr<WeakVisNode>> childTree = (*cit)->subTree();
		result.insert(result.end(), childTree.begin(), childTree.end());
	}

	return result;
}


int WeakVisNode::maxVertices() {
	int maxVertices = ownPolygon.number_of_vertices();
	for (auto cit = children.begin(); cit != children.end(); cit++) {
		maxVertices = max(maxVertices, (*cit)->maxVertices());
	}
	return maxVertices;
}

int WeakVisNode::maxReflexVertices() {
	//count own reflex vertices
	int maxReflexVertices = 0;
	for (auto vit = ownPolygon.vertices_begin(); vit != ownPolygon.vertices_end(); vit++)
		if (vit->data().isReflex)
			maxReflexVertices++;

	//compare to children
	for (auto cit = children.begin(); cit != children.end(); cit++) {
		maxReflexVertices = max(maxReflexVertices, (*cit)->maxReflexVertices());
	}
	return maxReflexVertices;
}

bool WeakVisNode::canSeeDecomp(shared_ptr<WeakVisNode> other) {
	//is he me, is he my papa, am I his papa, are we sibblings?
	return (this->id == other->id) || (papaId == other->id) || (this->id == other->papaId) || (papaId == other->papaId);	
}

void WeakVisNode::clearTree() {
	for (auto cit = children.begin(); cit != children.end(); cit++) {
		(*cit)->clearTree();
	}

	children = {};
}


back to top