// StlObject.cpp: implementation of the CStLObject class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "StLViewer.h"
#include "StlObject.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CStLObject::CStLObject(CStLReader* r)
{
myReader = r->Copy();
glObjType = GLSURFACE;
glObjID = (int)glObjType + CGLObject::GetCount();
itsMaterial = JADE;
itsShadeRed = 155;
itsShadeGreen = 155;
itsShadeBlue = 155;
itsRed = 200;
itsGreen = 225;
itsBlue = 50;
pointList = new CListOfCPoint3D;
ComputePoints();
ComputeBoundLimits();
}
CStLObject::~CStLObject()
{
pointList->Clear();
delete pointList;
delete myReader;
}
CGLObject* CStLObject::Copy() const
{
CStLObject* O = new CStLObject(myReader);
O->SetColor(itsRed, itsGreen, itsBlue);
O->SetMaterial(GetMaterial());
O->glObjID = glObjID;
return O;
}
void CStLObject::DefineDisplay()
{
GLfloat bgcol[4];
glGetFloatv(GL_COLOR_CLEAR_VALUE, bgcol);
GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
// Enable Depth Testing
glEnable(GL_DEPTH_TEST);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
// Enable lighting
glEnable(GL_LIGHTING);
// Enable color tracking
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,specref);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,128);
glShadeModel(GL_SMOOTH);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
if(displayMode == GLSHADED)
{
glPushAttrib(GL_LIGHTING_BIT);
ApplyMaterial(itsMaterial);
DrawShaded();
glPopAttrib();
}
else if(displayMode == GLWIREFRAME)
{
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_DEPTH_TEST);
DrawWired();
glPopAttrib();
}
else if(displayMode == GLHLREMOVED)
{
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
glColor3f(bgcol[0], bgcol[1], bgcol[2]);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(5, 5);
DrawShaded();
DrawWired();
glDisable(GL_POLYGON_OFFSET_FILL);
glPopAttrib();
}
glDisable(GL_BLEND);
}
void CStLObject::Display(const GLDisplayMode& dMode)
{
displayMode = dMode;
DefineDisplay();
}
void CStLObject::Hilight(const GLDisplayMode& dMode)
{
glPushAttrib(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glDisable(GL_DEPTH_TEST);
itsRed = 0; itsGreen = 255; itsBlue = 255;
glColor3ub(itsRed, itsGreen, itsBlue);
DrawWired();
glPopAttrib();
}
void CStLObject::SetColor(const GLubyte& red, const GLubyte& green, const GLubyte& blue)
{
if(displayMode == GLWIREFRAME)
{
itsRed = red;
itsGreen = green;
itsBlue = blue;
}
else
{
itsShadeRed = red;
itsShadeGreen = green;
itsShadeBlue = blue;
}
DefineDisplay();
}
void CStLObject::GetColor(GLubyte* colVect) const
{
colVect = new GLubyte[3];
if(displayMode == GLWIREFRAME)
{
colVect[0] = itsRed;
colVect[1] = itsGreen;
colVect[2] = itsBlue;
}
else
{
colVect[0] = itsShadeRed;
colVect[1] = itsShadeGreen;
colVect[2] = itsShadeBlue;
}
}
void CStLObject::ComputeBoundLimits()
{
double lx=0,ly=0,lz=0,sx=0,sy=0,sz=0;
CPoint3D P;
CArray<double, double> pxArray, pyArray, pzArray;
unsigned long pCnt=0;
unsigned long i=0,j=0,inc=0;
double v=0;
CListIteratorOfListOfCPoint3D myListIter(pointList);
for(myListIter.Init(); myListIter.More(); myListIter.Next())
{
P = myListIter.Current();
pxArray.Add(P.GetX());
pyArray.Add(P.GetY());
pzArray.Add(P.GetZ());
}
//Find Largest And Smallest X
pCnt = pxArray.GetUpperBound();
inc =1;
do
{
inc *= 3;
inc++;
}while(inc <= pCnt);
do
{
inc /= 3;
for(i=inc; i<=pCnt; i++)
{
v = pxArray[i];
j=i;
while(pxArray[j-inc] > v)
{
pxArray[j] = pxArray[j-inc];
j -= inc;
if(j <= inc)
break;
}
pxArray[j] = v;
}
}while(inc > 1);
sx = pxArray[0]; lx = pxArray[pCnt];
//Find Largest And Smallest Y
pCnt = pyArray.GetUpperBound();
inc =1;
do
{
inc *= 3;
inc++;
}while(inc <= pCnt);
do
{
inc /= 3;
for(i=inc; i<=pCnt; i++)
{
v = pyArray[i];
j=i;
while(pyArray[j-inc] > v)
{
pyArray[j] = pyArray[j-inc];
j -= inc;
if(j <= inc)
break;
}
pyArray[j] = v;
}
}while(inc > 1);
sy = pyArray[0]; ly = pyArray[pCnt];
//Find Largest And Smallest Z
pCnt = pzArray.GetUpperBound();
inc =1;
do
{
inc *= 3;
inc++;
}while(inc <= pCnt);
do
{
inc /= 3;
for(i=inc; i<=pCnt; i++)
{
v = pzArray[i];
j=i;
while(pzArray[j-inc] > v)
{
pzArray[j] = pzArray[j-inc];
j -= inc;
if(j <= inc)
break;
}
pzArray[j] = v;
}
}while(inc > 1);
sz = pzArray[0]; lz = pzArray[pCnt];
itsBox.SetLimits(sx,lx,sy,ly,sz,lz);
pxArray.RemoveAll();
pyArray.RemoveAll();
pzArray.RemoveAll();
}
void CStLObject::DrawWired()
{
int pCnt = 4;
CPoint3D curP;
CListIteratorOfListOfCPoint3D myPList(pointList);
glColor3ub(itsRed, itsGreen, itsBlue);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_TRIANGLES);
for(myPList.Init(); myPList.More(); myPList.Next())
{
curP = myPList.Current();
if(pCnt%4 ==0 )
glNormal3d(curP.GetX(), curP.GetY(), curP.GetZ());
else
glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
pCnt++;
}
glEnd();
}
void CStLObject::DrawShaded()
{
int pCnt = 4;
CPoint3D curP;
CListIteratorOfListOfCPoint3D myPList(pointList);
if(displayMode == GLSHADED)
glColor3ub(itsShadeRed, itsShadeGreen, itsShadeBlue);
//else HLR
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_TRIANGLES);
for(myPList.Init(); myPList.More(); myPList.Next())
{
curP = myPList.Current();
if(pCnt%4 ==0 )
glNormal3d(curP.GetX(), curP.GetY(), curP.GetZ());
else
glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
pCnt++;
}
glEnd();
}
void CStLObject::ComputePoints()
{
CPoint3D curP;
CListIteratorOfListOfCPoint3D myPList(myReader->pointList);
for(myPList.Init(); myPList.More(); myPList.Next())
pointList->Append(myPList.Current());
}