Advertisement

Find the outline points of an object

Started by April 13, 2019 04:17 PM
11 comments, last by _WeirdCat_ 5 years, 1 month ago

Those are plain vertices, working on algo.

its been a while but heres a code for it: first we need to create a set of polygons that are attached one to another and call them objects then through all objects we create a linked list of edges of all object polygons then through these objects edges we clip edges with another leaving not sorted list of outline edges: first the edge and poly class:

const int TPolygon_dim = 124;//122;






class TEdge
{
	public:
	vec3 v1;
	vec3 v2;
	int id;
	TEdge * next;
	TEdge * prev;
	
	bool processed;
	
	//face points outside object
	vec3 n;
	float d;
	int cn_vi; //connected to next: vertex index
	int cp_vi; //connected to prevorious: vertex index
	
	void Constructor()
	{
		id = -1;
		next = 0;
		prev = 0;
		processed = false;
		d = 0.0;
		cn_vi = -1;
		cp_vi = -1;
	}
	
	TEdge()
	{
		Constructor();
	}




TEdge( vec3 a, vec3 b  ) : v1(a), v2(b)
{
	Constructor();
}


TEdge( vec3 a, vec3 b, vec3 an, float ad  ) : v1(a), v2(b)
{
	Constructor();
	n = an;
	d = ad;
}


TEdge( TEdge * in )
		{
Constructor();
v1 = in->v1;
v2 = in->v2;
n = in->n;
d = in->d;
		}




	/*	TEdge & operator = (const TEdge & in)
		{
v1 = in.v1;
v2 = in.v2;
n = in.n;
d = in.d;


			return *this;
		}
*/


		bool operator == (const TEdge& in)
		{
bool b[4];
			b[0] = (v1 == in.v1);
			b[1] = (v2 == in.v2);
			b[2] = (v1 == in.v2);
			b[3] = (v2 == in.v1);
int cnt = 0;
for (int i=0; i < 4; i++)
if (b[i]) cnt = cnt + 1;


return (cnt >= 2);
		}




		vec3 getV(int a)
		{
			if (a < 0) return v1;
			if (a > 1) return v2;
			if (a == 0) return v1;
			if (a == 1) return v2;


          return v1;			
		}
	
	int other_vertex(int a)
	{
		if (a == 0) return 1;
		if (a == 1) return 0;	
		if (a < 0) return 1;
		if (a > 1) return 0;
		return a;
	}
	
