Those are plain vertices, working on algo.
Find the outline points of an object
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();
}
Master & Mentor
https://sites.google.com/site/customprog/
https://sites.google.com/site/customprog/
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement