Skip to content

Commit dbbb424

Browse files
author
tpat
committed
Fixed box scaling and zero normals. Using different thresholds for determining
which order of tensor to display
1 parent ce750f0 commit dbbb424

File tree

3 files changed

+252
-200
lines changed

3 files changed

+252
-200
lines changed

src/Graphics/Glyphs/GlyphGeom.cc

Lines changed: 206 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,14 @@ void GlyphGeom::addComet(const Point& p1, const Point& p2, double radius, int re
225225
generateComet(p1, p2, radius, resolution, color1, color2, sphere_extrusion);
226226
}
227227

228-
void GlyphGeom::addBox(const Point& center, Tensor& t, double scale, ColorRGB& node_color)
228+
void GlyphGeom::addBox(const Point& center, Tensor& t, double scale, ColorRGB& node_color, bool normalize)
229229
{
230-
generateBox(center, t, scale, node_color);
230+
generateBox(center, t, scale, node_color, normalize);
231231
}
232232

233-
void GlyphGeom::addEllipsoid(const Point& p, Tensor& t, int resolution, const ColorRGB& color)
233+
void GlyphGeom::addEllipsoid(const Point& p, Tensor& t, double scale, int resolution, const ColorRGB& color, bool normalize)
234234
{
235-
generateEllipsoid(p, t, resolution, color, false);
235+
generateEllipsoid(p, t, scale, resolution, color, false, normalize);
236236
}
237237

238238
void GlyphGeom::addCylinder(const Point& p1, const Point& p2, double radius, int resolution,
@@ -708,30 +708,97 @@ void GlyphGeom::generateComet(const Point& p1, const Point& p2,
708708
}
709709
}
710710

711-
void GlyphGeom::generateBox(const Point& center, Tensor& t, double scale, ColorRGB& node_color)
711+
void reorderTensor(std::vector<Vector>& eigvectors, Vector& eigvals)
712712
{
713+
if(eigvals[0] < eigvals[1])
714+
{
715+
double temp = eigvals[0];
716+
eigvals[0] = eigvals[1];
717+
eigvals[1] = temp;
718+
Vector tempVec = eigvectors[0];
719+
eigvectors[0] = eigvectors[1];
720+
eigvectors[1] = tempVec;
721+
}
722+
if(eigvals[1] < eigvals[2])
723+
{
724+
double temp = eigvals[1];
725+
eigvals[1] = eigvals[2];
726+
eigvals[2] = temp;
727+
Vector tempVec = eigvectors[1];
728+
eigvectors[1] = eigvectors[2];
729+
eigvectors[2] = tempVec;
730+
}
731+
if(eigvals[0] < eigvals[1])
732+
{
733+
double temp = eigvals[0];
734+
eigvals[0] = eigvals[1];
735+
eigvals[1] = temp;
736+
Vector tempVec = eigvectors[0];
737+
eigvectors[0] = eigvectors[1];
738+
eigvectors[1] = tempVec;
739+
}
740+
}
741+
742+
void GlyphGeom::generateBox(const Point& center, Tensor& t, double scale, ColorRGB& node_color, bool normalize)
743+
{
744+
double zeroThreshold = 0.000001;
713745
double eigval1, eigval2, eigval3;
714746
t.get_eigenvalues(eigval1, eigval2, eigval3);
715747

716-
Vector scaled_eigenvals(abs(eigval1), abs(eigval2), abs(eigval3));
717-
scaled_eigenvals *= scale;
748+
Vector eigvals(abs(eigval1), abs(eigval2), abs(eigval3));
749+
if(normalize)
750+
eigvals.normalize();
751+
eigvals *= scale;
752+
753+
std::vector<Vector> eigvectors(3);
754+
t.get_eigenvectors(eigvectors[0], eigvectors[1], eigvectors[2]);
755+
756+
// Checks to see if eigenvalues are close to 0
757+
bool eig_x_0 = eigvals.x() <= zeroThreshold;
758+
bool eig_y_0 = eigvals.y() <= zeroThreshold;
759+
bool eig_z_0 = eigvals.z() <= zeroThreshold;
760+
761+
// Set to 0 if below threshold
762+
eigvals[0] = (!eig_x_0) * eigvals[0];
763+
eigvals[1] = (!eig_y_0) * eigvals[1];
764+
eigvals[2] = (!eig_z_0) * eigvals[2];
718765

719-
Vector eigvec1, eigvec2, eigvec3;
720-
t.get_eigenvectors(eigvec1, eigvec2, eigvec3);
766+
bool flatTensor = (eig_x_0 + eig_y_0 + eig_z_0) >= 1;
767+
if(flatTensor)
768+
{
769+
reorderTensor(eigvectors, eigvals);
770+
771+
eig_x_0 = eigvals.x() <= zeroThreshold;
772+
eig_y_0 = eigvals.y() <= zeroThreshold;
773+
eig_z_0 = eigvals.z() <= zeroThreshold;
774+
// Check for zero eigenvectors
775+
if(eig_x_0)
776+
{
777+
eigvectors[0] = Cross(eigvectors[1], eigvectors[2]);
778+
}
779+
else if(eig_y_0)
780+
{
781+
eigvectors[1] = Cross(eigvectors[0], eigvectors[2]);
782+
}
783+
else if(eig_z_0)
784+
{
785+
eigvectors[2] = Cross(eigvectors[0], eigvectors[1]);
786+
}
787+
}
721788

722-
Transform rotate(Point(0.0, 0.0, 0.0), eigvec1, eigvec2, eigvec3);
789+
Transform rotate(Point(0.0, 0.0, 0.0), eigvectors[0], eigvectors[1], eigvectors[2]);
723790
Transform trans = rotate;
724791
trans.pre_translate((Vector) center);
725792

726793
// Rotate and translate points
727-
Vector p1 = Vector(trans * Point(scaled_eigenvals * Vector(-1.0, 1.0, 1.0)));
728-
Vector p2 = Vector(trans * Point(scaled_eigenvals * Vector(-1.0, 1.0, -1.0)));
729-
Vector p3 = Vector(trans * Point(scaled_eigenvals * Vector(1.0, 1.0, 1.0)));
730-
Vector p4 = Vector(trans * Point(scaled_eigenvals * Vector(1.0, 1.0, -1.0)));
731-
Vector p5 = Vector(trans * Point(scaled_eigenvals * Vector(-1.0, -1.0, 1.0)));
732-
Vector p6 = Vector(trans * Point(scaled_eigenvals * Vector(-1.0, -1.0, -1.0)));
733-
Vector p7 = Vector(trans * Point(scaled_eigenvals * Vector(1.0, -1.0, 1.0)));
734-
Vector p8 = Vector(trans * Point(scaled_eigenvals * Vector(1.0, -1.0, -1.0)));
794+
Vector p1 = Vector(trans * Point(eigvals * Vector(-1.0, 1.0, 1.0)));
795+
Vector p2 = Vector(trans * Point(eigvals * Vector(-1.0, 1.0, -1.0)));
796+
Vector p3 = Vector(trans * Point(eigvals * Vector(1.0, 1.0, 1.0)));
797+
Vector p4 = Vector(trans * Point(eigvals * Vector(1.0, 1.0, -1.0)));
798+
Vector p5 = Vector(trans * Point(eigvals * Vector(-1.0, -1.0, 1.0)));
799+
Vector p6 = Vector(trans * Point(eigvals * Vector(-1.0, -1.0, -1.0)));
800+
Vector p7 = Vector(trans * Point(eigvals * Vector(1.0, -1.0, 1.0)));
801+
Vector p8 = Vector(trans * Point(eigvals * Vector(1.0, -1.0, -1.0)));
735802

736803
// Rotate norms
737804
Vector x_vec = rotate * Vector(1, 0, 0);
@@ -770,128 +837,147 @@ void GlyphGeom::generateBoxSide(const Vector& p1, const Vector& p2, const Vector
770837
indices_.push_back(offset);
771838
}
772839

773-
void GlyphGeom::generateEllipsoid(const Point& center, Tensor& t, int resolution, const ColorRGB& color, bool half)
840+
void GlyphGeom::generateEllipsoid(const Point& center, Tensor& t, double scale, int resolution, const ColorRGB& color, bool half, bool normalize)
774841
{
775-
Vector eigvec1, eigvec2, eigvec3;
776-
t.get_eigenvectors(eigvec1, eigvec2, eigvec3);
842+
double zeroThreshold = 0.000001;
843+
std::vector<Vector> eigvectors(3);
844+
t.get_eigenvectors(eigvectors[0], eigvectors[1], eigvectors[2]);
777845

778-
double eigval1, eigval2, eigval3;
779-
t.get_eigenvalues(eigval1, eigval2, eigval3);
780-
Vector scaled_eigenvals = Vector(eigval1, eigval2, eigval3);
846+
double eigval1, eigval2, eigval3;
847+
t.get_eigenvalues(eigval1, eigval2, eigval3);
848+
Vector eigvals = Vector(fabs(eigval1), fabs(eigval2), fabs(eigval3));
849+
if(normalize)
850+
eigvals.normalize();
851+
eigvals *= scale;
781852

853+
// Checks to see if eigenvalues are close to 0
854+
bool eig_x_0 = eigvals.x() <= zeroThreshold;
855+
bool eig_y_0 = eigvals.y() <= zeroThreshold;
856+
bool eig_z_0 = eigvals.z() <= zeroThreshold;
857+
858+
// Set to 0 if below threshold
859+
eigvals[0] = (!eig_x_0) * eigvals[0];
860+
eigvals[1] = (!eig_y_0) * eigvals[1];
861+
eigvals[2] = (!eig_z_0) * eigvals[2];
862+
863+
bool flatTensor = (eig_x_0 + eig_y_0 + eig_z_0) >= 1;
864+
Vector zero_norm;
865+
866+
if(flatTensor)
867+
{
868+
reorderTensor(eigvectors, eigvals);
869+
870+
eig_x_0 = eigvals.x() <= zeroThreshold;
871+
eig_y_0 = eigvals.y() <= zeroThreshold;
872+
eig_z_0 = eigvals.z() <= zeroThreshold;
782873
// Check for zero eigenvectors
783-
bool zero_norm_used = false;
784-
Vector zero_norm;
785-
double epsilon = pow(2, -52);
786-
if(scaled_eigenvals[0] <= epsilon)
874+
if(eig_x_0)
787875
{
788-
zero_norm_used = true;
789-
zero_norm = Cross(eigvec2, eigvec3);
790-
eigvec1 = Cross(eigvec2, eigvec3);
876+
zero_norm = Cross(eigvectors[1], eigvectors[2]);
877+
eigvectors[0] = zero_norm;
791878
}
792-
else if(scaled_eigenvals[1] <= epsilon)
879+
else if(eig_y_0)
793880
{
794-
zero_norm_used = true;
795-
zero_norm = Cross(eigvec1, eigvec3);
796-
eigvec2 = Cross(eigvec1, eigvec3);
881+
zero_norm = Cross(eigvectors[0], eigvectors[2]);
882+
eigvectors[1] = zero_norm;
797883
}
798-
else if(scaled_eigenvals[2] <= epsilon)
884+
else if(eig_z_0)
799885
{
800-
zero_norm_used = true;
801-
zero_norm = Cross(eigvec1, eigvec2);
802-
eigvec3 = Cross(eigvec1, eigvec2);
886+
zero_norm = Cross(eigvectors[0], eigvectors[1]);
887+
eigvectors[2] = zero_norm;
803888
}
889+
}
890+
891+
Transform rotate(Point(0.0, 0.0, 0.0), eigvectors[0], eigvectors[1], eigvectors[2]);
892+
Transform trans = rotate;
893+
trans.pre_translate((Vector) center);
894+
895+
trans.post_scale (Vector(1.0,1.0,1.0) * eigvals);
896+
rotate.post_scale(Vector(1.0,1.0,1.0) / eigvals);
897+
898+
int nu = resolution + 1;
804899

805-
Transform rotate(Point(0.0, 0.0, 0.0), eigvec1, eigvec2, eigvec3);
806-
Transform trans = rotate;
807-
trans.pre_translate((Vector) center);
900+
// Half ellipsoid criteria.
901+
int nv = resolution;
902+
if (half) nv /= 2;
903+
904+
// Should only happen when doing half ellipsoids.
905+
if (nv < 2) nv = 2;
906+
907+
double end = half ? M_PI / 2 : M_PI;
908+
909+
SinCosTable tab1(nu, 0, 2 * M_PI);
910+
SinCosTable tab2(nv, 0, end);
911+
912+
// Draw the ellipsoid
913+
for (int v = 0; v<nv - 1; v++)
914+
{
915+
double nr1 = tab2.sin(v + 1);
916+
double nr2 = tab2.sin(v);
808917

809-
trans.post_scale (Vector(1.0,1.0,1.0) * scaled_eigenvals);
810-
rotate.post_scale(Vector(1.0,1.0,1.0) / scaled_eigenvals);
918+
double nz1 = tab2.cos(v + 1);
919+
double nz2 = tab2.cos(v);
811920

812-
int nu = resolution + 1;
921+
for (int u = 0; u<nu; u++)
922+
{
923+
uint32_t offset = static_cast<uint32_t>(numVBOElements_);
924+
double nx = tab1.sin(u);
925+
double ny = tab1.cos(u);
813926

814-
// Half ellipsoid criteria.
815-
int nv = resolution;
816-
if (half) nv /= 2;
927+
double x1 = nr1 * nx;
928+
double y1 = nr1 * ny;
929+
double z1 = nz1;
817930

818-
// Should only happen when doing half ellipsoids.
819-
if (nv < 2) nv = 2;
931+
double x2 = nr2 * nx;
932+
double y2 = nr2 * ny;
933+
double z2 = nz2;
820934

821-
double end = half ? M_PI / 2 : M_PI;
935+
// Rotate and translate points
936+
Vector p1 = Vector(trans * Point(x1, y1, z1));
937+
Vector p2 = Vector(trans * Point(x2, y2, z2));
822938

823-
SinCosTable tab1(nu, 0, 2 * M_PI);
824-
SinCosTable tab2(nv, 0, end);
939+
Vector v1, v2;
825940

826-
// Draw the ellipsoid
827-
for (int v = 0; v<nv - 1; v++)
941+
if(flatTensor)
942+
{
943+
// Avoids recalculating norm vector and prevents vectors with infinite length
944+
bool first_half = v < nv/2;
945+
v1 = first_half ? zero_norm : -zero_norm;
946+
v2 = first_half ? zero_norm : -zero_norm;
947+
}
948+
else
828949
{
829-
double nr1 = tab2.sin(v + 1);
830-
double nr2 = tab2.sin(v);
831-
832-
double nz1 = tab2.cos(v + 1);
833-
double nz2 = tab2.cos(v);
834-
835-
for (int u = 0; u<nu; u++)
836-
{
837-
uint32_t offset = static_cast<uint32_t>(numVBOElements_);
838-
double nx = tab1.sin(u);
839-
double ny = tab1.cos(u);
840-
841-
double x1 = nr1 * nx;
842-
double y1 = nr1 * ny;
843-
double z1 = nz1;
844-
845-
double x2 = nr2 * nx;
846-
double y2 = nr2 * ny;
847-
double z2 = nz2;
848-
849-
// Rotate and translate points
850-
Vector p1 = Vector(trans * Point(x1, y1, z1));
851-
Vector p2 = Vector(trans * Point(x2, y2, z2));
852-
853-
Vector v1, v2;
854-
855-
if(zero_norm_used)
856-
{
857-
// Avoids recalculating norm vector and prevents vectors with infinite length
858-
bool first_half = v < nv/2;
859-
v1 = first_half ? zero_norm : -zero_norm;
860-
v2 = first_half ? zero_norm : -zero_norm;
861-
}
862-
else
863-
{
864-
// Rotate norms
865-
v1 = rotate * Vector(x1, y1, z1);
866-
v2 = rotate * Vector(x2, y2, z2);
867-
}
868-
869-
v1.safe_normalize();
870-
v2.safe_normalize();
871-
872-
// Transorm points and add to points list
873-
points_.push_back(p1);
874-
points_.push_back(p2);
875-
876-
// Add normals
877-
normals_.push_back(v1);
878-
normals_.push_back(v2);
879-
880-
// Add color vectors from parameters
881-
colors_.push_back(color);
882-
colors_.push_back(color);
883-
884-
numVBOElements_ += 2;
885-
886-
indices_.push_back(0 + offset);
887-
indices_.push_back(1 + offset);
888-
indices_.push_back(2 + offset);
889-
indices_.push_back(2 + offset);
890-
indices_.push_back(1 + offset);
891-
indices_.push_back(3 + offset);
892-
}
893-
for(int jj = 0; jj < 6; jj++) indices_.pop_back();
950+
// Rotate norms
951+
v1 = rotate * Vector(x1, y1, z1);
952+
v2 = rotate * Vector(x2, y2, z2);
894953
}
954+
955+
v1.safe_normalize();
956+
v2.safe_normalize();
957+
958+
// Transorm points and add to points list
959+
points_.push_back(p1);
960+
points_.push_back(p2);
961+
962+
// Add normals
963+
normals_.push_back(v1);
964+
normals_.push_back(v2);
965+
966+
// Add color vectors from parameters
967+
colors_.push_back(color);
968+
colors_.push_back(color);
969+
970+
numVBOElements_ += 2;
971+
972+
indices_.push_back(0 + offset);
973+
indices_.push_back(1 + offset);
974+
indices_.push_back(2 + offset);
975+
indices_.push_back(2 + offset);
976+
indices_.push_back(1 + offset);
977+
indices_.push_back(3 + offset);
978+
}
979+
for(int jj = 0; jj < 6; jj++) indices_.pop_back();
980+
}
895981
}
896982

897983
void GlyphGeom::generateLine(const Point& p1, const Point& p2, const ColorRGB& color1, const ColorRGB& color2)

0 commit comments

Comments
 (0)