	bool SameEdge(TEdge * in)
	{
return ( ((v1 == in->v1) && (v2 == in->v2)) || ((v1 == in->v2) && (v2 == in->v1)) );
	}








//check whenever each edge shares one vertex
bool overlaps_with(TEdge * in, int & pvi, int & invi)
{
	vec3 lav1 = ClosestPointOnLine (v1, v2, in->v1);
	vec3 lav2 = ClosestPointOnLine (v1, v2, in->v2);
	float av1_dst = n3ddistance(lav1, in->v1);
	float av2_dst = n3ddistance(lav2, in->v2);
	
	bool v1_hit = (av1_dst <= close_to_zero); //tells if point lies on edge
	bool v2_hit = (av2_dst <= close_to_zero); //tells if point lies on edge
		
		if ((v1_hit) && (v2_hit)) { pvi = -1; invi = -1; return true; }
		if ((!v1_hit) && (!v2_hit)) return false;
		


		if (v1_hit) invi = 0;
		if (v2_hit) invi = 1;
//	if here then we swap edges and check for overlap condition
//	(means there must be one hit)




	 lav1 = ClosestPointOnLine (in->v1, in->v2, v1);
	 lav2 = ClosestPointOnLine (in->v1, in->v2, v2);
	 av1_dst = n3ddistance(lav1, v1);
	 av2_dst = n3ddistance(lav2, v2);
	
	 v1_hit = (av1_dst <= close_to_zero); //tells if point lies on edge
	 v2_hit = (av2_dst <= close_to_zero); //tells if point lies on edge
		
		if (v1_hit) pvi = 0;
		if (v2_hit) pvi = 1;
		bool shared_vertex = (getV(pvi) == in->getV(invi));
		


	if ( ((v1_hit) || (v2_hit)) && (!shared_vertex) ) return true;
		
		return false;
}




bool SharesVertexWith(TEdge * e)
{
	if (v1 == e->v1) return true;
	if (v1 == e->v2) return true;
	if (v2 == e->v1) return true;
	if (v2 == e->v2) return true;
	
	return false;
}
	/*
	  * Returns a linked list of edges created by a split
	  * there are few kinds of split:
	  * - edge has one point on clipped edge
	  * - edge has two points on clipped edge where
	  * - one vertex or two vertices can be shared
	  *   if two are shared then we remove both edges
	  * - if two point are on clip edge and none is shared
	  *   then we create proper edges
	  * Important note delete checked edges cause it will return new proper edges (for the own thought algo)
	  */
	TEdge * ClipEdgeWith(TEdge * in) //if id matches then theres no remove otherwise we remove both
	{
		
	if ( SameEdge(in) ) return 0; //indicates this and in removal
	
		
	vec3 lav1 = ClosestPointOnLine (v1, v2, in->v1);
	vec3 lav2 = ClosestPointOnLine (v1, v2, in->v2);
	float av1_dst = n3ddistance(lav1, in->v1);
	float av2_dst = n3ddistance(lav2, in->v2);
	
	bool v1_hit = (av1_dst <= close_to_zero); //tells if point lies on edge
	bool v2_hit = (av2_dst <= close_to_zero); //tells if point lies on edge
		
		if ((!v1_hit) && (!v2_hit)) return this;
		
	bool both_hits = (v1_hit && v2_hit);
	
	if (!both_hits)
	{
		int pvi, invi;
		bool overlaps = overlaps_with(in, pvi, invi);
		vec3 point_hit = lav1;
		if (v2_hit) point_hit = lav2;
		
		//no removal condition - if we share a vertex only by touching it
		if ( (point_hit == v1) || (point_hit == v2)  ) return this; //in other function we check if ids match then we know that we have returned from here, 
		/* ***** nope ******
		//now check whenever other point lies on edge line
		//there are two conditions here one is that other edge doesnt overlap but only touches edge with vertex and else
		*/
		
	if (overlaps) //actually for the whole algo to work there must be a condition when there are no two hits but only one which is checked with if(!both_hits)
	{
		vec3 ptmp1 = getV( other_vertex( pvi ) );
		vec3 ptmp2 = in->getV( invi );
		
		vec3 intmp1 = getV( pvi );
		vec3 intmp2 = in->getV( in->other_vertex( invi ) );
		
		TEdge * e1 = new TEdge(ptmp1, ptmp2, n, d);
		TEdge * e2 = new TEdge(intmp1, intmp2, in->n, in->d); //do przemyslenia
		e1->next = e2;
		e2->prev = e1;
		return e1;
		
	} else //does not overlap but only touches middle
	{
		if (!SharesVertexWith(in))
		{
		TEdge * e1 = new TEdge(v1, point_hit, n, d);
		TEdge * e2 = new TEdge(point_hit, v2, n, d);
		TEdge * e3 = new TEdge( in );
		e1->next = e2;
		e2->prev = e1;
		e2->next = e3;
		e3->prev = e2;


		return e1;
		} else
		{
			
		TEdge * e1 = new TEdge(this);
		TEdge * e2 = new TEdge(in);


		e1->next = e2;
		e2->prev = e1;




		return e1;			
		}
		
	}
	}
	
	if (both_hits)
	{
		bool v1_shared_v1 = (in->v1 == v1);
		bool v1_shared_v2 = (in->v2 == v1);
		
		bool v2_shared_v1 = (in->v1 == v2);
		bool v2_shared_v2 = (in->v2 == v2);
		//say we begin from v1
		
	if ( v1_shared_v1 || v1_shared_v2 || v2_shared_v1 || v2_shared_v2 )
	{
		vec3 closest; vec3 furthest;
		if (v1_shared_v1)
		{
		closest = v2;
		furthest = in->v2;
		}
		
		if (v1_shared_v2)
		{
		closest = v2;
		furthest = in->v1;
		}
		
		if (v2_shared_v1)
		{
		closest = v1;
		furthest = in->v2;
		}
		
		if (v2_shared_v2)
		{
		closest = v1;
		furthest = in->v1;
		}
		TEdge * ne = new TEdge(closest, furthest, n, d);
		return ne;
	} else //somewhere in between
	{
		//first vertex that is closest to v1
		//then create new two edges (actually modify these two so less memory twist is done)
		float dstinv1 = n3ddistance(v1, in->v1);
		float dstinv2 = n3ddistance(v1, in->v2);
				int closestvi = 0;
				if (dstinv2 < dstinv1) closestvi = 1;
				int furthestvi = other_vertex( closestvi );
				
				vec3 tmpv1 = v1;
				vec3 tmpv2 = in->getV( closestvi );
				
				vec3 tmpinv1 = in->getV( furthestvi );
				vec3 tmpinv2 = v2;
				
			/*	v1 = tmpv1;
				v2 = tmpv2;
				
				in->v1 = tmpinv1;
				in->v2 = tmpinv2;*/
		TEdge * e1 = new TEdge(tmpv1, tmpv2, n, d);
		TEdge * e2 = new TEdge(tmpinv1, tmpinv2, n, d);
		e1->next = e2;
		e2->prev = e1;
		return e1;
	}
	}
	


return this;
	}
	
		
		
TEdge * getLastEdge()
{
	TEdge * p = this;
	
	while ( p != 0 )
	{
		if (p->next == 0) return p;
		p = p->next;
	}
	
	return this;
}


TEdge * getFirstEdge()
{
	TEdge * p = this;
	while (p!=0)
	{
		if (p->prev == 0) return p;
		p = p->prev;
	}
return 0;
}




int Connection2V2Count(TEdge * from)
{
	int cnt = 0;
		TEdge * p = 0;
	if (from == 0) p = this->next;
	else p = from;
	
	while (p!=0)
	{
		if (this->id == p->id) { p = p->next; continue; }
		if  (v2 == p->v2) //swap vertices to perserve continous extrusion along outline
		{
			vec3 tmp = p->v1;
			p->v1 = p->v2;
			p->v2 = tmp;
		}
		
		if (v2 == p->v1)
		{
			cnt = cnt + 1;
		}
		
		p = p->next;
	}
	
	return cnt;
}


TEdge * FindNextConnected(TEdge * from) //find connected to v2
{
	TEdge * p = 0;
	if (from == 0) p = this->next;
	else p = from;
	
	while (p!=0)
	{
		if (this->id == p->id) { p = p->next; continue; }
		if  (v2 == p->v2) //swap vertices to perserve continous extrusion along outline
		{
			vec3 tmp = p->v1;
			p->v1 = p->v2;
			p->v2 = tmp;
		}
		
		if (v2 == p->v1) return p;
		
		p = p->next;
	}
	
	return 0;
}


};


typedef TEdge * TEdgeP;


inline TEdge * FindNextFreeEdge(TEdge * first)
{
	TEdge * p = first;
	while (p != 0)
	{
		if (!p->processed) return p;
		p = p->next;
	}
	return 0;
}


inline std::vector<TEdgeP> * FindEdgesThatShare( vec3 point, TEdge * first_obj)
{
	std::vector<TEdgeP> * vec = new std::vector<TEdgeP>();
	
	TEdge * p = first_obj;


	while (p!=0)
	{
		if ( (point == p->v1) || (point == p->v2) ) //add edge to list
		vec->push_back(p);
		
		p = p->next;
	}
	return vec;
}
		






template <class T> void RemoveLinkedElement(T *pa, T *& first_object)
{
T * p = pa;
if (p == 0) return;




if (p->prev == 0) //deleting first object
{
if (p->next != 0) p->next->prev = 0;
first_object = p->next;
delete p;
return;


}




if ( (p->prev != 0) && (p->next == 0) )      //last
p->prev->next = 0;




if ( (p->prev != 0) && (p->next != 0) ) //middle
{
p->prev->next = p->next;
p->next->prev = p->prev;
}








delete p;
}








template <class T> void RemoveLinkedListF(T *& first_object)
{
	
T * p = first_object;


if (p == 0) return;


while (p!=0)
{
	T*tmp=p;
	p = p->next;
	delete tmp;
}
first_object = 0;
}








