Click here to Skip to main content
Click here to Skip to main content
Articles » Multimedia » OpenGL » General » Downloads
 
Add your own
alternative version

Basic Curves And Surfaces Modeler

, 18 Apr 2012 CPOL
A basic demo of modeling curves and surfaces in OpenGL.
cadsurfexe.zip
CadSurfexe
CadSurf.exe
VKGeom.dll
VKGraphic.dll
cadsurf_demo.zip
CadSurf.exe
cadsurf_src.zip
CadSurf_src
VKernel
VKGraphic
VKGraphic.dsp
VKGraphic.dsw
VKGraphic.plg
VKGeom
VKGeom.dsp
VKGeom.dsw
cadsurf
CadSurf.clw
CadSurf.dsp
cadsurf.dsw
Thumbs.db
res
bmp00001.bmp
cadsurf.ico
CADSURFDOC.ICO
new_splash.bmp
new_splash.PNG
new_splash_small.bmp
tb_geom.bmp
Thumbs.db
toolbar.bmp
toolbar1.bmp
untitled.bmp
XPStyle.manifest
CadSurf_VS2008.zip
CadSurf
cadsurf
CadSurf.suo
res
bmp00001.bmp
cadsurf.ico
CADSURFDOC.ICO
new_splash.bmp
new_splash.PNG
new_splash_small.bmp
tb_geom.bmp
Thumbs.db
toolbar.bmp
toolbar1.bmp
untitled.bmp
VKernel
VKGeom
VKGraphic
VKGraphic.plg
// GLSurface.cpp: implementation of the CGLSurface class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "GLSurface.h"
#include "MMath.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CGLSurface::CGLSurface(const CSurface* s)
{
    pSurf = s->Copy();
    glObjType = GLSURFACE;
    glObjID = (int)glObjType + CGLObject::GetCount();
    SMOOTH = 100;
    CSMOOTH = 100;

    itsShadeRed = 150;
    itsShadeGreen = 150;
    itsShadeBlue = 150;

    itsRed = 200;
    itsGreen = 225;
    itsBlue = 50;

    isoRed = 205;
    isoGreen = 205;
    isoBlue = 255;

    factor = 1;
    pattern = 0x5555;

    SetMaterial(BRONZE);

    pointList = new CListOfCPoint3D;
    pointWFUList = new CListOfCPoint3D;
    pointWFVList = new CListOfCPoint3D;
    normalList = new CListOfCPoint3D;
    bpointList = new CListOfCPoint3D;

    myListWFUIter.SetList(pointWFUList);
    myListWFVIter.SetList(pointWFVList);

    ComputePoints();
    ComputeWFPoints();
    ComputeBoundLimits();
    InitDisplayList();
}

CGLSurface::~CGLSurface()
{
    if(pointList)
    {
	pointList->Clear();
	delete pointList;
    }
    if(pointWFUList)
    {
	pointWFUList->Clear();
	delete pointWFUList;
    }
    if(pointWFVList)
    {
	pointWFVList->Clear();
	delete pointWFVList;
    }
    if(normalList)
    {
	normalList->Clear();
	delete normalList;
    }
    if(bpointList)
    {
	bpointList->Clear();
	delete bpointList;
    }
    glDeleteLists(wireList, 1);
    glDeleteLists(edgeList, 1);
    glDeleteLists(shadList, 1);
    delete pSurf;
}

CGLObject* CGLSurface::Copy() const
{
    CGLSurface* S = new CGLSurface(pSurf);
    S->SetColor(itsRed, itsGreen, itsBlue);
    S->SetMaterial(GetMaterial());
    S->glObjID = glObjID;
    return S;
}

void CGLSurface::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);

    if(displayMode == GLSHADED)
    {	
	glPushAttrib(GL_LIGHTING_BIT);
	ApplyMaterial();
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(8, 8);
	DrawShaded();	
	glDisable(GL_LIGHTING);
	glDisable(GL_COLOR_MATERIAL);
	glColor3ub(25, 25, 25);
	DrawEdges();
	glDisable(GL_POLYGON_OFFSET_FILL);
	glPopAttrib();
    }	
    else if(displayMode == GLWIREFRAME)
    {
	glPushAttrib(GL_LIGHTING_BIT);
	glDisable(GL_LIGHTING);
	glDisable(GL_COLOR_MATERIAL);
	glDisable(GL_DEPTH_TEST);
	glColor3ub(itsRed, itsGreen, itsBlue);
	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();
    }
}

void CGLSurface::Display(const GLDisplayMode& dMode)
{
    displayMode = dMode;
    DefineDisplay();
}

