42 namespace AlignmentSubsystem
58 std::cerr <<
"AddOne: starting to add v" << p->
vnum <<
".\n";
68 std::cerr <<
"faddr: " << std::hex << f <<
" paddr: " << p <<
" Vol = " <<
std::dec << vol <<
'\n';
115 for (i = 0; i < 3; ++i)
122 std::cerr <<
"CheckEndpts: Error!\n";
123 std::cerr <<
" addr: " << std::hex <<
faces <<
':';
124 std::cerr <<
" edges:";
131 while (
faces != fstart);
134 std::cerr <<
"Checks: ERROR found and reported above.\n";
136 std::cerr <<
"Checks: All endpts of all edges of all faces check.\n";
142 std::cerr <<
"Checks: V, E, F = " << V <<
' ' << E <<
' ' << F <<
":\t";
144 if ((V - E + F) != 2)
145 std::cerr <<
"Checks: V-E+F != 2\n";
147 std::cerr <<
"V-E+F = 2\t";
149 if (F != (2 * V - 4))
150 std::cerr <<
"Checks: F=" << F <<
" != 2V-4=" << 2 * V - 4 <<
"; V=" << V <<
'\n';
152 std::cerr <<
"F = 2V-4\t";
154 if ((2 * E) != (3 * F))
155 std::cerr <<
"Checks: 2E=" << 2 * E <<
" != 3F=" << 3 * F <<
"; E=" << E <<
", F=" << F <<
'\n';
157 std::cerr <<
"2E = 3F\n";
165 int V = 0, E = 0, F = 0;
178 if ((e =
edges) !=
nullptr)
185 if ((f =
faces) !=
nullptr)
222 remove<tEdge>(
edges, e);
231 remove<tEdge>(
edges, t);
247 remove<tFace>(
faces, f);
256 remove<tFace>(
faces, t);
324 return (c->
v[
Z] - a->
v[
Z]) * (b->
v[
Y] - a->
v[
Y]) - (b->
v[
Z] - a->
v[
Z]) * (c->
v[
Y] - a->
v[
Y]) == 0 &&
325 (b->
v[
Z] - a->
v[
Z]) * (c->
v[
X] - a->
v[
X]) - (b->
v[
X] - a->
v[
X]) * (c->
v[
Z] - a->
v[
Z]) == 0 &&
326 (b->
v[
X] - a->
v[
X]) * (c->
v[
Y] - a->
v[
Y]) - (b->
v[
Y] - a->
v[
Y]) * (c->
v[
X] - a->
v[
X]) == 0;
355 std::cerr <<
"Checks: edges are NOT consistent.\n";
357 std::cerr <<
"Checks: edges consistent.\n";
376 std::cerr <<
"ConstructHull: After Add of " << v->
vnum <<
" & Cleanup:\n";
416 std::cerr <<
"Checks: NOT convex.\n";
418 std::cerr <<
"Checks: convex.\n";
424 tFace f0, f1 =
nullptr;
432 std::cerr <<
"DoubleTriangle: All points are Collinear!" << std::endl;
460 if ((v3 = v3->
next) == v0)
462 std::cerr <<
"DoubleTriangle: All points are coplanar!" << std::endl;
481 for (i = 0; i < 3; i++)
487 for (j = 0; j < 3; j++)
496 std::cerr <<
"Making a swap in EdgeOrderOnFaces: F(" << f->
vertex[0]->
vnum <<
','
499 newEdge = f->
edge[i];
501 f->
edge[j] = newEdge;
536 swap<tEdge>(s, f->
edge[1], f->
edge[2]);
552 for (i = 0; i < 2; ++i)
559 new_edge[i]->
endpts[1] = p;
565 new_face->
edge[0] = e;
566 new_face->
edge[1] = new_edge[0];
567 new_face->
edge[2] = new_edge[1];
571 for (i = 0; i < 2; ++i)
572 for (j = 0; j < 2; ++j)
574 if (!new_edge[i]->adjface[j])
576 new_edge[i]->
adjface[j] = new_face;
628 v->
v[
X] = x * ScaleFactor;
629 v->
v[
Y] = y * ScaleFactor;
630 v->
v[
Z] = z * ScaleFactor;
632 if ((std::abs(x) >
SAFE) || (std::abs(y) >
SAFE) || (std::abs(z) >
SAFE))
634 std::cout <<
"Coordinate of vertex below might be too large: run with -d flag\n";
647 add<tEdge>(
edges, e);
656 for (
int i = 0; i < 3; ++i)
658 f->
edge[i] =
nullptr;
662 add<tFace>(
faces, f);
685 int xmin, ymin, xmax, ymax;
688 int V = 0, E = 0, F = 0;
693 xmin = xmax = v->
v[
X];
698 else if (v->
v[
X] < xmin)
706 ymin = ymax = v->
v[
Y];
711 else if (v->
v[
Y] < ymin)
718 std::cout <<
"%!PS\n";
719 std::cout <<
"%%BoundingBox: " << xmin <<
' ' << ymin <<
' ' << xmax <<
' ' << ymax <<
'\n';
720 std::cout <<
".00 .00 setlinewidth\n";
721 std::cout << -xmin + 72 <<
' ' << -ymin + 72 <<
" translate\n";
733 std::cout <<
"\n%% Vertices:\tV = " << V <<
'\n';
734 std::cout <<
"%% index:\t\tx\ty\tz\n";
737 std::cout <<
"%% " << v->
vnum <<
":\t" << v->
v[
X] <<
'\t' << v->
v[
Y] <<
'\t' << v->
v[
Z] <<
'\n';
751 std::cout <<
"\n%% Faces:\tF = " << F <<
'\n';
752 std::cout <<
"%% Visible faces only: \n";
760 if ((a[0] * b[1] - a[1] * b[0]) >= 0)
764 std::cout <<
"newpath\n";
765 std::cout << f->
vertex[0]->
v[
X] <<
'\t' << f->
vertex[0]->
v[
Y] <<
"\tmoveto\n";
766 std::cout << f->
vertex[1]->
v[
X] <<
'\t' << f->
vertex[1]->
v[
Y] <<
"\tlineto\n";
767 std::cout << f->
vertex[2]->
v[
X] <<
'\t' << f->
vertex[2]->
v[
Y] <<
"\tlineto\n";
768 std::cout <<
"closepath stroke\n\n";
775 std::cout <<
"%% List of all faces: \n";
776 std::cout <<
"%%\tv0\tv1\tv2\t(vertex indices)\n";
792 std::cout <<
"\n%% Edges:\tE = " << E <<
'\n';
795 std::cout <<
"\nshowpage\n\n";
807 Ofile <<
"Edge List\n";
811 Ofile <<
" addr: " << std::hex <<
edges <<
'\t';
813 for (i = 0; i < 2; ++i)
816 for (i = 0; i < 2; ++i)
821 while (
edges != temp);
830 Ofile <<
"Face List\n";
834 Ofile <<
" addr: " << std::hex <<
faces <<
" ";
835 Ofile <<
" edges:" << std::hex;
836 for (i = 0; i < 3; ++i)
839 for (i = 0; i < 3; ++i)
844 while (
faces != temp);
851 std::map<int, int> vnumToOffsetMap;
856 Ofile.open(FileName, std::ios_base::out | std::ios_base::trunc);
858 Ofile <<
"# obj file written by chull\n";
859 Ofile <<
"mtllib chull.mtl\n";
860 Ofile <<
"g Object001\n";
862 Ofile <<
"usemtl default\n";
871 vnumToOffsetMap[v->
vnum] = Offset;
872 Ofile <<
"v " << v->
v[
X] <<
' ' << v->
v[
Y] <<
' ' << v->
v[
Z] <<
'\n';
887 c[0] = a[1] * b[2] - a[2] * b[1];
888 c[1] = a[2] * b[0] - a[0] * b[2];
889 c[2] = a[0] * b[1] - a[1] * b[0];
891 length = sqrt((c[0] * c[0]) + (c[1] * c[1]) + (c[2] * c[2]));
892 c[0] = c[0] / length;
893 c[1] = c[1] / length;
894 c[2] = c[2] / length;
895 Ofile <<
"vn " << c[0] <<
' ' << c[1] <<
' ' << c[2] <<
'\n';
905 Ofile <<
"f " << vnumToOffsetMap[f->
vertex[0]->
vnum] <<
"//" << i <<
' ' << vnumToOffsetMap[f->
vertex[1]->
vnum]
906 <<
"//" << i <<
' ' << vnumToOffsetMap[f->
vertex[2]->
vnum] <<
"//" << i <<
'\n';
914 Ofile.open(
"chull.mtl", std::ios_base::out | std::ios_base::trunc);
916 Ofile <<
"newmtl default\n";
917 Ofile <<
"Ka 0.2 0 0\n";
918 Ofile <<
"Kd 0.8 0 0\n";
919 Ofile <<
"illum 1\n";
927 Ofile.open(FileName, std::ios_base::out | std::ios_base::trunc);
929 Ofile <<
"\nHead vertex " << v->
vnum <<
" = " << std::hex << v <<
" :\n";
940 for (
int i = 0; i < 3; i++)
941 std::cout <<
'\t' << p->
v[i];
951 Ofile <<
"Vertex List\n";
955 Ofile <<
" addr " << std::hex <<
vertices <<
"\t";
972 while (!(std::cin.eof() || std::cin.fail()))
974 std::cin >> x >> y >> z;
980 if ((abs(x) >
SAFE) || (abs(y) >
SAFE) || (abs(z) >
SAFE))
982 std::cout <<
"Coordinate of vertex below might be too large: run with -d flag\n";
994 if (
nullptr != CurrentVertex)
998 tVertex TempVertex = CurrentVertex;
999 CurrentVertex = CurrentVertex->
next;
1006 if (
nullptr != CurrentEdge)
1010 tEdge TempEdge = CurrentEdge;
1011 CurrentEdge = CurrentEdge->
next;
1014 while (CurrentEdge !=
edges);
1018 if (
nullptr != CurrentFace)
1022 tFace TempFace = CurrentFace;
1023 CurrentFace = CurrentFace->
next;
1026 while (CurrentFace !=
faces);
1038 for (i = 0; i < 3; i++)
1046 int ax, ay, az, bx, by, bz, cx, cy, cz;
1058 vol = (ax * (by * cz - bz * cy) + ay * (bz * cx - bx * cz) + az * (bx * cy - by * cx));
1067 double ax, ay, az, bx, by, bz, cx, cy, cz;
1079 vol = ax * (by * cz - bz * cy) + ay * (bz * cx - bx * cz) + az * (bx * cy - by * cx);
1085 std::cerr <<
"Face=" << std::hex << f <<
"; Vertex=" <<
std::dec << p->
vnum <<
": vol(int) = " << voli
1086 <<
", vol(double) = " << vol <<
"\n";
1092 else if (vol < -0.5)
void Checks()
Checks the consistency of the hull and prints the results to the standard error output.
void ReadVertices()
ReadVertices: Reads in the vertices, and links them into a circular list with MakeNullVertex....
static const bool REMOVED
struct tEdgeStructure tsEdge
void CleanUp(tVertex *pvnext)
CleanUp goes through each data structure list and clears all flags and NULLs out some pointers....
tFace MakeNullFace()
MakeNullFace creates a new face structure and initializes all of its flags to NULL and sets all the f...
void EdgeOrderOnFaces()
EdgeOrderOnFaces: puts e0 between v0 and v1, e1 between v1 and v2, e2 between v2 and v0 on each face....
void Reset()
Frees the vertices edges and faces lists and resets the debug and check flags.
static const bool VISIBLE
void PrintPoint(tVertex p)
Prints a single vertex to the standard output.
void Convexity()
Convexity checks that the volume between every face and every point is negative. This shows that each...
struct tFaceStructure tsFace
void Consistency()
Consistency runs through the edge list and checks that all adjacent faces have their endpoints in opp...
tFace MakeFace(tVertex v0, tVertex v1, tVertex v2, tFace f)
MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the...
bool AddOne(tVertex p)
AddOne is passed a vertex. It first determines all faces visible from that point. If none are visible...
void MakeNewVertex(double x, double y, double z, int VertexId)
Makes a vertex from the supplied information and adds it to the vertices list.
struct tVertexStructure tsVertex
void CheckEndpts()
Checks that, for each face, for each i={0,1,2}, the [i]th vertex of that face is either the [0]th or ...
void PrintVertices(std::ofstream &Ofile)
Prints vertices to Ofile.
void CheckEuler(int V, int E, int F)
CheckEuler checks Euler's relation, as well as its implications when all faces are known to be triang...
void CleanVertices(tVertex *pvnext)
CleanVertices runs through the vertex list and deletes the vertices that are marked as processed but ...
bool Collinear(tVertex a, tVertex b, tVertex c)
Collinear checks to see if the three points given are collinear, by checking to see if each element o...
void PrintOut(const char *FileName, tVertex v)
Prints vertices, edges and faces to the standard error output.
int Volumei(tFace f, tVertex p)
Volumei returns the volume of the tetrahedron determined by f and p.
bool DoubleTriangle()
DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two...
void MakeCcw(tFace f, tEdge e, tVertex p)
MakeCcw puts the vertices in the face structure in counterclock wise order. We want to store the vert...
void CleanEdges()
CleanEdges runs through the edge list and cleans up the structure. If there is a newface then it will...
static const bool PROCESSED
void ConstructHull()
ConstructHull adds the vertices to the hull one at a time. The hull vertices are those in the list ma...
int VolumeSign(tFace f, tVertex p)
VolumeSign returns the sign of the volume of the tetrahedron determined by f and p....
tVertex MakeNullVertex()
MakeNullVertex: Makes a vertex, nulls out fields.
void PrintEdges(std::ofstream &Ofile)
Prints the edges Ofile.
void PrintObj(const char *FileName="chull.obj")
Outputs the faces in Lightwave obj format for 3d viewing. The files chull.obj and chull....
void Print()
Print: Prints out the vertices and the faces. Uses the vnum indices corresponding to the order in whi...
void SubVec(int a[3], int b[3], int c[3])
SubVec: Computes a - b and puts it into c.
tFace MakeConeFace(tEdge e, tVertex p)
MakeConeFace makes a new face and two new edges between the edge and the point that are passed to it....
void PrintFaces(std::ofstream &Ofile)
Prints the faces to Ofile.
tEdge MakeNullEdge()
MakeNullEdge creates a new cell and initializes all pointers to NULL and sets all flags to off....
void CleanFaces()
CleanFaces runs through the face list and deletes any face marked visible.
Namespace to encapsulate INDI client, drivers, and mediator classes.