template <class T> class TPolygon {
public:
 TPolygon<T> * next;
 
TEdge * toEdges()
{
	TEdgeP * p = new TEdgeP[Count];
	for (int i=0; i < Count; i++)
	{
	int vi = i;
	int next = vi+1;
	if (next >= Count) next = 0;
	
	p[i] = new TEdge(V[vi], V[next], SIDE_PLANES[i].n, 0.0);
//	ALOG("EDGE: "+vec3tostr(V[vi])+"  "+vec3tostr(V[next]));
	if (i > 0)
	{
	p[i-1]->next = p[i];
	p[i]->prev = p[i-1];
	}
	}


	return p[0];
}


TEdge edge(int i)
{
	int vi = i;
	int next = vi+1;
	if (next >= Count) next = 0;
	if (vi >= Count) { vi = 0; next = 1; }
	return TEdge(V[vi], V[next]);
}


	TPlane<T> plane;
int algined;
int	Count;
t3dpoint<T>	normal;
T distance;
t3dpoint<T>	V			[TPolygon_dim];
//vec2 t[TPolygon_dim];
//vec2 vt 	[TPolygon_dim];
TPlane<T> SIDE_PLANES	[TPolygon_dim];
//int 				FLAG		[TPolygon_dim];
TPolygon<T> * print_set;


bool isClockWise;
vec3 min;
vec3 max;




TPolygon<T>()
		{
//V = new t3dpoint<T>[TPolygon_dim];
//SIDE_PLANES = new TPlane<T>[TPolygon_dim];
//FLAG = new int[TPolygon_dim];
			
				
						print_set = 0;
			next = 0;
	algined = 0;//aligned?
	Count = 0;
//	for (int i = 0; i < TPolygon_dim; i++) FLAG[i] = 0;
		}


~TPolygon<T>()
{
	if (print_set != 0)
	delete [] print_set;


/*
	delete [] V;
	delete [] SIDE_PLANES;
	delete [] FLAG;*/
}










void GetMinMax()
{
	min = vec3(99999.999, 99999.999, 99999.999);
	max = vec3(-99999.999, -99999.999, -99999.999);
	
	for (int i=0; i < Count; i++)
	{
		if (min.x > V[i].x) min.x = V[i].x;
		if (min.y > V[i].y) min.y = V[i].y;
		if (min.z > V[i].z) min.z = V[i].z;
		
		if (max.x < V[i].x) max.x = V[i].x;
		if (max.y < V[i].y) max.y = V[i].y;
		if (max.z < V[i].z) max.z = V[i].z;	
	}
	
}


void DiscardDuplicatedVertices()
{
		for (int i=0; i<Count; i++)
		{
				bool found = true;
	while (found)
	{
		found = false;
		


		
			for (int j=0; j<Count; j++)
			if ( i != j )
			if (V[i] == V[j])
			{
//ALOG("FOUND "+vec3tostr(V[i])+" with "+vec3tostr(V[j]));
//ALOG(IntToStr(i)+"  "+IntToStr(j));
Delete(j);
			
				found = true;
				break;
			}


		
		}
	}
	


//	ALOG("Discarded "+IntToStr(newc)+" verts");
}
// 3, 23, 3, 55, 12, 2, 3


// index: 2 num 3
//3=55, 55 = 12, 12 = 2
void Delete(int indexa)
{
	if (indexa < 0) return;
	if (indexa > Count-1) return;
//for (int bb=0; bb < Count; bb++)
//	ALOG(vec3tostr(V[bb]));
	
for (int bb=indexa; bb < Count-1; bb++)
{
//	ALOG(vec3tostr(V[bb])+"   changed to  "+vec3tostr(V[bb+1]));
V[bb] = V[bb+1];
}
		Count =  Count - 1;
		if (Count < 0) Count = 0;
}


/* make either clockwise or counterclockwise */
void Transpose()
{
	t3dpoint<T> vv[128];
	
for (int i=0; i < Count; i++) vv[  i  ] = V[(Count-1) - i  ];
for (int i=0; i < Count; i++) V[  i  ] = vv[  i  ];
	
	CalcPlane();
}


void CalcPlane()
{
plane.calc_plane(V[0], V[1], V[2], false);
normal    = plane.n;
distance = plane.D;




isClockWise = IsTriClockwise(V[0], V[1], V[2]);
}






void Clear()
{
	Count = 0;
}


void AddVertex(t3dpoint<T> p)
{
	V[Count] = p;
Count = Count + 1;
}








TPolygon<T> & operator=(const TPolygon<T>& in)
{
Count = in.Count;
algined = in.algined;
	distance 		= in.distance;
	normal 			= in.normal;
plane = in.plane;
for (int i=0; i < in.Count; i++)
{
	V[i] 			= in.V[i];
	SIDE_PLANES[i] 	= in.SIDE_PLANES[i];
//	FLAG[i]			= in.FLAG[i];
}


	if (print_set != 0)
	{
	delete [] print_set;
	print_set = 0;
	}
	
if (in.print_set != 0)
{
	print_set = new TPolygon<T>[in.Count];
	for (int i=0; i < Count; i++)
	print_set[i] = in.print_set[i];
} else print_set = 0;
	return *this;
}






void CopyVerticesFrom(TPolygon<T> in)
{
	Count = in.Count;


	for (int i=0; i < Count; i++)
		V[i] 			= in.V[i];
}




t3dpoint<T> getCenterPoint()
		{
	t3dpoint<T> res = t3dpoint<T>(T(0.0), T(0.0), T(0.0));
	for (int i=0; i < Count; i++)
		res = res + V[i];


	return res / T(Count);
		}


/*
void FaceSidePlanes(int face_side) //defines where center point is situated, dont use isOnPlane its retarded
{
	t3dpoint<T> cp = getCenterPoint();
	
	if (classifyapointagainstaplane
}
*/


/*
  * test if its attached but not overlapping!
  * whenever a point from one poly lies on plane
  * and its behind or on plane for the rest of planes (is inside polygon)
  */
bool isAttached( TPolygon<T> to )
{
	bool result = false;
	//if test fails then we check 'to' poly against this one if that fails too then it is not attached
	for (int i=0; i < Count; i++)
	if (to.isPointOnSide(V[i]) > -1)
	{
		result = true;
	if (!to.isPointInside(V[i])) result = false;
	if (result) return true;
	}


	//now if still false we need to check against 'this'
	for (int i=0; i < to.Count; i++)
	if (isPointOnSide(to.V[i]) > -1)
	{
		result = true;
	if (!isPointInside(to.V[i])) result = false;
	if (result) return true;
	}
	
	return result;
}




void  MakeSidePlanes() //face planes are set to face outwards
{


t3dpoint<T> pop;
t3dpoint<T> A;
t3dpoint<T> B;
t3dpoint<T> tA;
t3dpoint<T> tB;
t3dpoint<T> tC;
t3dpoint<T> n;


pop = V[0];


A = vectorAB(V[0],V[1]);
B = vectorAB(V[0],V[Count - 1]);
n = Normalize(A * B);








for (int i=0; i < Count; i++)
{
tA = V[i];


if (i == Count-1) tB = V[0];
else tB = V[i+1];


tC = tA + (n*1000.0);


SIDE_PLANES[i].calc_plane(tA, tB, tC, false );




}
//make sure side planes always face outside convex polyhedra
vec3 cp = getCenterPoint();
for (int i=0; i < Count; i++)
	if ( SIDE_PLANES[i].ClassifyPoint(cp, 0.001) == isFront ) SIDE_PLANES[i].Negate();


}


//Accepts points on planes
bool isPointInside(vec3 ppoint)
{
	for (int i=0; i < Count; i++) //oryginalnie bylo 0.001
	if ( SIDE_PLANES[i].ClassifyPoint(ppoint, 0.001) == isFront ) return false;


	return true;
}


//if false then returns -1 else returns side index
int isPointOnSide(vec3 ppoint)
{
	for (int i=0; i < Count; i++)
	if ( SIDE_PLANES[i].ClassifyPoint(ppoint, 0.001) == isOnPlane ) return i;


	return -1;
}




//damn stupid you you already have a boundary definition set...
void CreatePrintSet()
{
	MakeSidePlanes();
	
	if (print_set != 0)
	{
	delete [] print_set;
	print_set = 0;
	}
	
	print_set = new TPolygon<T>[Count];
	//crap i already can define boundary set so wont finish it
	
}




};


typedef TPolygon<float> * poly3fp;
typedef TPolygon<float> poly3f;


then actual code for outline generation




//now we should check which are connected sets
std::vector< poly3f_listp* > * conn_list =
CreateAttachmentList(modelset, model_count);


int separated_object_count = int ( (*conn_list).size() );


CAN_LOG=true;
TEdgeP * edge_list = 0;
std::vector<TEdge*> outline_list;
//ALOG("SEP COUNT: "+IntToStr(separated_object_count));
if (ps.outline) //having edges of each object we compose an outline of it
{
//create and copy data to internal structure
edge_list = new TEdgeP[ separated_object_count ];
for (int soc=0; soc < separated_object_count; soc++)
edge_list[soc] = 0;


for (int soc=0; soc < separated_object_count; soc++)
{
	int obj_len = int ( (*(*conn_list)[soc]).size());
//ALOG("LIST CONNECTIONS: "+IntToStr(obj_len));
for (int n=0; n < obj_len; n++) //through all connected objects
{


	TEdge * edges =  (*(*conn_list)[soc])[n]->toEdges();


	if ( edge_list[soc] == 0)
	edge_list[soc] = edges;
	else
	{


		TEdge * last_edge = edge_list[soc]->getLastEdge();
		if (last_edge != 0)
		last_edge->next = edges;
		if (edges != 0)
		edges->prev = last_edge;
	}
}
}




//reassign pids and complete linked list for further processing
for (int i=0; i < separated_object_count; i++)
{
	int edge_id = 0;
TEdge * pid = edge_list[i];
while (pid!=0)
{
	edge_id = edge_id + 1;
	pid->id = edge_id;
	if (pid->next != 0) pid->next->prev = pid; //??


	pid = pid->next;
}


}


//having edges of each object we compose an outline of it


for (int i=0; i < separated_object_count; i++)
{
bool all_outlines_processed = false;
bool break_here = false;
while (!all_outlines_processed)
{


	break_here = false;


	int edge_id = 0;
TEdge * pid = edge_list[i];
//ALOG("REASSIGN PIDS");
while (pid!=0) //need to reassign pids
{
//		ALOG("EDGE: "+vec3tostr(pid->v1)+"  "+vec3tostr(pid->v2));


	edge_id = edge_id + 1;
	pid->id = edge_id;
	if (pid->next != 0) pid->next->prev = pid;
	pid = pid->next;
}


pid = edge_list[i];
while (pid!=0)
{
//ALOG("WHILE P");
	TEdge * p2 = edge_list[i];
	while (p2!=0)
	{


//ALOG("WHILE P2");
		if (p2->id == pid->id) {  break_here = false;   p2 = p2->next; continue; }


	TEdge * ne = pid->ClipEdgeWith(p2);






	//p->ids are different this indicates cut
break_here = true;
	if (ne == 0) //here we remove p and p2
	{
		
	RemoveLinkedElement(pid, edge_list[i]);
	RemoveLinkedElement(p2, edge_list[i]);


	break;


	}
	//if returned this
	if (ne->id == pid->id)  { break_here = false;  p2 = p2->next; continue; }
	


			RemoveLinkedElement(pid, edge_list[i]);
			RemoveLinkedElement(p2, edge_list[i]);
//ALOG("REM: "+vec3tostr(pid->v1)+"   "+vec3tostr(pid->v2));
//ALOG("REM: "+vec3tostr(p2->v1)+"   "+vec3tostr(p2->v2));
/*
TEdge * xc = ne;
while (xc != 0)
{
	ALOG("Create "+vec3tostr(xc->v1)+"   "+vec3tostr(xc->v2));
	xc = xc->next;
}*/
TEdge * last_edge = edge_list[i]->getLastEdge();
last_edge->next = ne;
ne->prev = last_edge;




		if (break_here) break;
		p2 = p2->next;
	}
	if (break_here) break;


	pid = pid->next;
}
	if (!break_here) all_outlines_processed = true;
}//while !all_outlines_processed


}






//ALOG("4");


// After finding an outline we should first sort connected edges
// then we need to offset them by extrusion_width / 2.0 towards solid
//But first renew ids and fix two way linked list
for (int i=0; i < separated_object_count; i++)
{


	TEdge * pid = edge_list[i];
while (pid!=0)
{
	pid->prev = 0;


	pid = pid->next;
}
	int edge_id = 0;
pid = edge_list[i];


while (pid!=0)
{
	edge_id = edge_id + 1;
	pid->id = edge_id;
	pid->processed = false;
//	ALOG("EDGE: "+vec3tostr(pid->v1)+"  "+vec3tostr(pid->v2));


	if (pid->next != 0) pid->next->prev = pid;
	pid = pid->next;
	
}
}


// *Now sort:


for (int i=0; i < separated_object_count; i++)
{


bool all_preprocessed = false;
bool loop_processed = false;
while (!all_preprocessed)
{
	
TEdge * first = FindNextFreeEdge( edge_list[i] );
//if (first !=0)
//	ALOG("first "+vec3tostr(first->v1)+"  "+vec3tostr(first->v2));


TEdge * loop_first = first;
if (first == 0) { all_preprocessed = true; break; }




TEdge * pfirst = new TEdge( first ); // edge_list[i] );
loop_processed = false;
while (!loop_processed)
{


	TEdge * nec = first->FindNextConnected( edge_list[i] );
	int cnta = LOGConnection2V2Count( first, edge_list[i] );
//	if (cnta > 1) ALOG("MORE THAN ONE CONNECTION "+IntToStr(cnta));
	if (nec == 0) { loop_processed = true;     all_preprocessed = true;   break; }
	if (nec->id == loop_first->id)
	{
//ALOG("FOUND ITSELF BREAK");
		outline_list.push_back( pfirst->getFirstEdge() );
	 loop_processed = true;


	   break;


	 }
	else
	{
		TEdge * new_edge = new TEdge( nec );
//			ALOG("adding ce "+vec3tostr(new_edge->v1)+"  "+vec3tostr(new_edge->v2));


		new_edge->prev = pfirst;
		pfirst->next = new_edge;
		
		pfirst = new_edge;
		first->processed = true;
		nec->processed = true;
		first = nec;
	
	}
}
}
}


int outline_count =  int (outline_list.size());
//Now.offset outline polygon (doing that before sort would render algo above useless => no continous outline)
float outline_offset = ps.extrusion_width / 2.0;
/*
for (int i=0; i < outline_count; i++)
{
	TEdge * pid = outline_list[i];


	while (pid!=0)
	{
ALOG("V1: "+ vec3tostr(pid->v1)+"  V2: "+ vec3tostr(pid->v2)+" n:"+vec3tostr(pid->n));
pid = pid->next;
	}
}*/
for (int i=0; i < outline_count; i++)
{
	TEdge * pid = outline_list[i];
	int p_id = 0;
	while (pid!=0)
	{
		p_id = p_id + 1;
		pid->id = p_id;
		pid->processed = false;


		TEdge * next_edge = pid->next;
		if (next_edge == 0) next_edge = outline_list[i];
		
		vec3 offset_vec = -Normalize( (pid->n*100.0 + next_edge->n*100.0) / 2.0 );
		
		pid->v2 = pid->v2 + offset_vec * outline_offset;
		next_edge->v1 = next_edge->v1 + offset_vec * outline_offset;
				
		
		pid = pid->next;
	}


}


//ALOG("7");


for (int soc=0; soc < outline_count; soc++)
{
TEdge * ep = outline_list[soc];


while (ep!=0)
{
vec3 epv1 = vec3(ep->v1.x, layer_h, ep->v1.z);
vec3 epv2 = vec3(ep->v2.x, layer_h, ep->v2.z);




		  MoveHotEnd(epv1, 0.0, ps);
		  float gE = getExtrusionLength2(vectorAB(epv1, epv2), ps.extrusion_width, ps.filament_width);
	 
		  if (ps.cubic_extrusion)
	  	gE = getExtrusionLength(vectorAB(epv1, epv2), ps.extrusion_width, ps.filament_width, ps.layer_height);
	  //	ALOG("gE: "+FloatToStr(gE));
	  	MoveHotEnd(epv2, gE, ps);


	ep = ep->next;
}
}


outline_list.clear();
}



This topic is closed to new replies.

Advertisement