void CGLSurface::Hilight(const GLDisplayMode&)
{
    glPushAttrib(GL_LIGHTING_BIT);
    glDisable(GL_LIGHTING);
    glDisable(GL_COLOR_MATERIAL);
    glDisable(GL_DEPTH_TEST);
    itsRed = 0; itsGreen = 255; itsBlue = 255;
    isoRed = 0; isoGreen = 255; isoBlue = 255;
    glColor3ub(itsRed, itsGreen, itsBlue);
    DrawWired();
    glPopAttrib();
}

void CGLSurface::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 CGLSurface::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 CGLSurface::SetSurface(const CSurface* s)
{
    pSurf = s->Copy();
    ComputePoints();
    ComputeBoundLimits();
}

CGeometry* CGLSurface::Geometry() const
{
    CSurface* surf = pSurf->Copy();
    return surf;
}

void CGLSurface::ComputeBoundLimits()
{
    /*
       if(pSurf->IsOfType(SPHERE))
       {
       CSphere* pSph = static_cast<CSphere*> (pSurf);
       double rad = pSph->GetRadius();
       CPoint3D P = pSph->GetLocation().GetPosition();
       itsBox.SetLimits(-rad+P.GetX(), rad+P.GetX(), -rad+P.GetY(), rad+P.GetY(), -rad+P.GetZ(), rad+P.GetZ());
       return;
       }
       double lx=0,ly=0,lz=0,sx=0,sy=0,sz=0;
       CPoint3D P;
       QList<double> pxArray, pyArray, pzArray;
       pxArray.setAutoDelete(TRUE);
       pyArray.setAutoDelete(TRUE);
       pzArray.setAutoDelete(TRUE);

       CListIteratorOfListOfCPoint3D myListIter(bpointList);
       for(myListIter.Init(); myListIter.More(); myListIter.Next())
       {
       P = myListIter.Current();	
       double *x = new double, *y = new double, *z = new double;
     *x = P.GetX(); *y = P.GetY(); *z = P.GetZ();
     pxArray.append(x);
     pyArray.append(y);
     pzArray.append(z);
     }
     pxArray.sort();
     pyArray.sort();
     pzArray.sort();
     sx = *pxArray.first();  lx = *pxArray.last();
     sy = *pyArray.first();  ly = *pyArray.last();
     sz = *pzArray.first();  lz = *pzArray.last();

     itsBox.SetLimits(sx,lx,sy,ly,sz,lz);
     */
}

void CGLSurface::ComputePoints()
{
    SMOOTH *= 6;

    CPoint3D curP1;
    double uparts, vparts, istep, jstep;
    double fUPar, lUPar, fVPar, lVPar;

    double i, j;

    fUPar = pSurf->FirstUParameter();
    lUPar = pSurf->LastUParameter();

    fVPar = pSurf->FirstVParameter();
    lVPar = pSurf->LastVParameter();

    uparts = vparts = SMOOTH/15;

    istep = fabs(lUPar-fUPar)/uparts;
    jstep = fabs(lVPar-fVPar)/vparts;

    if(pointList && (!pointList->IsEmpty()))
	pointList->Clear();
    if(normalList && (!normalList->IsEmpty()))
	normalList->Clear();
    if(bpointList && (!bpointList->IsEmpty()))
	bpointList->Clear();


    for(j = fVPar; j <= lVPar; j += jstep)
    {
	for(i = fUPar; i <= lUPar; i += istep)
	{
	    curP1 = pSurf->PointAtPara(i, j);
	    bpointList->Append(curP1);
	}
    }

    CPoint3D curP; CVector3D N;

    for(j = fVPar; j < lVPar; j += jstep)
    {
	for(i = fUPar; i < lUPar; i += istep)
	{
	    curP = pSurf->PointAtPara(i, j);
	    N = pSurf->NormalAt(i,j);

	    N.Normalize();
	    normalList->Append(N.Point());
	    pointList->Append(curP);

	    curP = pSurf->PointAtPara(i, j+jstep);
	    N = pSurf->NormalAt(i,j+jstep);
	    N.Normalize();
	    normalList->Append(N.Point());
	    pointList->Append(curP);
	}
	curP = pSurf->PointAtPara(lUPar, j);
	N = pSurf->NormalAt(lUPar,j);
	N.Normalize();
	normalList->Append(N.Point());
	pointList->Append(curP);

	curP = pSurf->PointAtPara(lUPar, j+jstep);
	N = pSurf->NormalAt(lUPar,j+jstep);
	N.Normalize();

	normalList->Append(N.Point());
	pointList->Append(curP);
    }
}

void CGLSurface::ComputeWFPoints()
{
    double fUPar = pSurf->FirstUParameter();
    double lUPar = pSurf->LastUParameter();
    double fVPar = pSurf->FirstVParameter();
    double lVPar = pSurf->LastVParameter();
    double parts;
    if(pSurf->IsOfType(EXTRUDED) || pSurf->IsOfType(RULED))
	parts = 2;
    else
	parts = 3;
    double ustep = fabs(lUPar-fUPar)/parts;
    double vstep = fabs(lVPar-fVPar)/parts;
    double i;

    //Compute U ISO Lines
    ComputeUIso(fVPar);	//Edge
    for(i = fVPar+vstep; i < lVPar; i += vstep)
	ComputeUIso(i);
    ComputeUIso(lVPar);	//Edge

    //Compute V ISO Lines
    ComputeVIso(fUPar);	//Edge
    for(i = fUPar+ustep; i <= lUPar; i += ustep)
	ComputeVIso(i);
    ComputeVIso(lUPar);	//Edge
}

void CGLSurface::ComputeUIso(const double vPar)
{
    double fPar = pSurf->FirstUParameter();
    double lPar = pSurf->LastUParameter();
    double parts = CSMOOTH;
    double step = fabs(lPar-fPar)/parts;
    double i;
    CPoint3D curP;

    for(i = fPar; i <= lPar; i += step)
    {
	curP = pSurf->PointAtPara(i, vPar);
	pointWFUList->Append(curP);
    }
    curP = pSurf->PointAtPara(lPar, vPar);
    pointWFUList->Append(curP);
}

void CGLSurface::ComputeVIso(const double uPar)
{
    double fPar = pSurf->FirstVParameter();
    double lPar = pSurf->LastVParameter();
    double parts = CSMOOTH;
    double step = fabs(lPar-fPar)/parts;
    double i;
    CPoint3D curP;

    for(i = fPar; i <= lPar; i += step)
    {
	curP = pSurf->PointAtPara(uPar, i);
	pointWFVList->Append(curP);
    }
    curP = pSurf->PointAtPara(uPar, lPar);
    pointWFVList->Append(curP);
}

void CGLSurface::DrawUIso()
{
    double fPar = pSurf->FirstUParameter();
    double lPar = pSurf->LastUParameter();
    double parts = CSMOOTH;
    double step = fabs(lPar-fPar)/parts;
    double i;
    CPoint3D curP;

    glColor3ub(isoRed, isoGreen, isoBlue);
    glBegin(GL_LINE_STRIP);
    for(i = fPar; i <= lPar; i += step)
    {
	curP = myListWFUIter.Current();
	glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
	myListWFUIter.Next();
    }
    curP = myListWFUIter.Current();
    glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
    myListWFUIter.Next();
    glEnd();
}

void CGLSurface::DrawVIso()
{
    double fPar = pSurf->FirstVParameter();
    double lPar = pSurf->LastVParameter();
    double parts = CSMOOTH;
    double step = fabs(lPar-fPar)/parts;
    double i;
    CPoint3D curP;

    glColor3ub(isoRed, isoGreen, isoBlue);
    glBegin(GL_LINE_STRIP);
    for(i = fPar; i <= lPar; i += step)
    {
	curP = myListWFVIter.Current();
	glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
	myListWFVIter.Next();
    }
    curP = myListWFVIter.Current();
    glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
    myListWFVIter.Next();
    glEnd();
}

void CGLSurface::DrawWired()
{
    myListWFUIter.Init();
    myListWFVIter.Init();
    double fUPar = pSurf->FirstUParameter();
    double lUPar = pSurf->LastUParameter();
    double fVPar = pSurf->FirstVParameter();
    double lVPar = pSurf->LastVParameter();
    double parts;
    if(pSurf->IsOfType(EXTRUDED) || pSurf->IsOfType(RULED))
	parts = 2;
    else
	parts = 3;
    double ustep = fabs(lUPar-fUPar)/parts;
    double vstep = fabs(lVPar-fVPar)/parts;
    double i;

    glLineStipple(factor,pattern);

    //Draw U ISO Lines
    isoRed = itsRed;
    isoGreen = itsGreen;
    isoBlue = itsBlue;
    glDisable(GL_LINE_STIPPLE);
    DrawUIso();	//Edge
    for(i = fVPar+vstep; i < lVPar; i += vstep)
    {
	isoRed = 205;
	isoGreen = 205;
	isoBlue = 255;
	glEnable(GL_LINE_STIPPLE);
	DrawUIso();
    }
    isoRed = itsRed;
    isoGreen = itsGreen;
    isoBlue = itsBlue;
    glDisable(GL_LINE_STIPPLE);
    DrawUIso();	//Edge

    //Draw V ISO Lines
    DrawVIso();	//Edge
    for(i = fUPar+ustep; i <= lUPar; i += ustep)
    {	
	isoRed = 205;
	isoGreen = 205;
	isoBlue = 255;
	glEnable(GL_LINE_STIPPLE);
	DrawVIso();
    }
    isoRed = itsRed;
    isoGreen = itsGreen;
    isoBlue = itsBlue;
    glDisable(GL_LINE_STIPPLE);
    DrawVIso();	//Edge

    glDisable(GL_LINE_STIPPLE);
}

void CGLSurface::DrawShaded()
{
    CPoint3D curP; CPoint3D N;
    double uparts, vparts, istep, jstep;
    double fUPar, lUPar, fVPar, lVPar;

    double i, j;

    fUPar = pSurf->FirstUParameter();
    lUPar = pSurf->LastUParameter();

    fVPar = pSurf->FirstVParameter();
    lVPar = pSurf->LastVParameter();

    uparts = vparts = SMOOTH/15;

    istep = fabs(lUPar-fUPar)/uparts;
    jstep = fabs(lVPar-fVPar)/vparts;

    CListIteratorOfListOfCPoint3D myListIterP(pointList);
    CListIteratorOfListOfCPoint3D myListIterN(normalList);
    myListIterP.Init();
    myListIterN.Init();


    if(displayMode == GLSHADED) 
	glColor3ub(itsShadeRed, itsShadeGreen, itsShadeBlue);
    //else HLR

    glFrontFace(GL_CW);
    for(j = fVPar; j < lVPar; j += jstep)
    {
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	glBegin(GL_TRIANGLE_STRIP);
	for(i = fUPar; i < lUPar; i += istep)
	{
	    curP = myListIterP.Current();
	    N = myListIterN.Current();
	    glNormal3d(N.GetX(), N.GetY(), N.GetZ());
	    glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
	    myListIterP.Next();
	    myListIterN.Next();

	    curP = myListIterP.Current();
	    N = myListIterN.Current();
	    glNormal3d(N.GetX(), N.GetY(), N.GetZ());
	    glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
	    myListIterP.Next();
	    myListIterN.Next();
	}
	curP = myListIterP.Current();
	N = myListIterN.Current();
	glNormal3d(N.GetX(), N.GetY(), N.GetZ());
	glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
	myListIterP.Next();
	myListIterN.Next();

	curP = myListIterP.Current();
	N = myListIterN.Current();
	glNormal3d(N.GetX(), N.GetY(), N.GetZ());
	glVertex3d(curP.GetX(), curP.GetY(), curP.GetZ());
	myListIterP.Next();
	myListIterN.Next();

	glEnd();
    }
    glFrontFace(GL_CCW);
}

void CGLSurface::DrawEdges()
{
    myListWFUIter.Init();
    myListWFVIter.Init();
    double fUPar = pSurf->FirstUParameter();
    double lUPar = pSurf->LastUParameter();
    double fVPar = pSurf->FirstVParameter();
    double lVPar = pSurf->LastVParameter();
    double parts;
    if(pSurf->IsOfType(EXTRUDED) || pSurf->IsOfType(RULED))
	parts = 2;
    else
	parts = 3;
    double ustep = fabs(lUPar-fUPar)/parts;
    double vstep = fabs(lVPar-fVPar)/parts;
    double i;

    isoRed = 25;
    isoGreen = 25;
    isoBlue = 25;
    glDisable(GL_LINE_STIPPLE);
    glLineWidth(2.5);
    //Draw U ISO Lines    	
    DrawUIso();	//Edge
    for(i = fVPar+vstep; i < lVPar; i += vstep)
    {			
	DrawUIso();
    }    
    DrawUIso();	//Edge

    //Draw V ISO Lines
    DrawVIso();	//Edge
    for(i = fUPar+ustep; i <= lUPar; i += ustep)
    {		
	DrawVIso();
    }    	
    DrawVIso();	//Edge

    glLineWidth(1.0);
}

void CGLSurface::InitDisplayList()
{
    //wire list
    wireList = glGenLists(1);
    glNewList(wireList, GL_COMPILE);
    DrawWired();
    glEndList();

    //edges list
    edgeList = glGenLists(1);
    glNewList(edgeList, GL_COMPILE);
    DrawEdges();
    glEndList();

    //shaded list
    shadList = glGenLists(1);
    glNewList(shadList, GL_COMPILE);
    DrawShaded();
    glEndList();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sharjith
Engineer Tata Technologies Ltd
India India
Sharjith is a Mechanical Engineer with strong passion for Automobiles, Aircrafts and Software development.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 18 Apr 2012
Article Copyright 2003 by Sharjith
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid