Carnivorous Plants Website
Carnivorous Plants in the Wilderness
by Makoto Honda
 

Last update : 2010-August-30                Copyright © 2010-2012 Makoto Honda. All Rights Reserved.   

  

 

  HOME

 

Some Notes   

Copyright (c) 2010-2012 Makoto Honda. All Rights Reserved.

=========================================================================

HOW TO USE CObList (MFC)

.AddTail (pE)
.IsEmpty()
.Find (pE)
.RemoveAt (pos)
.RemoveAll ()

// Declare a CObList...
CObList m_elemList

// Add an object to the list...
m_elemList.AddTail (pE);

// Retrieve the very first value from the list
POSITION pos = _P_list.GetHeadPosition();
CCFDPoint* ptOrigin = (CCFDPoint*)_P_list.GetNext (pos);

// Retrieve a value from the list
for (POSITION pos = _P_list.GetHeadPosition(); pos != NULL;)
{
     CCFDPoint* p = (CCFDPoint*)_P_list.GetNext (pos);
     TempPoint ( RED, SOLID, p->m_mxOrigin );
}
// RemoveAll
for (POSITION pos = m_tempPointList.GetHeadPosition(); pos != NULL;)
{ CTempElemPoint* p = (CTempElemPoint*)m_tempPointList.GetNext (pos); delete p;}
m_tempPointList.RemoveAll ();
 

=========================================================================

DYNAMIC ARRAY USAGE

int* pArray = NULL;
int size = 0;
----------
size = 15;
pArray = new int  [ size ];
-----------
size = 30;
if (pArray) delete [ ] pArray;
pArray = new int [ size ]:
-----------
pArray [ 5 ] = 99;
int value = pArray [ 5 ];


==============================================2010-4-11===================

TEMPORARY ELEMENT

Data::TempPoint (pt)
Data::TempPointNew (pt)
Data::ClearTempPoint ()
Data::DrawAllTempElems ()

GElem1.h / cpp

class CTempElem : public CObject
{
     G_COLOR color;
     G_STYLE style;
}
class AFX_EXT_CLASS CTempElemPoint : public CTempElem
{
     CPoint3D point;
     int pointSize;
}
class AFX_EXT_CLASS CTempElemLine : public CTempElem
{
     CPoint3D point1, point2;
}
class AFX_EXT_CLASS CTempElemCircle : public CTempElem
{
     CPoint3D ptOrigin, vecNormal;
     float radius;
}

GData.h

CObList m_tempPointList;
CObList m_tempLineList;
CObList m_tempCircleList;

GData.cpp

void CData::TempPoint (G_COLOR c, G_STYLE s, int size, const CPoint3D& pt)
{
     CTempElemPoint* p = new CTempElemPoint (c, s, size, pt);
     m_tempPointList.AddTail (p);
}
void CData::TempPointNew (G_COLOR c, G_STYLE s, int size, const CPoint3D& pt)
{
     ClearTempPoint(); // ClearTempPointList
     TempPoint (c, s, size, pt);
}
void CData::ClearTempPoint ()
{
     for (POSITION pos = m_tempPointList.GetHeadPosition(); pos != NULL;)
     { CTempElemPoint* p = (CTempElemPoint*)m_tempPointList.GetNext (pos); delete p;}
     m_tempPointList.RemoveAll ();
}
void CData::ClearTempAll ()
{
     ClearTempPoint(); // ClearTempPointList
     ClearTempPointLarge(); // ClearTempPointLargeList
     ClearTempLine(); // ClearTempLineList
     ClearTempCircle(); // ClearTempCircleList
     ClearTempArc(); // ClearTempArcList
}
void CData::DrawAllTempElems ()
{
     glPointSize (5.0); // size must be here, not inside glBegin
     glBegin (GL_POINTS);
     for (POSITION pos = m_tempPointList.GetHeadPosition(); pos != NULL;)
     {
          CTempElemPoint* p = (CTempElemPoint*)m_tempPointList.GetNext (pos);
          SetTempColorAndStyle (p->color, p->style);
          glVertex3f (p->point.x, p->point.y, p->point.z);
     }
     glEnd ();
}
 

GFM_cfd.h / cpp

ClearTempAll(); // erases key-in visual cue
TempPoint ( RED, SOLID, 1, pt );
InvalidateAllVpts ();
 

=========================================================================

FM NAME CHANGE / ADD / STRING TABLE (MFC)

GDoc.h

     OnCreateMultiBox
     OnUpdateCreateMultiBox

GDoc.cpp

     ON_COMMAND_CREATE_MULTI_BOX
     ON_UPDATE_COMMAND_CREATE_MULTI_BOX

     void CGDoc::OnCreateMultiBox()
     { m_pData->m_pFK = new CFK_createMultiBox(m_pData); InitializeFK(); }
     void CGDoc::OnUpdateCreateMultiBox(CCmdUI* pCmdUI)
     { m_pData->m_pFK->UpdateFKmode (pCmdUI, FK_CREATE_MULTI_BOX); }

GGlobal.h

     FM_CREATE_MULTI_BOX

G.rc

     Toolbar...
     Menus...
     Dialogs...
     ID_CREATE_MULTI_BOX "Create Multi-Box\n Multi-Box"
     IDP_CREATE_MULTI_BOX_FM "Create Multi-Box"
     IDP_CREATE_MULTI_BOX_1 "prompt 1"
     IDP_CREATE_MULTI_BOX_2 "prompt 2"

Resource.h

     Must contain all symbols used in G.rc
     -- Copy G/Resurce.h to A_Include/Resource.h


=========================================================================

HOW TO CHANGE TOOLBAR

G.rc

     Double-click G/G.rc and bring up the toolbar icon editor
     ---- IDR_TOOLBAR9

IDR_TOOLBAR9 TOOLBAR DISCARDABLE 16, 15
BEGIN
BUTTON ID_CFD_CREATE_DOMAIN
BUTTON ID_CFD_SLICE
SEPARATOR
BUTTON ID_CFD_MY_IBITSU_TEST
SEPARATOR
BUTTON ID_CFD_INSERT_ELEMENT
BUTTON ID_CFD_GRID_GENERATION
END

Do not use class wizard (G.clw) - Edit G.rc manually.

MainFrm.cpp

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

if (!m_wndToolBar9.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar9.LoadToolBar(IDR_TOOLBAR9))
{
TRACE0("Failed to create toolbar\n"); return -1; // fail to create
}

=========================================================================

HOW AN ELEMENT IS CREATED

ADocFK_elem.cpp

------------------------------------------------------------- ADocFK_elem.cpp
void CGDoc::Line_1_IND (UINT, CPoint) ////
{ if ( ! m_bWhenIND ) return; // No piercing of CP
m_pointArray [m_pointIndex++] = m_ptIND; ////
NXS (2); ////
}
void CGDoc::Line_2_IND (UINT, CPoint) ////
{ if ( ! m_bWhenIND ) return; // No piercing of CP
intArray [m_pointIndex++] = m_ptIND; ////
} ////
void CGDoc::Line_2_END (UINT, CPoint) ////
{ CreateLine ( m_pointArray [0] ); ////
m_pointIndex = 0; ////
NXS (1);
} ////
---------------------------------------------------------------- ADoc.h
void CreateLine (const CPoint3D& pt )
{ CreateAndDisplay (ET_LINE, pt); } ////
-------------------------------------------------------- ADocFK_kernel.cpp
void CGDoc::CreateAndDisplay (ELEM_TYPE type, ////
const CPoint3D& pt, // = CPoint3D(0,0,0), ////
const CPoint3D& dir, // = CPoint3D(0,0,-1), ////
const CPoint3D& ori ) // = CPoint3D(0,1,0) ////
{ 1. CElem* pE = m_pElemCur = NewElem (type, pt, dir, ori ); ////
if (pE == NULL) return; // New elem creation failed ////
2. m_elemList.AddTail (pE); SetModifiedFlag(); ////
3. pE->GenerateVertices();
4. glNewList ((GLuint)pE, GL_COMPILE); ////
pE->CreateGLcalls (); ////
glEndList (); ////
5. for (POSITION pos = GetFirstViewPosition(); pos != NULL;) ////
{ CGView* pView = (CGView*) GetNextView (pos); ////
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; ////
pView->Invalidate(); // Calls OnDraw(); ////
} } ////
-------------------------------------------------------- ADocFK_kernel.cpp
CElem* CGDoc::NewElem ( ELEM_TYPE elemType, const CPoint3D& pt, ////
const CPoint3D& dir, const CPoint3D& ori ) ////
{ ////
CElem* pElem = NULL; ////
switch (elemType) ////
{ case ET_POINT: ////
pElem = new CElemPoint ( this, pt ); break;
case ET_LINE:
pElem = new CElemLine ( this, m_pointIndex, pt ); ////
case ET_CUBE: ////
pElem = new CElemCube (this,1,0.2f,1.0f,0.5f,pt ); ////
case ET_ELBOW: ////
pElem = new CElemElbow (this,1,0.2f,1.0f, pt,dir,ori); ////
} ////
if (pElem) return pElem; else return NULL; ////
} ////
------------------------------------------------------------------- Elem.h
CElemLine (CGDoc* pDoc, int total, CPoint3D pt ) ////
: CElem (pt) ////
{ m_elemType = ET_LINE; ////
m_pDoc = pDoc; ////
m_total = total; ////
m_pArray = new CPoint3D [ total ]; ////
m_R = m_G = m_B = 1.0f ; ////
}; ////
-------------------------------------------------------------------- Elem.h
CElem ( const CPoint3D& pt, ////
const CPoint3D& dir = CPoint3D ( 0.0f, 0.0f, -1.0f ), ////
const CPoint3D& ori = CPoint3D ( 0.0f, 1.0f, 0.0f ),
float height = 1.0f, float width = 1.0f, float length =1.0f )
{ m_mxOrigin = pt; ////
CPoint3D z ( -dir.x, -dir.y, -dir.z ); ////
m_mxAxisZ = z.Normalize();
CPoint3D x = dir * ori;
m_mxAxisX = x.Normalize();
m_mxAxisY = m_mxAxisZ * m_mxAxisX; ////
m_height = height; ////
m_width = width; ////
m_length = length; ////
m_R = m_G = m_B = 0.5f; ////
}; ////
 

=========================================================================

HOW TO CREATE SUBMENUS

MainFrm.h

protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CStatusBar m_wndStatusBar1;
CStatusBar m_wndStatusBar2;
CToolBar m_wndToolBar;
public:
CDialogBar m_wndDlgBarSm; // for submenu

GDoc.h

protected:
//{{AFX_MSG(CGDoc)
afx_msg void OnSubmenuItem1();
afx_msg void OnSubmenuItem2();
afx_msg void OnSubmenuItem3();
afx_msg void OnSubmenuItem4();

GDoc.cpp

BEGIN_MESSAGE_MAP(CGDoc, CDocument)
//{{AFX_MSG_MAP(CGDoc)
ON_COMMAND(IDC_SM_ITEM_1, OnSubmenuItem1)
ON_COMMAND(IDC_SM_ITEM_2, OnSubmenuItem2)
ON_COMMAND(IDC_SM_ITEM_3, OnSubmenuItem3)
ON_COMMAND(IDC_SM_ITEM_4, OnSubmenuItem4)

void CGDoc::OnSubmenuItem1() { m_pFK->EventForMENU (1); } // How about Tempo FK ????
void CGDoc::OnSubmenuItem2() { m_pFK->EventForMENU (2); } // How about Tempo FK ????
void CGDoc::OnSubmenuItem3() { m_pFK->EventForMENU (3); } // How about Tempo FK ????
void CGDoc::OnSubmenuItem4() { m_pFK->EventForMENU (4); } // How about Tempo FK ????

GFK_base.h

class CFK_BASE
{
public:

// CDialog* m_pDlgSubmenu; // keep the current submenu panel ptr
CDialog* m_pDlgPanel; // keep the current 2nd level panel ptr
BOOL m_bWndDlgBarSm; // Mainframe's dialog bar for submenu

void HideSubpanel () ;
}
class CFK_baseP : public CFK_BASE
{
public:
CFK_baseP ( CGDoc* pDoc ); // constructor
~CFK_baseP ()
{
HideSubmenuDlgBar () ;
}
void ShowSubmenuDlgBar ( UINT dialogID ) ;
void HideSubmenuDlgBar () ;
};

GFK_base.cpp

CFK_BASE::CFK_BASE ( CGDoc* pDoc )
{
m_pDoc = pDoc;
m_pCurPlane = m_pDoc->m_pCurPlane;

pxs = 0;
cxs = 1;
m_stringID = IDP_NOT_FOUND;

m_ptReference.x = m_ptReference.y = m_ptReference.z = 0.0f;

m_pDlgSubmenu = NULL;
m_pDlgPanel = NULL;
m_bWndDlgBarSm = false; // Mainframe's dialog bar for submenu
}
//////////////////////////////////////////////////////////
void CFK_baseP::ShowSubmenuDlgBar ( UINT dialogID )
{
CMainFrame* p = (CMainFrame*) AfxGetMainWnd ();
if (m_bWndDlgBarSm) p->m_wndDlgBarSm.DestroyWindow();

p->m_wndDlgBarSm.Create( p, dialogID, // IDD_DLG_BAR_B,
// CBRS_LEFT|CBRS_TOOLTIPS|CBRS_FLYBY, IDD_DLG_BAR_B );
CBRS_BOTTOM|CBRS_TOOLTIPS|CBRS_FLYBY, dialogID ); // IDD_DLG_BAR_B );

p-> RecalcLayout();
m_bWndDlgBarSm = true;
HideSubpanel (); // always delete current sub-panel
}
/////////////////////////////////////////////////////////
void CFK_baseP::HideSubmenuDlgBar ()
{
if (m_bWndDlgBarSm)
{
CMainFrame* p = (CMainFrame*) AfxGetMainWnd ();
p->m_wndDlgBarSm.DestroyWindow();
p-> RecalcLayout();
m_bWndDlgBarSm = false;
}

GFK_editing.cpp

/////////////////////////////////////////////////////////////////////////////
CFK_elemRotate::~CFK_elemRotate () // desctructor
{
m_pDoc->m_bElemDynHilite = false;
HideSubmenuDlgBar ();
// VisualCueClear ();
}
/////////////////////////////////////////////////////////////////////////////
void CFK_elemRotate::EventForESC ( UINT, CPoint)
{
HideSubmenuDlgBar ();
NXS (1);
}
/////////////////////////////////////////////////////////////////////////////
void CFK_elemRotate::EventForSEL ( UINT, CPoint)
{
switch (cxs)
{
case 1:
{
ShowSubmenuDlgBar ( IDD_SM_ELEM_ROTATE );
m_pElemSaved = m_pElemSEL; // New target
ELEM_TYPE et = m_pElemSEL->m_elemType;

=========================================================================

KEY-IN COORDINATES

GDoc_1.cpp

CPoint3D CGDoc::GetKeyCoordinate ( )
{
// This is a front-end preprocessor (FEP) for every coordinate key-ins.
// This function returns both "absolute" and "relative" x, y, z values
// in the rectangular coordinate system. That is, how the original
// key-in was made -- be that in the absolute/relative mode, in the
// rectangular/cylindrical/spherical coordinate, or in the global or
// the "current plane" coordinate system -- is totally transparent to
// the application programs using this FEP. This also produces an
// appropriate visual cue.

// Input : m_value1KEY, m_value2KEY, m_value3KEY ... original values
// m_modeAbsRel, m_modeRectCylSph, m_modeGlobalCP
// ptRef .... Reference pt in global/rectangular system
// Default value is (0,0,0)
// Output :
// m_tempCoordAbs ..... Absolute coord (same as return value)
// m_tempCoordRel ..... Relative coord w/respect to ptRef
// m_tempCoordRef ..... Reference coord given as input
// m_tempCoordKey ..... Initial input values
// Return ...Point in the global/absolute coordinate

CPoint3D ptKey (m_value1KEY, m_value2KEY, m_value3KEY); // original values keyed in
CPoint3D pt;
float angle2, angle3;

switch ( m_modeRCS ) // COORD_MODE - Standard MAthematical Table (p.385)
{
case COORD_RECT: // ------------------------------ Rectangular Coordinate
case COORD_CYL: // ------------------------------ Cylindrical Coordiante
case COORD_SPH: // -------------------------------- Spherical Coordinate
}
CPoint3D ptAbs, ptRel;
if ( m_modeGlobalCP = COORD_GLOBAL )
{ // ------------------------------------------------------ Global Coordinate
switch ( m_modeAbsRel )
{
case COORD_ABSOLUTE: // ------ Absolute
ptAbs = pt;
ptRel = ptAbs - ptRef;
break;
case COORD_RELATIVE: // ------ Relative
ptAbs = ptRef + pt;
ptRel = pt;
break;
}
else if ( m_modeGlobalCP = COORD_CUR_PLANE )
{ // ------------------------------------------------ Current Plane Coordinate
switch ( m_modeAbsRel )
{
case COORD_ABSOLUTE: // ------ Absolute
ptAbs = pt;
ptRel = ptAbs - ptRef;
break;
case COORD_RELATIVE: // ------ Relative
ptAbs = ptRef + pt;
ptRel = pt;
break;
}
// Update the reference point
m_ptReference = ptAbs;

m_tempCoordKey = ptKey;
m_tempCoordRef = ptRef;
m_tempCoordAbs = ptAbs;
m_tempCoordRel = ptRel;

GData.cpp

void CGDoc::DrawAllTempElems ()
{
int i;

// --------------------------------------------------- Points
if ( m_tempPointTotal )
{
glPointSize (6.0);
glBegin ( GL_POINTS );
for ( i = 0; i < m_tempPointTotal; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempPointArray[i].x ,
m_tempPointArray[i].y ,
m_tempPointArray[i].z );
}
glEnd ();
}
// --------------------------------------------------- Lines
if ( m_tempLineTotal )
{
glBegin ( GL_LINES );
for ( i = 0; i < m_tempLineTotal; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempLineArray[0][i].x ,
m_tempLineArray[0][i].y ,
m_tempLineArray[0][i].z );
glVertex3f ( m_tempLineArray[1][i].x ,
m_tempLineArray[1][i].y ,
m_tempLineArray[1][i].z );
}
glEnd ();
}
// ------------------------------------------------ Multi-Line 1
if ( m_tempMultiLineTotal1 )
{
glLineWidth ( 3.0 );
glBegin ( GL_LINE_STRIP );
for ( i = 0; i < m_tempMultiLineTotal1; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.5f, 0.5f ); // Yellow
glVertex3f ( m_tempMultiLineArray1[i].x ,
m_tempMultiLineArray1[i].y ,
m_tempMultiLineArray1[i].z );
}
glEnd ();
}
// ------------------------------------------------ Circle
for ( i = 0; i < m_tempCircleTotal; i++ )
{
GLUquadric* ppp = gluNewQuadric ();
gluDisk ( ppp, m_tempCircleRadius[i],
m_tempCircleRadius[i]+1.0,20,3);
// must apply transformation
}
// ------------------------------------------------- Coordinate system
if ( m_tempCoordType > 0 )
{
//------------- Dot for all cases -------------
CPoint3D ptZero ( 0.0f, 0.0f, 0.0f );
CPoint3D ptAbs ( m_tempCoordAbs.x,
m_tempCoordAbs.y,
m_tempCoordAbs.z );
glPointSize (9.0);
glBegin ( GL_POINTS );
glColor3f ( 1.0f, 1.0f, 0.0f ); // Yellow
glVertex3f ( ptAbs.x, ptAbs.y, ptAbs.z );
glEnd ();

CPoint3D pt0 = (m_modeAbsRel == COORD_ABSOLUTE ) ? ptZero
: m_tempCoordRel;

glEnable (GL_LINE_STIPPLE);
glLineStipple (1, 0x00FF); // dashed line
glLineWidth (1.0);

switch ( m_tempCoordType )
{
case 1: // -------------------------------------- RECTANGULAR
{
// m_tempCoordType = 0; // delete each time
CPoint3D p [] = {
CPoint3D ( m_tempCoordAbs.x,m_tempCoordAbs.y,m_tempCoordAbs.z ),
CPoint3D ( m_tempCoordAbs.x,m_tempCoordRef.y,m_tempCoordAbs.z ),
CPoint3D ( m_tempCoordRef.x,m_tempCoordRef.y,m_tempCoordAbs.z ),
CPoint3D ( m_tempCoordRef.x,m_tempCoordAbs.y,m_tempCoordAbs.z ),
CPoint3D ( m_tempCoordAbs.x,m_tempCoordAbs.y,m_tempCoordRef.z ),
CPoint3D ( m_tempCoordAbs.x,m_tempCoordRef.y,m_tempCoordRef.z ),
CPoint3D ( m_tempCoordRef.x,m_tempCoordRef.y,m_tempCoordRef.z ),
CPoint3D ( m_tempCoordRef.x,m_tempCoordAbs.y,m_tempCoordRef.z ) };

glColor3f ( 1.0f, 1.0f, 1.0f ); // Yellow
glBegin ( GL_LINE_LOOP ); // Not GL_POLYGON
   for ( i = 0; i < 4; i++ ) glVertex3f(p[i].x, p[i].y, p[i].z);
glEnd ();

glBegin ( GL_LINE_LOOP );
   for ( i = 4; i < 8; i++ ) glVertex3f(p[i].x, p[i].y, p[i].z);
glEnd ();

glBegin ( GL_LINES );
for ( i = 0; i < 4; i++ )
{
glVertex3f(p[i].x, p[i].y, p[i].z);
glVertex3f(p[i+4].x, p[i+4].y, p[i+4].z);
}
break;
}
case 2: // -------------------------------------- CYLINDRICAL
{
// Draw a box before pt0 gets changed
glColor3f ( 1.0f, 1.0f, 1.0f );
glBegin ( GL_LINE_LOOP ); // Not GL_POLYGON
glVertex3f( pt0.x, pt0.y, pt0.z );
glVertex3f( pt0.x, pt0.y, m_tempCoordAbs.z );
glVertex3f( m_tempCoordAbs.x, m_tempCoordAbs.y, m_tempCoordAbs.z );
glVertex3f( m_tempCoordAbs.x, m_tempCoordAbs.y, pt0.z );
glEnd ();
// circle 1 base - at pt0, rad = m_value1KEY= m_tempCoordKey.x
CircleFlatZ ( RED, SOLID, pt0, m_tempCoordKey.x );
// circle 2 ------ at pt0 + m_value3KEY, rad = m_value1KEY
// pt0.z += m_tempCoordKey.z
pt0.z += m_tempCoordKey.z;
CircleFlatZ ( RED, SOLID, pt0, m_tempCoordKey.x );
break;
}
case 3: // -------------------------------------- SPHERICAL
{
// Draw a triangle before pt0 gets changed
glColor3f ( 1.0f, 1.0f, 1.0f );
glBegin ( GL_LINE_STRIP ); // Not GL_POLYGON
glVertex3f( pt0.x, pt0.y, pt0.z );
glVertex3f( m_tempCoordAbs.x, m_tempCoordAbs.y, m_tempCoordAbs.z );
glVertex3f( pt0.x, pt0.y, m_tempCoordAbs.z );
glEnd ();
// circle 1 base - at pt0, rad = m_value1KEY
CircleFlatZ ( RED, SOLID, pt0, m_tempCoordKey.x );
// circle 2 ------ at pt0 + ptABS.z, rad = sqrt ( )
float qqq = pow ( m_tempCoordAbs.x, 2 ) + pow ( m_tempCoordAbs.y, 2 );
float radius = (float) sqrt ( qqq );
pt0.z += m_tempCoordAbs.z;
CircleFlatZ ( RED, SOLID, pt0, radius );
break;
}
glEnd ();
glDisable (GL_LINE_STIPPLE);
 

========================================================================

HOW A POINT IS CREATED / DRAWN

Gxxx.cpp

------------------------------------------------------------------------- Elem.h
public:
CElemPoint (CGDoc* pDoc, CPoint3D pt)
: CElem (pt)
{
m_elemType = ET_POINT;
};
----------------------------------------------------------------------- Elem.cpp
int CElemPoint::GenerateVertices ()
{
// No need to generate vertices since we use DIsplay-List
return 6;
}
----------------------------------------------------------------------- Elem.cpp
void CElemPoint::CreateGLcalls ()
{
// No need to generate vertices since we use DIsplay-List
}
----------------------------------------------------------------------- Elem.cpp
void CElemPoint::DrawElemOneVpt ( int flagVisual, DISPLAY_MODE mode,
DISPLAY_MODE cull, GLenum renderMode )
{
// Set transformation
GLfloat mmm[16] = { m_mxAxisX.x, m_mxAxisX.y, m_mxAxisX.z, 0.0f ,
m_mxAxisY.x, m_mxAxisY.y, m_mxAxisY.z, 0.0f ,
m_mxAxisZ.x, m_mxAxisZ.y, m_mxAxisZ.z, 0.0f ,
m_mxOrigin.x, m_mxOrigin.y, m_mxOrigin.z, 1.0f };
glLoadIdentity();
glMultMatrixf(mmm);

// If re-drawing for pick purpose, give pick id ...
if (renderMode == GL_SELECT) glLoadName ((GLuint)this);

glCallList ( DL_POINT ); /// (GLuint) this ); // GLuint id = (GLuint)this;

// Make sure to clear so subsequent items get NULL pick id
glLoadName ( NULL ); // non-pickable

// Visual cues --- such as vertical/horizontal move indicator
if (flagVisual > 0)
{
if (m_bZShift) glCallList ( DL_VISUAL2);
else glCallList ( DL_VISUAL1);
}
}
=========================================================================

HOW A CUBE IS CREATED / DRAWN

Gxxx.cpp

----------------------------------------------------------------------- Elem.cpp
CElemCube::CElemCube ( CGDoc* pDoc, BOOL flag,
float w, float h, float l, const CPoint3D& pt )
:CElem (pt)
{
m_elemType = ET_CUBE;

m_width = w;
m_height = h;
m_length = l;

m_R = 1.0f;
m_G = 1.0f;
m_B = 0.2f;
}
----------------------------------------------------------------------- Elem.cpp
int CElemCube::GenerateVertices ()
{
const float H = m_height;
const float W = m_width;
const float L = m_length;

CPoint3D p0 ( 0.0f, 0.0f, 0.0f ); v[0] = p0;
CPoint3D p1 ( 0.0f, H, 0.0f ); v[1] = p1;
CPoint3D p2 ( 0.0f, H, -L ); v[2] = p2;
CPoint3D p3 ( 0.0f, 0.0f, -L ); v[3] = p3;
CPoint3D p4 ( W, 0.0f, 0.0f ); v[4] = p4;
CPoint3D p5 ( W, H, 0.0f ); v[5] = p5;
CPoint3D p6 ( W, H, -L ); v[6] = p6;
CPoint3D p7 ( W, 0.0f, -L ); v[7] = p7;
return 8;
}
----------------------------------------------------------------------- Elem.cpp
void CElemCube::CreateGLcalls ()
{
CreatePolygonWithNormal (4, v, 0,1,2,3 );
CreatePolygonWithNormal (4, v, 7,6,5,4 );
CreatePolygonWithNormal (4, v, 0,4,5,1 );
CreatePolygonWithNormal (4, v, 1,5,6,2 );
CreatePolygonWithNormal (4, v, 2,6,7,3 );
CreatePolygonWithNormal (4, v, 0,3,7,4 );
}

=========================================================================

HOW AN ELEMENT IS DRAWN

Gxxx.cpp

-------------------------------------------------------------- CGView.cpp
void CGView::OnDraw(CDC* pDC)
{
HGLRC hRC = wglGetCurrentContext(); // Check if any RC is "current"
HDC hDC = wglGetCurrentDC();
VERIFY (wglMakeCurrent (m_hDC, m_hRC));
DrawMyScene();
SwapBuffers (m_hDC); // double buffering - glFlush() not needed
if (hRC && hDC) ::wglMakeCurrent (hDC, hRC);
}
-------------------------------------------------------------- CGView.cpp
void CGView::DrawMyScene()
{
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity ();
if (m_shadeMode == DM_SMOOTH) glShadeModel ( GL_SMOOTH );
else glShadeModel ( GL_FLAT );
glEnable ( GL_DEPTH_TEST );
glClearColor (0.0f, 0.0f, 0.1f, 1.0f); // set background color
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushAttrib ( GL_ALL_ATTRIB_BITS );
glDisable ( GL_LIGHTING ); // to draw flat lines 96-5-8
//glColorMaterial (GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
//glEnable ( GL_COLOR_MATERIAL );
DrawVisCueFkFrame();
glCallList ( DL_CAGE );
glCallList ( DL_AXIS );
DrawCurPlane ();
glEnable ( GL_LIGHTING );
glPopAttrib ();
DrawAllElems();
}
-------------------------------------------------------------- CGView.cpp
void CGView::DrawAllElems ()
{
CGDoc* pDoc = GetDocument();
for (POSITION pos = pDoc->m_elemList.GetHeadPosition(); pos != NULL;)
{ CElem* p = (CElem*)pDoc->m_elemList.GetNext(pos);
p->DrawElemOneVpt ( 1, m_displayMode, m_cullMode, m_renderMode );
} }
---------------------------------------------------------------- Elem.cpp
void CElem::DrawElemOneVpt ( int flagVisual, DISPLAY_MODE mode,
DISPLAY_MODE cull, GLenum renderMode )
{
GLfloat colorA[] = { m_R, m_G, m_B, 1.0f };
glMaterialfv( GL_FRONT,GL_AMBIENT_AND_DIFFUSE,colorA );
if ( mode == DM_SHADED ) glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );
else if ( mode == DM_WIRE ) glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
else if ( mode == DM_HLR )
{ glPolygonMode ( GL_FRONT, GL_FILL );
glPolygonMode ( GL_BACK, GL_LINE ); };
////
if ( cull == DM_CULL )
{ glCullFace ( GL_BACK );
glEnable ( GL_CULL_FACE ); }
else
{ glCullFace ( GL_BACK );
glDisable ( GL_CULL_FACE ); };
////
GLfloat mmm[16] = { m_mxAxisX.x, m_mxAxisX.y, m_mxAxisX.z, 0.0f ,
m_mxAxisY.x, m_mxAxisY.y, m_mxAxisY.z, 0.0f ,
m_mxAxisZ.x, m_mxAxisZ.y, m_mxAxisZ.z, 0.0f ,
m_mxOrigin.x, m_mxOrigin.y, m_mxOrigin.z, 1.0f };
glLoadIdentity();
glMultMatrixf(mmm);
if (renderMode == GL_SELECT) glLoadName ((GLuint)this);
glCallList ( (GLuint) this ); // GLuint id = (GLuint)this;
glLoadName ( NULL ); // non-pickable
// Visual cues --- such as vertical/horizontal move indicator
if (flagVisual > 0)
{ if (m_bZShift) glCallList ( DL_VISUAL2 );
else glCallList ( DL_VISUAL1 );
} }

=========================================================================

DISPLAY LIST USAGE

Gxxx.cpp

--------------------------------------------------------------- AGlobal.h
enum DISPLAY_LIST // Display list id
{
DL_ZERO_ILLEGAL,
DL_AXIS,
DL_CAGE,
DL_POINT,
DL_CUR_PLANE,
DL_VISUAL1,
};
------------------------------------------------------ CGDocFK_kernel.cpp
void CGDoc::FromOnNewDocument()
{
HGLRC hRC = wglGetCurrentContext(); // Check if any RC is "current"
HDC hDC = wglGetCurrentDC();
VERIFY (wglMakeCurrent (m_master_hDC, m_master_hRC));
CreateDisplayList ( DL_CAGE );
CreateDisplayList ( DL_AXIS );
CreateDisplayList ( DL_POINT );
CreateDisplayList ( DL_CUR_PLANE );
CreateDisplayList ( DL_VISUAL1 );
if (hRC && hDC) ::wglMakeCurrent (hDC, hRC);
}
------------------------------------------------------ CGDocFK_kernel.cpp
void CGDoc::CreateDisplayList ( DISPLAY_LIST no )
{
glNewList ( no, GL_COMPILE);
switch ( no )
{
case DL_VISUAL1:
float s = 0.3f;
glPushAttrib ( GL_ALL_ATTRIB_BITS );
glDisable ( GL_LIGHTING );
GLfloat colorB[] = {0.0f, 0.5f, 0.8f, 1.0f};
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,colorB);
glBegin (GL_LINES);
glVertex3f (0.0f,-2.0f,0.0f);
glVertex3f (0.0f, 2.0f,0.0f);
glEnd();
glEnable ( GL_LIGHTING );
glPopAttrib ();
case DL_AXIS: // Axis
glBegin ( GL_LINES );
glColor3f (1.0f, 0.0f, 0.0f);
glVertex3f ( 0.0f, 0.0f, 0.0f );
glVertex3f ( size, 0.0f, 0.0f );
glEnd();
case DL_POINT: // Point element
glPushAttrib ( GL_ALL_ATTRIB_BITS );
glDisable ( GL_LIGHTING );
glColor3f (1.0f, 1.0f, 0.0f);
glBegin ( GL_LINES );
glVertex3f ( 0.0f , 0.0f , s );
glVertex3f ( 0.0f , 0.0f , -s );
glVertex3f ( s , 0.0f , 0.0f );
glEnd();
glEnable ( GL_LIGHTING );
glPopAttrib ();
case DL_CUR_PLANE: /// Current plane
glColor3f (0.4f, 0.4f, 0.4f);
glBegin ( GL_LINES );
for (int k = 0; k < total; k++)
{
glVertex3f ( xxx, yy, zzz );
glVertex3f (-xxx, yy, zzz );
xx += increment;
};
glEnd ();
glEndList();
}
-------------------------------------------------------------- CGView.cpp
void CGView::DrawMyScene()
{ ........
........
glPushAttrib ( GL_ALL_ATTRIB_BITS );
glDisable ( GL_LIGHTING ); // to draw flat lines 96-5-8
DrawVisCueFkFrame();
glCallList ( DL_CAGE );
glCallList ( DL_AXIS );
DrawCurPlane ();
glEnable ( GL_LIGHTING );
glPopAttrib ();
DrawAllElems();
}
------------------------------------------------------------- CGView.cpp
void CGView::DrawCurPlane ()
{
CGDoc* pDoc = GetDocument();
CCurPlane* pCP = pDoc->m_pCurPlane;
GLfloat mmm[16] = {
pCP->m_mxAxisX.x, pCP->m_mxAxisX.y, pCP->m_mxAxisX.z, 0.0f ,
pCP->m_mxAxisY.x, pCP->m_mxAxisY.y, pCP->m_mxAxisY.z, 0.0f ,
pCP->m_mxAxisZ.x, pCP->m_mxAxisZ.y, pCP->m_mxAxisZ.z, 0.0f ,
pCP->m_mxOrigin.x, pCP->m_mxOrigin.y, pCP->m_mxOrigin.z, 1.0f };
glLoadIdentity(); /// 97-4-19 did not work
glMultMatrixf(mmm);
glColor3f (0.0f, 0.7f, 1.0f); // CP color
glCallList ( DL_CUR_PLANE ); // Display List
glLoadIdentity(); // needed for proper polygon display
}
--------------------------------------------------------------- Elem.cpp
void CElemPoint::DrawElemOneVpt ( int flagVisual, DISPLAY_MODE mode,
DISPLAY_MODE cull, GLenum renderMode )
{
GLfloat mmm[16] = { m_mxAxisX.x, m_mxAxisX.y, m_mxAxisX.z, 0.0f ,
m_mxAxisY.x, m_mxAxisY.y, m_mxAxisY.z, 0.0f ,
m_mxAxisZ.x, m_mxAxisZ.y, m_mxAxisZ.z, 0.0f ,
m_mxOrigin.x, m_mxOrigin.y, m_mxOrigin.z, 1.0f };
glLoadIdentity();
glMultMatrixf(mmm);
if (renderMode == GL_SELECT) glLoadName ((GLuint)this);
glCallList ( DL_POINT ); // Display List
glLoadName ( NULL ); // non-pickable
}
=========================================================================

HOW TO CREATE 2D LINE

Gxxx.cpp

-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine_1_IND (UINT, CPoint)
{
if ( ! m_bWhenIND ) return; // No piercing of CP
m_pointArray [ m_pointIndex++ ] = m_ptIND;
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine_1_KY3 (UINT, CPoint)
{
CPoint3D ppp ( m_value1KEY, m_value2KEY, m_value3KEY );
// Now project onto current plane - show visual cue line

///////////////////////////////////////
// Apply inverse transformation to bring vertices to local coordinate
CMat4x4 mmm ( m_pCurPlane->m_mxAxisX, m_pCurPlane->m_mxAxisY,
m_pCurPlane->m_mxAxisZ, m_pCurPlane->m_mxOrigin );
CMat4x4 ttt = mmm.InverseByTranspose();
CPoint3D transformed = ttt.vM ( ppp ); // = [V] x [M]
transformed.z = 0.0f; // PROJECT !!!
CPoint3D projected = mmm.vM ( transformed ); // = [V] x [M]
m_pointArray [ m_pointIndex++ ] = projected;
//---------------------------------------------------------TEMPORARY
// visual cue between original pt and projected pt
m_ptVis1 = ppp;
m_ptVis2 = projected;
//---------------------------------------------------------TEMPORARY
///////////////////////////////////////
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::DrawVisCueFkFrame ( )
{
glBegin (GL_LINES);
glColor3f ( 1.0f, 0.0f, 0.0f );
glVertex3f ( m_ptVis1.x, m_ptVis1.y, m_ptVis1.z );
glVertex3f ( m_ptVis2.x, m_ptVis2.y, m_ptVis2.z );
glEnd ();
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine_2_IND (UINT, CPoint)
{
if ( ! m_bWhenIND ) return; // No piercing of CP
m_pointArray [ m_pointIndex++ ] = m_ptIND;
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine_2_KY3 (UINT, CPoint)
{
CPoint3D ppp ( m_value1KEY, m_value2KEY, m_value3KEY );
///////////////////////////////////////
// Apply inverse transformation to bring vertices to local coordinate
CMat4x4 mmm ( m_pCurPlane->m_mxAxisX, m_pCurPlane->m_mxAxisY,
m_pCurPlane->m_mxAxisZ, m_pCurPlane->m_mxOrigin );
CMat4x4 ttt = mmm.InverseByTranspose();
CPoint3D transformed = ttt.vM ( ppp ); // = [V] x [M]
transformed.z = 0.0f; // PROJECT !!!
CPoint3D projected = mmm.vM ( transformed ); // = [V] x [M]
m_pointArray [ m_pointIndex++ ] = projected;
//---------------------------------------------------------TEMPORARY
// visual cue between original pt and projected pt
m_ptVis1 = ppp;
m_ptVis2 = projected;
//---------------------------------------------------------TEMPORARY
///////////////////////////////////////
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine_2_END (UINT, CPoint)
{
CreateLine ( m_pointArray [0] ); // CreateLine
NXS (1);
}
----------------------------------------------------------------------H1doc.h
void CreateLine (const CPoint3D& pt3d1)
{ CreateAndDisplay (ET_LINE, pt3d1);};

-----------------------------------------------------------H1docFK_kernel.cpp
void CGDoc::CreateAndDisplay (ELEM_TYPE type,
const CPoint3D& pt, // origin point
const CPoint3D& dir, // direction vector
const CPoint3D& ori, // orientation vector
float height, float width, float length )
{
// This function creates a new element and then displays it

// 1. Create C++ object (only persistent data set)
CElemBase1D* pE = m_pElemCur =
NewElem ( type, pt, dir, ori, height, width, length );

if (pE == NULL) return; // New elem creation failed

// 2. Add to the list
m_elemList.AddTail (pE);
SetModifiedFlag();

// 3. Generate vertices
pE->GenerateVertices();

// 4. Create OpenGL calls and save them in a "master" display list
HGLRC hRC = wglGetCurrentContext(); // just a test

/VERIFY (wglMakeCurrent(m_master_hDC,m_master_hRC));
glNewList ((GLuint)pE, GL_COMPILE);
pE->CreateGLcalls ();
glEndList ();
/VERIFY (wglMakeCurrent (NULL, NULL));

// 5. Display the element
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{
CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
pView->Invalidate(); // Calls OnDraw();
}
}
-----------------------------------------------------------H1docFK_kernel.cpp
CElemBase1D* CGDoc::NewElem ( ELEM_TYPE elemType, const CPoint3D& pt,
const CPoint3D& dir, const CPoint3D& ori,
float height, float width, float length )
{
CElemBase1D* pElem;
switch (elemType)
{
case ET_LINE: pElem = new CElemLine (this, pt); break;
case ET_LINE_3D: pElem = new CElemLine3d (this, pt); break;
} }
------------------------------------------------------------------H1elem1.cpp
CElemLine::CElemLine (CGDoc* pDoc, CPoint3D pt)
: CElemBase3D (pt)
{
m_totalVertex = pDoc->m_pointIndex;
m_pVertex2D = new CPoint2D [ m_totalVertex ];

// Copy into Line object even if it is available in Doc, since we dont
// want to access Doc from GenerateVertices

m_pVertex3D = new CPoint3D [ m_totalVertex ];
for ( int i = 0; i < m_totalVertex; i++ )
m_pVertex3D [i] = pDoc->m_pointArray [i];

// Need identical transformation as the current plane
m_mxOrigin = pDoc->m_pointArray [0]; // pDoc->m_pCurPlane->m_mxOrigin;
m_mxAxisX = pDoc->m_pCurPlane->m_mxAxisX;
m_mxAxisY = pDoc->m_pCurPlane->m_mxAxisY;
m_mxAxisZ = pDoc->m_pCurPlane->m_mxAxisZ;
}
------------------------------------------------------------------H1elem1.cpp
int CElemLine::GenerateVertices ()
{
// Create 2d vertices at origin transformed from the original loc
// Convert to origin using CP

// Apply inverse transformation to bring vertices to local coordinate
CMat4x4 mmm ( m_mxAxisX, m_mxAxisY, m_mxAxisZ, m_mxOrigin );
CMat4x4 ttt = mmm.InverseByTranspose();
CPoint3D transformed;

for ( int i = 0; i < m_totalVertex; i++ )
{
transformed = ttt.vM ( m_pVertex3D [i] ); // = [V] x [M]
m_pVertex2D [i].x = transformed.x ;
m_pVertex2D [i].y = transformed.y ;
}
return m_totalVertex;
}
------------------------------------------------------------------H1elem1.cpp
void CElemLine::CreateGLcalls ()
{
glBegin ( GL_LINE_STRIP );
for ( int i = 0; i < m_totalVertex; i++ )
glVertex3f ( m_pVertex2D[i].x, m_pVertex2D[i].y, 0.0f );
glEnd();
}

=========================================================================

HOW TO CREATE 3D LINE

Gxxx.cpp

-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine3d_1_IND (UINT, CPoint)
{
if ( ! m_bWhenIND ) return; // No piercing of CP
m_pointArray [ m_pointIndex++ ] = m_ptIND;
SetRubberBandAnchorAllVpts ( m_savePt1 );
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine3d_1_KY3 (UINT, CPoint)
{
CPoint3D ppp ( m_value1KEY, m_value2KEY, m_value3KEY );
m_pointArray [ m_pointIndex++ ] = ppp;
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine3d_2_IND (UINT, CPoint)
{
if ( ! m_bWhenIND ) return; // No piercing of CP
m_pointArray [ m_pointIndex++ ] = m_ptIND;
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine3d_2_KY3 (UINT, CPoint)
{
CPoint3D ppp ( m_value1KEY, m_value2KEY, m_value3KEY );
m_pointArray [ m_pointIndex++ ] = ppp;
NXS (2);
}
-------------------------------------------------------------H1docFK_elem.cpp
void CGDoc::CreateLine3d_2_END (UINT, CPoint)
{
// End the current multi-line creation
CreateLine3D ( m_pointArray [0] ); // CreateLine
NXS (1);
}
----------------------------------------------------------------------H1doc.h
void CreateLine3D (const CPoint3D& pt3d1)
{ CreateAndDisplay (ET_LINE_3D, pt3d1);};
-----------------------------------------------------------H1docFK_kernel.cpp
void CGDoc::CreateAndDisplay (ELEM_TYPE type,
const CPoint3D& pt, // origin point
const CPoint3D& dir, // direction vector
const CPoint3D& ori, // orientation vector
float height, float width, float length )
{
// This function creates a new element and then displays it

// 1. Create C++ object (only persistent data set)
CElemBase1D* pE = m_pElemCur =
NewElem ( type, pt, dir, ori, height, width, length );

if (pE == NULL) return; // New elem creation failed

// 2. Add to the list
m_elemList.AddTail (pE);
SetModifiedFlag();

// 3. Generate vertices
pE->GenerateVertices();

// 4. Create OpenGL calls and save them in a "master" display list
HGLRC hRC = wglGetCurrentContext(); // just a test

/VERIFY (wglMakeCurrent(m_master_hDC,m_master_hRC));
glNewList ((GLuint)pE, GL_COMPILE);
pE->CreateGLcalls ();
glEndList ();
/VERIFY (wglMakeCurrent (NULL, NULL));

// 5. Display the element
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{
CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
pView->Invalidate(); // Calls OnDraw();
}
}
-----------------------------------------------------------H1docFK_kernel.cpp
CElemBase1D* CGDoc::NewElem ( ELEM_TYPE elemType, const CPoint3D& pt,
const CPoint3D& dir, const CPoint3D& ori,
float height, float width, float length )
{
CElemBase1D* pElem;
switch (elemType)
{
case ET_LINE: pElem = new CElemLine (this, pt); break;
case ET_LINE_3D: pElem = new CElemLine3d (this, pt); break;
} }
------------------------------------------------------------------H1elem1.cpp
CElemLine3d::CElemLine3d (CGDoc* pDoc, CPoint3D pt)
: CElemBase3D (pt)
{
m_totalVertex = pDoc->m_pointIndex;
m_pVertex3D = new CPoint3D [ m_totalVertex ];
CPoint3D delta = pDoc->m_pointArray [0];
for (int i = 0; i < m_totalVertex; i++)
{
// translate the first pt (pivot) to local origin
m_pVertex3D [i] = pDoc->m_pointArray [i] - delta;
};
m_mxOrigin = delta;
}
------------------------------------------------------------------H1elem1.cpp
int CElemLine3d::GenerateVertices ()
------------------------------------------------------------------H1elem1.cpp
void CElemLine3d::CreateGLcalls ()
{
glBegin ( GL_LINE_STRIP );
for ( int i = 0; i < m_totalVertex; i++ )
glVertex3f (m_pVertex3D[i].x,m_pVertex3D[i].y,m_pVertex3D[i].z);
glEnd();
}

=========================================================================

VISUAL CUES

Gxxx.cpp

------------------------------------------------------------ H1DocFK_elem.cpp
void CGDoc::CreateLine_1_KY3 (UINT, CPoint)
{
CPoint3D ppp ( m_value1KEY, m_value2KEY, m_value3KEY );
// Now project onto current plane - show visual cue line

CPoint3D transformed = m_vcMatrixT.vM ( ppp ); // = [V] x [M]
transformed.z = 0.0f; // PROJECT !!!
CPoint3D projected = m_vcMatrixM.vM ( transformed ); // = [V] x [M]
m_vcPointArray3 [ m_pointIndex ] = projected;
m_pointArray [ m_pointIndex++ ] = projected;
//---------------------------------------------------------TEMPORARY
// visual cue between original pt and projected pt
m_vcPointArray1 [m_vcPointIndex] = ppp;
m_vcPointArray2 [m_vcPointIndex] = projected;
m_vcPointIndex++;
DrawVisCueAllVpts ();
//---------------------------------------------------------TEMPORARY
NXS (2);
}
------------------------------------------------------------ H1DocFK_elem.cpp
void CGDoc::DrawVisCueAllVpts ( )
{
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{
CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
pView->Invalidate(); // Calls OnDraw();
// ----------- Set DC and RC and
// ----------- Directoly can call DrawVisCueTempElem3D ?????
}
}
------------------------------------------------------------ H1view.cpp
void CGView::OnDraw(CDC* pDC)
{
HGLRC hRC = wglGetCurrentContext();
HDC hDC = wglGetCurrentDC();
VERIFY (wglMakeCurrent (m_hDC, m_hRC)); // Vitally needed
/////
DrawMyScene();
/////
SwapBuffers (m_hDC); // float buffering - glFlush() not needed
if (hRC && hDC) ::wglMakeCurrent (hDC, hRC);
}
------------------------------------------------------------ H1view.cpp
void CGView::DrawMyScene()
{
CGDoc* pDoc = GetDocument();
glMatrixMode ( GL_MODELVIEW ); // should be GL_MODELVIEW 97-4-25 NO!
glLoadIdentity ();
if (m_shadeMode == DM_SMOOTH) glShadeModel ( GL_SMOOTH );
else glShadeModel ( GL_FLAT );
glEnable ( GL_DEPTH_TEST );
glClearColor (0.0f, 0.0f, 0.1f, 1.0f); // set background color
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// < I > --- Projection + Lighting
glColor3f (0.0f, 1.0f, 0.0f);
DrawAllElems();
glLoadIdentity(); // Must clear ModelView matrix
/////////////////////////////////////////////////////////PUSH 1
glPushAttrib ( GL_ALL_ATTRIB_BITS );
glDisable ( GL_LIGHTING ); // to draw flat lines 96-5-8
/////////////////////////////////////////////////////////PUSH 1
// < II > --- Projection + No lighting
glCallList ( DL_AXIS ); // DrawAxes ( 5.0f );
glCallList ( DL_CAGE ); // DrawCagee ( 1.5f );
DrawCurPlane (); // DrawVptCurPlane ();
// Temporary Displays....
pDoc->DrawVisCuePolygonMaking ();
pDoc->DrawVisCueTempElem3D ();
DrawVisCueLightPosition ();
///////////////////////////////////////PUSH 2
glMatrixMode (GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
///////////////////////////////////////PUSH 2
// < III > --- No projection + No lighting
DrawVisCueFkFrameOneVpt();
////////////////////////////////////////POP 2
glMatrixMode (GL_PROJECTION );
glPopMatrix ();
glMatrixMode (GL_MODELVIEW ); // added for consistency 97-4-26
////////////////////////////////////////POP 2
/////////////////////////////////////////////////////////POP 1
glEnable ( GL_LIGHTING );
glPopAttrib ();
/////////////////////////////////////////////////////////POP 1
}
------------------------------------------------------------ H1DocFK_elem.cpp
void CGDoc::DrawVisCueTempElem3D ( )
{
int i;
for ( i = 0; i < m_vcPointIndex; i++ )
{
glBegin (GL_LINES);
glColor3f ( 1.0f, 0.0f, 0.0f );
glVertex3f ( m_vcPointArray1[i].x, m_vcPointArray1[i].y,
m_vcPointArray1[i].z );
glVertex3f ( m_vcPointArray2[i].x, m_vcPointArray2[i].y,
m_vcPointArray2[i].z );
glEnd ();
};
glBegin (GL_LINE_STRIP);
glColor3f ( 1.0f, 1.0f, 0.0f );
for ( i = 0; i < m_pointIndex; i++ )
glVertex3f ( m_pointArray[i].x, m_pointArray[i].y,
m_pointArray[i].z );
glEnd ();
}
=========================================================================

HOW TO DRAW TEMP ELEMENT

Gxxx.cpp

------------------------------------------------------------ GDocFK_elem.cpp
void CGDoc::ElemTranslate_3_KY3 (UINT, CPoint pt)
{
// NOT DONE =======================
CPoint3D keyinPt ( m_value1KEY, m_value2KEY, m_value3KEY );
m_savePt2 = keyinPt;
m_tempPointArray [ m_tempPointTotal++ ] = m_savePt2; // vis cue
m_tempLineArray [ 1 ][ m_tempLineTotal++ ] = m_savePt2; // vis cue
NXS (3);
}
------------------------------------------------------------ GDocFK_elem.cpp
void CGDoc::ElemTranslate_3_KY1 (UINT, CPoint)
{
CPoint3D dir = m_savePt2 - m_savePt1;
CPoint3D pt = dir * m_value1KEY;
pt = pt + m_savePt1;

if ( m_bCopyMove )
{ // -------------------------> COPY mode
TranslateCopyAndDisplay (m_pElemSEL, dir, m_value1KEY);
}
else
{ // -------------------------> MOVE mode
m_pElemSEL->Translate ( this, pt );
InvalidateAllVpts ();
};
m_pElemSEL->Unhighlight ();
}

----------------------------------------------------------------- GDoc.h
int m_tempPointTotal;
int m_tempLineTotal;
int m_tempMultiLineTotal1;
int m_tempMultiLineTotal2;
int m_tempMultiLineTotal3;
int m_tempCircleTotal;
int m_tempArrowTotal;

CPoint3D m_tempPointArray [ 100 ];
CPoint3D m_tempLineArray [ 2 ][ 100 ];
CPoint3D m_tempMultiLineArray1 [ 100 ];
CPoint3D m_tempMultiLineArray2 [ 100 ];
CPoint3D m_tempMultiLineArray3 [ 100 ];
CPoint3D m_tempCircleArray [ 3 ][ 100 ];
CPoint3D m_tempArrowArray [ 2 ][ 100 ];

G_COLOR m_tempPointColor [ 100 ];
G_COLOR m_tempLineColor [ 100 ];
G_COLOR m_tempMultiLineColor1;
G_COLOR m_tempMultiLineColor2;
G_COLOR m_tempMultiLineColor3;
G_COLOR m_tempCircleColor [ 100 ];
G_COLOR m_tempArrowColor [ 100 ];

G_STYLE m_tempPointStyle [ 100 ];
G_STYLE m_tempLineStyle [ 100 ];
G_STYLE m_tempMultiLineStyle1;
G_STYLE m_tempMultiLineStyle2;
G_STYLE m_tempMultiLineStyle3;
G_STYLE m_tempCircleStyle [ 100 ];
G_STYLE m_tempArrowStyle [ 100 ];

public:
void DrawAllTempElems ();
void TempPoint ( G_COLOR, G_STYLE, const CPoint3D& );
void TempLine ( G_COLOR, G_STYLE, const CPoint3D&, const CPoint3D& );
void TempMultiLine1 ( G_COLOR, G_STYLE, const CPoint3D& );
void TempMultiLine2 ( G_COLOR, G_STYLE, const CPoint3D& );
void TempMultiLine3 ( G_COLOR, G_STYLE, const CPoint3D& );
void TempCircle ( G_COLOR, G_STYLE, const CPoint3D&, const CPoint3D&,
const CPoint3D& );
void TempArrow ( G_COLOR, G_STYLE, const CPoint3D&, const CPoint3D& );

void ClearTempAll () { m_tempPointTotal = m_tempLineTotal =
m_tempMultiLineTotal1 = m_tempMultiLineTotal2 =
m_tempMultiLineTotal3 = m_tempCircleTotal =
m_tempArrowTotal = 0; };
void ClearTempPoint () { m_tempPointTotal = 0; };
void ClearTempLine () { m_tempLineTotal = 0; };
void ClearTempMultiLineAll () { m_tempMultiLineTotal1 = m_tempMultiLineTotal2 =
m_tempMultiLineTotal3 = 0; };
void ClearTempMultiLine1 () { m_tempMultiLineTotal1 = 0; };
void ClearTempMultiLine2 () { m_tempMultiLineTotal2 = 0; };
void ClearTempMultiLine3 () { m_tempMultiLineTotal3 = 0; };
void ClearTempCircle () { m_tempCircleTotal = 0; };
void ClearTempArrow () { m_tempArrowTotal = 0; };

void InvalidateAllVpts ();

---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::FromOnNewDocument()
{
// initialize temporary element counters
m_tempPointTotal = 0;
m_tempLineTotal = 0;
m_tempMultiLineTotal1 = 0;
m_tempMultiLineTotal2 = 0;
m_tempMultiLineTotal3 = 0;
m_tempCircleTotal = 0;
m_tempArrowTotal = 0;
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::InvalidateAllVpts ()
{
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{
CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
pView->Invalidate(); // Calls OnDraw();
}
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::DrawAllTempElems ()
{
int i;

// --------------------------------------------------- Points
glBegin ( GL_POINTS );
for ( i = 0; i < m_tempPointTotal; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempPointArray[i].x ,
m_tempPointArray[i].y ,
m_tempPointArray[i].z );
}
glEnd ();

// --------------------------------------------------- Lines
glBegin ( GL_LINES );
for ( i = 0; i < m_tempLineTotal; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempLineArray[0][i].x ,
m_tempLineArray[0][i].y ,
m_tempLineArray[0][i].z );
glVertex3f ( m_tempLineArray[1][i].x ,
m_tempLineArray[1][i].y ,
m_tempLineArray[1][i].z );
}
glEnd ();

// ------------------------------------------------ Multi-Line 1
glBegin ( GL_LINE_STRIP );
for ( i = 0; i < m_tempMultiLineTotal1; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempMultiLineArray1[i].x ,
m_tempMultiLineArray1[i].y ,
m_tempMultiLineArray1[i].z );
}
glEnd ();
// ------------------------------------------------ Multi-Line 2
glBegin ( GL_LINE_STRIP );
for ( i = 0; i < m_tempMultiLineTotal2; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempMultiLineArray2[i].x ,
m_tempMultiLineArray2[i].y ,
m_tempMultiLineArray2[i].z );
}
glEnd ();
// ------------------------------------------------ Multi-Line 3
glBegin ( GL_LINE_STRIP );
for ( i = 0; i < m_tempMultiLineTotal3; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempMultiLineArray3[i].x ,
m_tempMultiLineArray3[i].y ,
m_tempMultiLineArray3[i].z );
}
glEnd ();

// ------------------------------------------------ Circle

// --------------------------------------------------- Arrows
glBegin ( GL_LINES );
for ( i = 0; i < m_tempArrowTotal; i++ )
{
// glColor3f ( m_tempPointColor [i]
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempArrowArray[0][i].x ,
m_tempArrowArray[0][i].y ,
m_tempArrowArray[0][i].z );
glVertex3f ( m_tempArrowArray[1][i].x ,
m_tempArrowArray[1][i].y ,
m_tempArrowArray[1][i].z );
}
glEnd ();
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::TempPoint ( G_COLOR c, G_STYLE s, const CPoint3D& pt )
{
m_tempPointArray [ m_tempPointTotal ] = pt;
m_tempPointColor [ m_tempPointTotal ] = c;
m_tempPointStyle [ m_tempPointTotal ] = s;
m_tempPointTotal++;
InvalidateAllVpts ();
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::TempLine ( G_COLOR c, G_STYLE s, const CPoint3D& pt1,
const CPoint3D& pt2 )
{
m_tempLineArray [0][ m_tempLineTotal ] = pt1;
m_tempLineArray [1][ m_tempLineTotal ] = pt2;
m_tempLineColor [ m_tempLineTotal ] = c;
m_tempLineStyle [ m_tempLineTotal ] = s;
m_tempLineTotal++;
InvalidateAllVpts ();
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::TempMultiLine1 ( G_COLOR c, G_STYLE s, const CPoint3D& pt)
{
m_tempMultiLineArray1 [ m_tempMultiLineTotal1 ] = pt;
m_tempMultiLineColor1 = c;
m_tempMultiLineStyle1 = s;
m_tempMultiLineTotal1++;
InvalidateAllVpts ();
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::TempMultiLine2 ( G_COLOR c, G_STYLE s, const CPoint3D& pt)
{
m_tempMultiLineArray2 [ m_tempMultiLineTotal2 ] = pt;
m_tempMultiLineColor2 = c;
m_tempMultiLineStyle2 = s;
m_tempMultiLineTotal2++;
InvalidateAllVpts ();
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::TempMultiLine3 ( G_COLOR c, G_STYLE s, const CPoint3D& pt)
{
m_tempMultiLineArray3 [ m_tempMultiLineTotal3 ] = pt;
m_tempMultiLineColor3 = c;
m_tempMultiLineStyle3 = s;
m_tempMultiLineTotal3++;
InvalidateAllVpts ();
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::TempCircle ( G_COLOR c, G_STYLE s, const CPoint3D& pt1,
const CPoint3D& pt2, const CPoint3D& pt3 )
{
m_tempCircleArray [0][ m_tempCircleTotal ] = pt1;
m_tempCircleArray [1][ m_tempCircleTotal ] = pt2;
m_tempCircleArray [2][ m_tempCircleTotal ] = pt3;
m_tempCircleColor [ m_tempCircleTotal ] = c;
m_tempCircleStyle [ m_tempCircleTotal ] = s;
m_tempCircleTotal++;
InvalidateAllVpts ();
}
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::TempArrow ( G_COLOR c, G_STYLE s, const CPoint3D& pt1,
const CPoint3D& pt2 )
{
m_tempArrowArray [0][ m_tempArrowTotal ] = pt1;
m_tempArrowArray [1][ m_tempArrowTotal ] = pt2;
m_tempArrowColor [ m_tempArrowTotal ] = c;
m_tempArrowStyle [ m_tempArrowTotal ] = s;
m_tempArrowTotal++;
InvalidateAllVpts ();
}

=========================================================================

GRID SNAP

GDoc.h/cpp

--------------------------------------------------------------------- GDoc.h
float m_gridSize; // grid interval (for snapping)
int m_gridTotal; // total number of lines in grid
BOOL m_bGridSnap; // true = grid snap option is active
------------------------------------------------------------------- GDoc.cpp
void CGDoc::OnGridSnap()
{ m_bGridSnap = m_bGridSnap ? false : true;
CreateDisplayList ( DL_CUR_PLANE );
InvalidateAllVpts ();
----------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::CreateDisplayList ( DISPLAY_LIST no )
{ glNewList ( no, GL_COMPILE);
switch ( no )
case DL_AXIS: // Axis
case DL_POINT: // Point element
case DL_CUR_PLANE: /// Current plane
// Color of the current plane --- User-customizable 97-4-25
if (m_bGridSnap) glColor3f (0.0f, 0.0f, 0.6f);
else glColor3f (0.4f, 0.4f, 0.4f);
float xxx = yyy = m_gridSize * m_gridTotal;
float xx = yy = zzz = 0.0f ;
glBegin ( GL_LINES );
for (int k = 0; k < m_gridTotal; k++)
{ glVertex3f ( xxx, yy, zzz );
glVertex3f (-xxx, yy, zzz );
......
xx += m_gridSize; };
glEnd ();
glEndList();
------------------------------------------------------------------ GView.cpp
void CGView::OnLButtonDown(UINT nFlags, CPoint point)
{ CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view pointer of event-origin
if ( (!( nFlags & MK_CONTROL )) && // forced INDICATE working OK
PickOperation (point) ) // return true if something selected
pDoc->FK_dispenser (SEL, nFlags, point); // something selected
else
{ if ( GetWorldCPWhenIND (point))
{ pDoc->m_bWhenIND = true; // pierced
pDoc->GridSnapCheck (); } // Set m_ptIND accordingly
else pDoc->m_bWhenIND = false;
pDoc->FK_dispenser (IND, nFlags, point); // always called anyway
};
m_oldMousePt = point; // Save R-mouse-down point
---------------------------------------------------------- GDocFK_kernel.cpp
void CGDoc::GridSnapCheck ()
{ // This updates m_ptIND accordingly -- if grid snap option is on.
if ( m_bGridSnap == false ) return;
// 0. Pt = m_ptIND
// 1. Pt0 = Pt x MATRIX (-CP)
// 2. Using m_gridSIze, get new Pt0 at grid pt -- call it Pt0a
// 3. Pa = P0a x MATRIX (CP)
// 4. m_ptIND = Pa
CPoint3D pt0a;
CMat4x4 mmm (m_pCurPlane->m_mxAxisX,Y,Z // Set the current plane matrix
m_pCurPlane->m_mxOrigin );
CMat4x4 mmmT = mmm.InverseByTranspose (); // Create the inverse matrix
CPoint3D pt0 = mmmT.vM (m_ptIND); // Bring the point to the local origin
BOOL xDone = false;
// Adjust X to the closest grid point
float aaa = pt0.x;
yNext: // Second time - adjust Y to the closest grid point
int factor = ( aaa < 0.0f ) ? -1 : +1;
aaa *= factor;
int n = aaa / m_gridSize;
float smallerGridPt = n * m_gridSize;
float largerGridPt = smallerGridPt + m_gridSize;
float small = aaa - smallerGridPt;
float large = largerGridPt - aaa;
float newGridPt = ( small < large ) ? smallerGridPt : largerGridPt;
if (!xDone)
{ pt0a.x = newGridPt * factor; xDone = true;
aaa = pt0.y; goto yNext; }
else pt0a.y = newGridPt * factor;
// Bring the grid point back to the 3D space
m_ptIND = mmm.vM (pt0a);


=========================================================================

HOW I-SHAPE IS CREATED

Gxxx.cpp

------------------------------------------------------------- DocFK_elem.cpp
void CGDoc::CreateShapeI_1_KY3 (UINT, CPoint)
{ CPoint3D pt = GetKeyCoordinate (); // Input m_value1KEY,2,3
CPoint3D dir ( 0.0f, 0.0f, -1.0f );
CPoint3D ori ( 0.0f, 1.0f, 0.0f );
CreateShapeI ( pt, dir, ori, 1.0f, 0.5f );
--------------------------------------------------------------------- Doc.h
void CreateShapeI (const CPoint3D& pt, const CPoint3D& dir,
const CPoint3D& ori, float h, float w)
{ CreateAndDisplay (ET_SHAPE_I, pt, dir, ori, h, w);};
---------------------------------------------------------- DocFK_kernel.cpp
void CGDoc::CreateAndDisplay (ELEM_TYPE type,
const CPoint3D& pt, // origin point
const CPoint3D& dir, // direction vector
const CPoint3D& ori, // orientation vector
float height, float width, float length )
{
// This function creates a new element and then displays it

// 1. Create C++ object (only persistent data set)
CElemBase1D* pE = m_pElemCur =
NewElem ( type, pt, dir, ori, height, width, length );
if (pE == NULL) return; // New elem creation failed
// 2. Add to the list
m_elemList.AddTail (pE);
SetModifiedFlag();
// 3. Generate vertices
pE->GenerateVertices();
// 4. Create OpenGL calls and save them in a "master" display list
HGLRC hRC = wglGetCurrentContext(); // just a test
glNewList ((GLuint)pE, GL_COMPILE);
pE->CreateGLcalls ();
glEndList ();
// 5. Display the element
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{ CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
// pView->Invalidate(); // Calls OnDraw();
pView->Invalidate(false); // Calls OnDraw();
---------------------------------------------------------- DocFK_kernel.cpp
CElemBase1D* CGDoc::NewElem ( ELEM_TYPE elemType, const CPoint3D& pt,
const CPoint3D& dir, const CPoint3D& ori,
float height, float width, float length )
{ CElemBase1D* pElem;
switch (elemType)
{
case ET_EXT_POLYGON:
case ET_EXTRUDE:
pElem = new CElemExtrude ( m_pExtrudeElem2D,
pt, dir, ori, height, width, length );
break;
case ET_POINT:
pElem = new CElemPoint
(this, pt);
break;
case ET_LINE:
pElem = new CElemLine
(this, pt);
break;
case ET_LINE_3D:
pElem = new CElemLine3d
(this, pt);
break;
case ET_ELBOW:
pElem = new CElemElbow (this, 1, 0.2f, 1.0f, pt, dir, ori);
break;
case ET_ELBOW_3D:
pElem = new CElemElbow3D
(this, 1.f, 1.f,1.f, pt.x, pt.y, pt.z, 0.707f,0.707f,0.0f, 0.f,1.f,0.f );
break;
case ET_BOX:
pElem = new CElemBox ( pt, dir, ori, height, width );
break;
case ET_SHAPE_I:
pElem = new CElemShapeI ( pt, dir, ori, height, width );
break;
default:
pElem = NULL;
}
if (pElem) return pElem;
else return NULL;
------------------------------------------------------------------- GElem.h
public:
CElemShapeI ( float h, float w ) // For 3D aggregation only
{
// Constructor to be called if this 2D elem is used in 3D
m_totalVertex = 12;
m_height = h; m_width = w;
};

CElemShapeI ( const CPoint3D& pt, const CPoint3D& dir,
const CPoint3D& ori, float height, float width )
:CElemBase2D ( pt, dir, ori, height, width )
{ m_totalVertex = 12; };

CPoint2D m_vertex2D [ 12 ];

virtual int GenerateVertices ();
virtual void CreateGLcalls ();
------------------------------------------------------------- GElemBase.cpp
int CElemShapeI::GenerateVertices ()
{
m_pVertex2D = &m_vertex2D [0];

const int half = 12;

float w = m_width / 2.0f;
float h = m_height / 2.0f;
float m_height2 = m_height / 5.0f; // SHOULD BE GIVEN!!!!
float m_width2 = m_width / 5.0f; // SHOULD BE GIVEN!!!!
float h2 = h - m_height2;
float w2 = m_width2 / 2.0f;

m_vertex2D [0].x = w; m_vertex2D [0].y = h;
m_vertex2D [1].x = w; m_vertex2D [1].y = h2;
m_vertex2D [2].x = w2; m_vertex2D [2].y = h2;
m_vertex2D [3].x = w2; m_vertex2D [3].y = -h2;
m_vertex2D [4].x = w; m_vertex2D [4].y = -h2;
m_vertex2D [5].x = w; m_vertex2D [5].y = -h;
m_vertex2D [6].x = -w; m_vertex2D [6].y = -h;
m_vertex2D [7].x = -w; m_vertex2D [7].y = -h2;
m_vertex2D [8].x = -w2; m_vertex2D [8].y = -h2;
m_vertex2D [9].x = -w2; m_vertex2D [9].y = h2;
m_vertex2D[10].x = -w; m_vertex2D[10].y = h2;
m_vertex2D[11].x = -w; m_vertex2D[11].y = h;

return half;
------------------------------------------------------------- GElemBase.cpp
void CElemShapeI::CreateGLcalls ()
{
int index [ 12 ];
for (int i = 0; i < m_totalVertex; i++) index [i] = i;
CreatePolygonWithNormal ( m_totalVertex, m_vertex2D, index );
 

=========================================================================

HOW EXTRUDE-I-SHAPE IS CREATED

Gxxx.cpp

------------------------------------------------------------- DocFK_elem.cpp
void CGDoc::DRV_createExtShapeI (MSSG messageType, UINT nFlags, CPoint point)
------------------------------------------------------------- DocFK_elem.cpp
void CGDoc::CreateExtShapeI_1_KY3 (UINT, CPoint)
{ CPoint3D pt = GetKeyCoordinate (); // Input m_value1KEY,2,3
CPoint3D dir ( 0.0f, 0.0f, -1.0f );
CPoint3D ori ( 0.0f, 1.0f, 0.0f );
CElemShapeI elem2D ( 1.0f, 2.0f ); // pt3d, dir, ori );
m_pExtrudeElem2D = &elem2D; // NOTE: this elem was created on the stack
elem2D.GenerateVertices();
CreateExtrude ( pt, dir, ori, 0.5f, 0.5f, 1.0f );
----------------------------------------------------------------------- Doc.h
void CreateExtrude (const CPoint3D& pt, const CPoint3D& dir,
const CPoint3D& ori, float h, float w, float l)
{ CreateAndDisplay (ET_EXTRUDE, pt, dir, ori, h, w, l);};
---------------------------------------------------------- DocFK_kernel.cpp
void CGDoc::CreateAndDisplay (ELEM_TYPE type,
const CPoint3D& pt, // origin point
const CPoint3D& dir, // direction vector
const CPoint3D& ori, // orientation vector
float height, float width, float length )
{
// 1. Create C++ object (only persistent data set)
CElemBase1D* pE = m_pElemCur =
NewElem ( type, pt, dir, ori, height, width, length );
if (pE == NULL) return; // New elem creation failed
m_elemList.AddTail (pE);
SetModifiedFlag();
pE->GenerateVertices();
HGLRC hRC = wglGetCurrentContext(); // just a test
glNewList ((GLuint)pE, GL_COMPILE);
pE->CreateGLcalls ();
glEndList ();
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{ CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
pView->Invalidate(false); // Calls OnDraw();
}
---------------------------------------------------------- DocFK_kernel.cpp
CElemBase1D* CGDoc::NewElem ( ELEM_TYPE elemType, const CPoint3D& pt,
const CPoint3D& dir, const CPoint3D& ori,
float height, float width, float length )
{ CElemBase1D* pElem;
switch (elemType)
{
case ET_EXTRUDE:
pElem = new CElemExtrude ( m_pExtrudeElem2D,
pt, dir, ori, height, width, length );
---------------------------------------------------------- ElemBase.cpp
CElemExtrude::CElemExtrude ( CElemBase2D* pE, const CPoint3D& pt,
const CPoint3D& dir, const CPoint3D& ori,
float height, float width, float length )
:CElemBase3D ( pt, dir, ori, height, width, length )
{
m_R = 0.0f;
m_G = 0.99f;
m_B = 0.99f ;

m_pTemplateElem2D = pE;
// Set other defaults
CPoint3D n1 (0.0f, 0.0f, +1.0f); // default normal at end 1
// CPoint3D n2 (0.0f, 0.0f, -1.0f); // default normal at end 2
CPoint3D n2 (0.0f, 0.707f, -0.707f); // default normal at end 2
SetNormalFaceOne (n1);
SetNormalFaceTwo (n2);
m_taperFactor.x = m_taperFactor.y = 1.0f;
m_shiftDelta.x = m_shiftDelta.y = 0.0f;

// Get total and keep it
int half = m_totalVertex = m_pTemplateElem2D->GetTotalVertex2D();

// Take in all 2D vertex pts and keep them (for future elem modification)
m_pVertex2D = new CPoint2D [half];
for (int i = 0; i < half; i++)
m_pVertex2D [i] = m_pTemplateElem2D->m_pVertex2D [i];

// create 3D array on the heap & point to it with m_pVertex3D
int total = half * 2;
m_pVertex3D = new CPoint3D [total]; // make sure to delete later
// pierce using normals on both ends to get final vertices
// For now, just extend the other side
};
----------------------------------------------------------------- Elem.h
CElemBase3D ( const CPoint3D& pt,const CPoint3D& dir,const CPoint3D& ori,
float height, float width, float length )
: CElemBase2D ( pt, dir, ori, height, width )
{
// Input: pt is the element's origin point
// dir is the direction vector (OK if not normalized)
// ori is the orientation vector (OK if not normalized nor
// not normal to dir, as long as not colinear to dir)

m_length = length;
};
----------------------------------------------------------------- Elem.h
CElemBase2D (const CPoint3D& pt,const CPoint3D& dir,const CPoint3D& ori,
float height, float width = 1.0f )
: CElemBase1D ( pt )
{
// Input: pt is the element's origin point
// dir is the direction vector (OK if not normalized)
// ori is the orientation vector (OK if not normalized nor
// not normal to dir, as long as not colinear to dir)

// Set element-specific attributes
m_width = width;
m_height = height;

// Set Z-axis which is opposite of the direction
CPoint3D norm = dir.Normalize();
m_mxAxisZ.x = - norm.x;
m_mxAxisZ.y = - norm.y;
m_mxAxisZ.z = - norm.z;

// Set X-axis
CPoint3D x = ori * m_mxAxisZ;
m_mxAxisX = x.Normalize();

// Set Y-axis
m_mxAxisY = m_mxAxisZ * m_mxAxisX;
};
----------------------------------------------------------------- Elem.h
CElemBase1D (const CPoint3D& pt)
{
m_mxOrigin = pt;
m_highlight = false;
m_R = m_G = m_B = 0.5f; // default color setting
};
------------------------------------------------------------- ElemBase.cpp
int CElemExtrude::GenerateVertices ()
{
// This function (declared virtual at the base) is subclass-specific
// function to generate all points (vertices), assuming the element
// resides in the local coordinate system with end 1 at the origin,
// and with end 2 in the local y-direction. The height is measured in
// the local z-direction, the width in the local x-direction.

// a point contained in Face 1
CPoint3D planePt1 (0,0,0);

// a point contained in Face 2
CPoint3D planePt2 (m_shiftDelta.x, m_shiftDelta.y, -m_length);

// if no taperring, line vectors are all the same ..
CPoint3D lineVec = planePt1 - planePt2;

// if TAPER, all line vec are DIFFERENT
// if TAPER, all line vec are DIFFERENT
// if TAPER, all line vec are DIFFERENT
// if TAPER, all line vec are DIFFERENT

CPoint3D vvv;

// THIS IS A WASTE --- no need to pierce here!!!
for (int i = 0; i < m_totalVertex; i++)
{
vvv.x = ( m_pVertex2D [i] ).x ;
vvv.y = ( m_pVertex2D [i] ).y ;
vvv.z = 0.0f;

// Get pierced pts on Face 1
PierceLinePlane ( vvv, lineVec, planePt1,
m_normalFaceOne, m_pVertex3D [i] );
// Get pierced pts on Face 2
PierceLinePlane ( vvv, lineVec, planePt2,
m_normalFaceTwo, m_pVertex3D [i + m_totalVertex] );

TRACE("original 2D - i=%d %f %f %f \n", i,
vvv.x,
vvv.y,
vvv.z );
TRACE("face 1 - i=%d %f %f %f \n", i,
m_pVertex3D [i].x ,
m_pVertex3D [i].y ,
m_pVertex3D [i].z );
};
return 0;
}
------------------------------------------------------------- ElemBase.cpp
void CElemExtrude::CreateGLcalls ()
{
// This is the general function applicable to all extrude-elements

// -------------------------------- Faces x 2
int i;
int total2 = m_totalVertex * 2 ;
int* pIndex = new int [ total2 ];

// MUST BE CONVEX ELSE ...
// MUST BE CONVEX ELSE ...
// MUST BE CONVEX ELSE ...

for (i = 0; i < m_totalVertex; i++) pIndex[i] = m_totalVertex -1 -i;
// CreatePolygonWithNormal ( m_totalVertex, m_pVertex3D, pIndex );
for (i = 0; i < m_totalVertex; i++) pIndex[i] = i + m_totalVertex;
// CreatePolygonWithNormal ( m_totalVertex, m_pVertex3D, pIndex );
delete [] pIndex;

// --------------------------------- Sides x m_totalVertex
int pIndex4 [4];
for (i = 0; i < m_totalVertex - 1; i++)
{
pIndex4 [0] = i;
pIndex4 [1] = i + 1;
pIndex4 [2] = i + m_totalVertex + 1;
pIndex4 [3] = i + m_totalVertex;
CreatePolygonWithNormal ( 4, m_pVertex3D, pIndex4 );
};
// One last one
pIndex4 [0] = m_totalVertex - 1;
pIndex4 [1] = 0;
pIndex4 [2] = m_totalVertex;
pIndex4 [3] = m_totalVertex * 2 - 1;
CreatePolygonWithNormal ( 4, m_pVertex3D, pIndex4 );
}

=========================================================================

FUNCTION MODE (FM) : CLASS-BASED APPROACH

Gxxx.cpp

----------------------------------------------------------------- Doc.h
CFK_baseP* m_pFK; // currently active FK
CFK_baseP* m_pFKprev; // previous FK
CFK_baseP* m_pFKT; // current temporary FK

int FK_mode; // permanemt FK
int FK_modePrev; // save
int cxs;
int nxs;
int pxs;

int FK_modeT; // temporary FK
int FK_modePrevT; // save
int cxsT;
int nxsT;
int pxsT;
------------------------------------------------------------------ Doc.cpp
void CGDoc::OnCreateLine3d()
{ m_pFK = new CFK_createLine3d ( this ); }
void CGDoc::OnUpdateCreateLine3d(CCmdUI* pCmdUI)
{ m_pFK->UpdateFKmode ( pCmdUI, FK_CREATE_LINE_3D ); }
------------------------------------------------------------------ Doc.cpp
void CGDoc::OnCreatePoint()
{ m_pFK = new CFK_createPoint ( this ); }
void CGDoc::OnUpdateCreatePoint(CCmdUI* pCmdUI)
{ m_pFK->UpdateFKmode ( pCmdUI, FK_CREATE_POINT ); }
----------------------------------------------------------------- FK_base.h
class CFK_baseP
{
public:
int pxs, cxs;
CGDoc* m_pDoc;
FK_MODE m_FKmode;
UINT m_stringID;

// Operations
public:
CFK_baseP ( CGDoc* pDoc ); // constructor
virtual ~CFK_baseP (); // destructor

virtual void EventForSEL ( UINT, CPoint );
virtual void EventForIND ( UINT, CPoint );
virtual void EventForKY3 ( UINT, CPoint );
virtual void EventForKY2 ( UINT, CPoint );
virtual void EventForKY1 ( UINT, CPoint );
virtual void EventForLBD ( UINT, CPoint );
virtual void EventForLBU ( UINT, CPoint );
virtual void EventForLB2 ( UINT, CPoint );
virtual void EventForRBD ( UINT, CPoint );
virtual void EventForRBU ( UINT, CPoint );
virtual void EventForRB2 ( UINT, CPoint );
virtual void EventForAWU ( UINT, CPoint );
virtual void EventForAWD ( UINT, CPoint );
virtual void EventForAWL ( UINT, CPoint );
virtual void EventForAWR ( UINT, CPoint );
virtual void EventForDNC ( UINT, CPoint );
virtual void EventForDNS ( UINT, CPoint );
virtual void EventForUPC ( UINT, CPoint );
virtual void EventForUPS ( UINT, CPoint );
virtual void EventForYES ( UINT, CPoint );
virtual void EventForEND ( UINT, CPoint );
virtual void EventForSPC ( UINT, CPoint );
virtual void EventForESC ( UINT, CPoint );
virtual void EventForMMV ( CGView*, CPoint, UINT, CPoint );

virtual void InitializeFK ();

virtual void NXS ( int nxs );
void UpdateFKmode ( CCmdUI* pCmdUI, FK_MODE fk );
};
----------------------------------------------------------------- FK_base.h
class CFK_baseT : public CFK_baseP
{
public:
// Operations
public:
virtual void EventForIND ( UINT, CPoint );
virtual void EventForKY3 ( UINT, CPoint );
virtual void EventForESC ( UINT, CPoint );
virtual void EventForEND ( UINT, CPoint );

virtual void InitializeFK ();
virtual void NXS (int nxs) ;
};
----------------------------------------------------------------- FK_base.h
class CFK_createPoint : public CFK_baseP
{
public:
// Operations
public:
CFK_createPoint ( CGDoc* pDoc );
~CFK_createPoint ();
virtual void EventForIND ( UINT, CPoint );
virtual void EventForKY3 ( UINT, CPoint );
virtual void InitializeFK ();
virtual void NXS (int nxs) ;
};
----------------------------------------------------------------- FK_base.h
class CFK_createLine3d : public CFK_baseP
{
public:
// Operations
public:
CFK_createLine3d ( CGDoc* pDoc );
~CFK_createLine3d ();

virtual void EventForSEL ( UINT, CPoint );
virtual void EventForIND ( UINT, CPoint );
virtual void EventForKY3 ( UINT, CPoint );
virtual void EventForEND ( UINT, CPoint );
virtual void InitializeFK ();
virtual void NXS (int nxs) ;
};
----------------------------------------------------------------- FK_base.cpp
CFK_baseP::CFK_baseP ( CGDoc* pDoc )
{
m_pDoc = pDoc;
////error ?? m_stringID = IDP_PROMPT_NOT_FOUND;
pxs = 0;
NXS ( 1 );

if ( m_pDoc->m_pFK != NULL ) delete m_pDoc->m_pFK; // Destructor of the previous FK
InitializeFK (); // New FK initialization

if ( m_pDoc->m_pFKT != NULL ) delete m_pDoc->m_pFKT;
}
----------------------------------------------------------------- FK_base.cpp
CFK_baseP::~CFK_baseP ( )
{
}
----------------------------------------------------------------- FK_base.cpp
void CFK_baseP::NXS ( int nxs )
{
pxs = cxs; cxs = nxs;

// Display prompt message
//--------------------------------------------
// Convert string resource ID to a string
CString str;
//error ?? AfxFormatString1 ( str, m_stringID, " " );

// Display in the 2nd status bar
//--------------------------------------------

////error ?? m_stringID = IDP_PROMPT_NOT_FOUND;
}
----------------------------------------------------------------- FK_base.cpp
void CFK_baseP::InitializeFK ()
{
}
///////////
void CFK_baseP::UpdateFKmode ( CCmdUI* pCmdUI, FK_MODE fk )
{
if ( m_FKmode == fk ) pCmdUI->SetCheck(1); else pCmdUI->SetCheck(0);
}
///////////
void CFK_baseP::EventForSEL ( UINT nFlags, CPoint pt )
{
}
///////////
void CFK_baseP::EventForIND ( UINT nFlags, CPoint pt )
{
}
///////////
void CFK_baseP::EventForKY1 ( UINT nFlags, CPoint pt )
{
}
///////////
void CFK_baseP::EventForKY2 ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForKY3 ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForLBD ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForLBU ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForLB2 ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForRBD ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForRBU ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForRB2 ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForAWU ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForAWD ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForAWL ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForAWR ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForDNC ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForDNS ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForUPC ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForUPS ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForYES ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForSPC ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForEND ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForESC ( UINT nFlags, CPoint pt )
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_baseP::EventForMMV ( CGView* pV, CPoint d, UINT nFlags, CPoint pt )
{
}

=========================================================================

FM CREATE POINT

Gxxx.cpp

CFK_createPoint::CFK_createPoint ( CGDoc* pDoc ) // constructor
: CFK_baseP ( pDoc )
{
m_FKmode = FK_CREATE_POINT; // See Effective C++ enum???

// Add FK entry_time_only initialization below

}
/////////////////////////////////////////////////////////////////////////////
CFK_createPoint::~CFK_createPoint () // desctructor
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createPoint::InitializeFK ()
{
// FK initialization that application can call anytime. Ex. After NXS(1).

}
/////////////////////////////////////////////////////////////////////////////
void CFK_createPoint::NXS ( int nxs )
{
switch ( nxs )
{
case 1: m_stringID = IDP_CREATE_POINT_1; break;
case 2: m_stringID = IDP_CREATE_POINT_2; break;
};
CFK_baseP::NXS ( nxs ); // Call base function at the end
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createPoint::EventForIND ( UINT, CPoint)
{
switch (cxs)
{
case 1:
if ( ! m_pDoc->m_bWhenIND ) return; // No piercing of CP
m_pDoc->CreatePoint (m_pDoc->m_ptIND);
break;
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createPoint::EventForKY3 ( UINT, CPoint)
{
CPoint3D pt;
switch (cxs)
{
case 1:
pt = m_pDoc->GetKeyCoordinate (); // Input m_value1KEY,2,3
m_pDoc->CreatePoint (pt);
NXS (2);
break;
case 2:
pt = m_pDoc->GetKeyCoordinate (); // Input m_value1KEY,2,3
m_pDoc->CreatePoint (pt);
break;
}
}
 

=========================================================================

FM CREATE LINE 3D

Gxxx.cpp

CFK_createLine3d::CFK_createLine3d ( CGDoc* pDoc ) // constructor
: CFK_baseP ( pDoc )
{
m_FKmode = FK_CREATE_LINE_3D; // See Effective C++ enum???

// Add FK entry_time_only initialization below

}
/////////////////////////////////////////////////////////////////////////////
CFK_createLine3d::~CFK_createLine3d () // desctructor
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::InitializeFK ()
{
// FK initialization that application can call anytime. Ex. After NXS(1).
m_pDoc->m_pointIndex = 0;

}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::NXS ( int nxs )
{
switch ( nxs )
{
case 1: m_stringID = IDP_CREATE_POINT_1; break;
case 2: m_stringID = IDP_CREATE_POINT_2; break;
};

CFK_baseP::NXS ( nxs ); // Call base function at the end
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::EventForIND ( UINT, CPoint)
{
switch (cxs)
{
case 1:
if ( ! m_pDoc->m_bWhenIND ) return; // No piercing of CP
// save as pt1 for line
m_pDoc->m_pointArray [ m_pDoc->m_pointIndex++ ] = m_pDoc->m_ptIND;
// SetRubberBandAnchorAllVpts ( m_savePt1 );
// was-- m_pRubberBandLine = new CRubberBandLineAllVpts
// ( &dc, pView, this, m_savePt1, this );
NXS (2);
m_pDoc->TempPoint ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->TempMultiLine1 ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->InvalidateAllVpts ();
break;
case 2:
if ( ! m_pDoc->m_bWhenIND ) return; // No piercing of CP
// save as pt1 for line
m_pDoc->m_pointArray [ m_pDoc->m_pointIndex++ ] = m_pDoc->m_ptIND;
// SetRubberBandAnchorAllVpts ( m_savePt1 );
// was-- m_pRubberBandLine = new CRubberBandLineAllVpts
// ( &dc, pView, this, m_savePt1, this );
NXS (2);
m_pDoc->TempPoint ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->TempMultiLine1 ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->InvalidateAllVpts ();
break;
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::EventForSEL ( UINT, CPoint)
{
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::EventForKY3 ( UINT, CPoint)
{
CPoint3D pt;
switch (cxs)
{
case 1:
pt = m_pDoc->GetKeyCoordinate (); // Input m_value1KEY,2,3
m_pDoc->m_pointArray [ m_pDoc->m_pointIndex++ ] = pt;

// CleanRubberBandRelics(); // erase previous rubber-band first
// SetRubberBandAnchorAllVpts ( m_savePt1 );
NXS (2);
m_pDoc->TempPoint ( RED, SOLID, pt );
m_pDoc->TempMultiLine1 ( RED, SOLID, pt );
m_pDoc->InvalidateAllVpts ();
break;
case 2:
pt = m_pDoc->GetKeyCoordinate (); // Input m_value1KEY,2,3
m_pDoc->m_pointArray [ m_pDoc->m_pointIndex++ ] = pt;

// CleanRubberBandRelics(); // erase previous rubber-band first
// SetRubberBandAnchorAllVpts ( m_savePt1 );
NXS (2);
m_pDoc->TempPoint ( RED, SOLID, pt );
m_pDoc->TempMultiLine1 ( RED, SOLID, pt );
m_pDoc->InvalidateAllVpts ();
break;
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::EventForEND ( UINT, CPoint)
{
CPoint3D pt;
switch (cxs)
{
case 2:
// End the current multi-line creation
m_pDoc->CreateLine3D ( m_pDoc->m_pointArray [0] ); // CreateLine

// CleanRubberBandRelics();
NXS (1);
m_pDoc->m_pointIndex = 0;
m_pDoc->ClearTempAll ();
//m_skipViewing = true; // Do not route this event to VW-mode
break;
}
}
=========================================================================

EVENT HANDLING

Gxxx.cpp

void CGView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CGDoc* pDoc = GetDocument();
// CWnd::Invalidate(true); // (true)
if (pStatus)
{
int v11, v22;
v11 = (int) (v1 * 10.0f); v22 = (int)(v2 * 10.);
wsprintf(text,"x=%d y=%d",v11, v22);
pStatus->SetPaneText(0, text);
};
pDoc->m_pViewEvent = this; // view ptr where this event originated
MSSG msgType;
CPoint dummy;
BOOL action = true;
switch (nChar)
{
case VK_ESCAPE: // msgType = ESC; break; // ESC button DOWN
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForESC (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_LEFT: // msgType = AWL; break; // Left-arrow
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForAWL (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_RIGHT: // msgType = AWR; break; // Right-arrow
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForAWR (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_UP: // msgType = AWU; break; // Up-arrow
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForAWU (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_DOWN: // msgType = AWD; break; // Down-arrow
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForAWD (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_SPACE: // msgType = SPC; break; // Space key hit
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForSPC (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_END: // msgType = END; break; // END key hit
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForEND (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
//------- put SHIFT/CONTROL Last else always DNC when arrow+CNTL 97-6-21
case VK_SHIFT: // msgType = DNS; break; // SHIFT down
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForDNS (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_CONTROL: // msgType = DNC; break; // CTRL down
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForDNC (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
// case VK_ALTERNATE: msgType = DNA; break; // ALT down
//c default: action = false;
}
//c if (action) pDoc->FK_dispenser (msgType, nFlags, dummy);

////-6-21////////////////////if not spoken for then

// DID NOT WORK WELL 6-21


// if ( nChar == 40 || nChar == 38 ) // Arrow keys UP & DOWN
if ( nChar == VK_UP || nChar == VK_DOWN ) // Arrow keys UP & DOWN
//c if ( msgType == AWU || msgType == AWD ) // Arrow keys UP & DOWN
{
if ( nFlags & MK_SHIFT && nFlags & MK_CONTROL )
{
}
else if ( nFlags & MK_SHIFT )
{
int x = (msgType == AWD) ? 50 : -50;
CPoint delta ( x, x );
OnMMPanTurnHead ( delta );
}
else if ( nFlags & MK_CONTROL )
{
int x = (msgType == AWD) ? 50 : -50;
CPoint delta ( x, x );
OnMMZoomMoveCamera ( delta );
}
else
{
// float factor = (nChar == 40) ? 1.1f : 0.9f;
float factor = (msgType == AWU) ? 1.1f : 0.9f;
if (m_projectMode == PM_PERSPECTIVE) // Perspective projection
{
m_viewAngle *= factor;
if (m_viewAngle < 1 ) m_viewAngle = 0.20f;
if (m_viewAngle > 179 ) m_viewAngle = 179.0f;
}
else // Parallel projection
{
m_vptX *= factor;
m_vptY *= factor;
};

float v1 = m_viewAngle;
float v2 = 0.0f;
/////
Setup2Projection ();
/////
}
};
Invalidate(false); // (true)

///-6-21////////////////////if not spoken for then

CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
TRACE (" CGView ------ OnKeyUp \n" );

CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view ptr where this event originated
MSSG msgType;
CPoint dummy;
BOOL action = true;
switch (nChar)
{
case VK_SHIFT: // msgType = UPS; break; // SHIFT button UP
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForUPS (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
case VK_CONTROL: // msgType = UPC; break; // CTRL button UP
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForUPC (nFlags,dummy);
else pDoc->m_pFKT->EventForESC (nFlags, dummy );
break;
// case VK_ALTERNATE: msgType = UPA; break; // ALT button UP
//c default: action = false;
}
//c if (action) pDoc->FK_dispenser (msgType, nFlags, dummy);
CView::OnKeyUp(nChar, nRepCnt, nFlags);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// We put the pointer to the view instance which intercepted this
// WM_CHAR message in the Doc's m_pViewEvent member.

TRACE( "TRACE - View::OnChar called\n" );

CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view ptr where this event originated

CClientDC dc(this);
MSSG msgType;
CPoint dummy;
CString a,b,c, rightString;

if ( nChar == 'y' )
{
// The 'y' means 'YES'
msgType = YES;
}
else if ( nChar == '\r' )
{
// Return was hit, so analyze the keyed-in string
int total = pDoc->m_keyinString.GetLength();

int ix = pDoc->m_keyinString.Find(',');
if ( ix == -1 ) // could not find a comma ---> KEY1
{
a = pDoc->m_keyinString;
msgType = KY1;
}
else
{
a = pDoc->m_keyinString.Left (ix);
rightString = pDoc->m_keyinString.Right (total - 1 - ix);
int ixx = rightString.Find(',');
if ( ixx == -1 ) // could not find a comma ---> KEY2
{
b = rightString;
msgType = KY2;
}
else
{
b = rightString.Left(ixx);
total = rightString.GetLength();
c = rightString.Right (total - 1 - ixx);
msgType = KY3;
};
};
//dc.TextOut(10,20,a, a.GetLength());
//dc.TextOut(10,40,b, b.GetLength());
//dc.TextOut(10,60,c, c.GetLength());

pDoc->m_keyinString.Empty();

pDoc->m_value1KEY = (float) atof (a);
pDoc->m_value2KEY = (float) atof (b);
pDoc->m_value3KEY = (float) atof (c);

// clear the key-in field display in the status bar #1
///////////////////////////////////////////////////////////////////
char text [100];
CStatusBar* pStatus = (CStatusBar*)
AfxGetApp()->m_pMainWnd->GetDescendantWindow(ID_MY_STATUS_BAR_1);
if (pStatus)
{
pStatus->SetPaneText ( 1, " " );
}
///////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////
// now write converted values back to screen
// pDoc->ScreenDisplayCoordinates (3, pDoc->m_value1KEY,
// pDoc->m_value2KEY,
// pDoc->m_value3KEY );


}
else
{
// accumulate the keyed-in string until <return>
pDoc->m_keyinString += nChar;

// display on the key-in field in the status bar #1
///////////////////////////////////////////////////////////////////
char text [100];
CStatusBar* pStatus = (CStatusBar*)
AfxGetApp()->m_pMainWnd->GetDescendantWindow(ID_MY_STATUS_BAR_1);
if (pStatus)
{
pStatus->SetPaneText ( 1, pDoc->m_keyinString );
}
///////////////////////////////////////////////////////////////////
///dc.TextOut (0,0, pDoc->m_keyinString,
/// pDoc->m_keyinString.GetLength());

return;
};

//c pDoc->FK_dispenser (msgType, nFlags, dummy);
if (msgType == YES )
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForYES (nFlags,dummy);
else pDoc->m_pFKT->EventForYES (nFlags, dummy );
else if (msgType == KY1 )
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForKY1 (nFlags,dummy);
else pDoc->m_pFKT->EventForKY1 (nFlags, dummy );
else if (msgType == KY2 )
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForKY2 (nFlags,dummy);
else pDoc->m_pFKT->EventForKY2 (nFlags, dummy );
else if (msgType == KY3 )
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForKY3 (nFlags,dummy);
else pDoc->m_pFKT->EventForKY3 (nFlags, dummy );

CView::OnChar(nChar, nRepCnt, nFlags);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnLButtonDown(UINT nFlags, CPoint point)
{
TRACE( "TRACE - View::OnLButtonDown called\n" );

CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view pointer of event-origin

if ( (!( nFlags & MK_CONTROL )) && // forced INDICATE working OK
//SelectFEP (nFlags, point) ) // return true if something selected
PickOperation (point) ) // return true if something selected
{
// pDoc->FK_dispenser (SEL, nFlags, point); // something selected
// Something selected
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForSEL ( nFlags, point );
else pDoc->m_pFKT->EventForSEL ( nFlags, point );
}
else
{
if ( GetWorldCPWhenIND (point))
{
pDoc->m_bWhenIND = true; // pierced
pDoc->GridSnapCheck (); // Set m_ptIND accordingly
}
else
{
pDoc->m_bWhenIND = false;
}
//c pDoc->FK_dispenser (IND, nFlags, point); // always called anyway
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForIND ( nFlags, point );
else pDoc->m_pFKT->EventForIND ( nFlags, point );
/// pDoc->FK_dispenser (LBD, nFlags, point); // nothing seected
};
// Save R-mouse-down point
m_oldMousePt = point;

CView::OnLButtonDown(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnLButtonUp(UINT nFlags, CPoint point)
{
TRACE( "TRACE - View::OnLButtonUp called\n" );

CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view pointer of event-origin

//c pDoc->FK_dispenser (LBU, nFlags, point);
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForLBU ( nFlags, point );
else pDoc->m_pFKT->EventForLBU ( nFlags, point );
CView::OnLButtonUp(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view pointer of event-origin

//c pDoc->FK_dispenser (LB2, nFlags, point);
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForLB2 ( nFlags, point );
else pDoc->m_pFKT->EventForLB2 ( nFlags, point );
CView::OnLButtonDblClk(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnRButtonDown(UINT nFlags, CPoint point)
{
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForRBD ( nFlags, point );
else pDoc->m_pFKT->EventForRBD ( nFlags, point );
// Save R-mouse-down point
m_oldMousePt = point;

// For box zoom - this is not changed at each mouse move 97-6-22
pDoc->m_ptPanOrigin = point;

CView::OnRButtonDown(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnRButtonUp(UINT nFlags, CPoint point)
{
TRACE( "TRACE - View::OnRButtonUp called\n" );
CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view pointer of event-origin

//c pDoc->FK_dispenser (RBU, nFlags, point);
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForRBU ( nFlags, point );
else pDoc->m_pFKT->EventForRBU ( nFlags, point );
CView::OnRButtonUp(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnRButtonDblClk(UINT nFlags, CPoint point)
{
CGDoc* pDoc = GetDocument();
pDoc->m_pViewEvent = this; // view pointer of event-origin

//c pDoc->FK_dispenser (RB2, nFlags, point);
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->EventForRB2 ( nFlags, point );
else pDoc->m_pFKT->EventForRB2 ( nFlags, point );
CView::OnRButtonDblClk(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnMouseMove(UINT nFlags, CPoint point)
{

// GLfloat v1, v2;
// char text [100];
// COGLDoc* pDoc = GetDocument();
// 12-13-96
// CStatusBar* pStatus = (CStatusBar*)
// AfxGetApp()->m_pMainWnd->GetDescendantWindow(ID_MY_STATUS_BAR);

CGDoc* pDoc = GetDocument();

// Get delta-difference from mouse-down point
CPoint delta = m_oldMousePt - point;
if ( delta.x == 0 && delta.y == 0 ) return; // mouse did not move

//c if ( pDoc->FK_M_dispenser(this, delta, nFlags, point)) goto JumpToEnd;
if ( pDoc->m_pFKT == NULL )
{
pDoc->m_pFK->EventForMMV ( this, delta, nFlags, point );
}
else
{pDoc->m_pFKT->EventForMMV ( this, delta, nFlags, point );
goto JumpToEnd; // NOT ALWAYS ?????????????????? -11-9
}
// If true is returned, skip OnMMxxx. That is, FK takes over RBSetup.
// (RBSetup = RButtonSetup) Typically, Temporary FK takes over RBSetup
// also while permanent FK does not. 97-6-21

if (nFlags & MK_LBUTTON && nFlags & MK_RBUTTON)
{
// Both LEFT and RIGHT mouse buttons
OnMouseMoveLRButtons (delta, nFlags, point);
}
else if (nFlags & MK_LBUTTON)
{
// LEFT mouse button
OnMouseMoveLButton (delta, nFlags, point);
}
else if (nFlags & MK_RBUTTON)
{
// RIGHT mouse button
OnMouseMoveRButton (delta, nFlags, point);
}
else
{
// No mouse button held
OnMouseMoveNoButton (delta, nFlags, point);
};

JumpToEnd: m_oldMousePt = point;

Invalidate(false); // (true)
CView::OnMouseMove(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
void CGView::OnMouseMoveNoButton (CPoint delta, UINT nFlags, CPoint point)
{
}
/////////////////////////////////////////////////////////////////////////////
void CGView::OnMouseMoveLRButtons (CPoint delta, UINT nFlags, CPoint point)
{
}
/////////////////////////////////////////////////////////////////////////////
void CGView::OnMouseMoveLButton (CPoint delta, UINT nFlags, CPoint point)
{
}
/////////////////////////////////////////////////////////////////////////////
void CGView::OnMouseMoveRButton (CPoint delta, UINT nFlags, CPoint point)
{
CGDoc* pDoc = GetDocument();

float x = (float)delta.x;
float y = (float)delta.y;

if (pDoc->FK_modeT == FK_EXIT) // Default VW-mode
{
if (nFlags & MK_CONTROL && nFlags & MK_SHIFT)
OnMMViewingDefault ( delta, pDoc->m_viewingDefaultBOTH );
else if (nFlags & MK_SHIFT)
OnMMViewingDefault ( delta, pDoc->m_viewingDefaultSHIFT );
else if (nFlags & MK_CONTROL)
OnMMViewingDefault ( delta, pDoc->m_viewingDefaultCTRL );
else OnMMViewingDefault ( delta, pDoc->m_viewingDefaultNONE );
};
}

=========================== FK CLASS ===================================
////////////////////////////////////////////////////////////////////////////
CFK_BASE* m_pFK; // Currently active FK-permanent
CFK_BASE* m_pFKT; // Currently active FK-temporary

BOOL SetFKmodeForT ( FK_MODE fk );
void UpdateFKmodeForT ( CCmdUI* pCmdUI, FK_MODE fk );

/////////////////////////////////////////////////////////////////////////////
void CGDoc::OnCreatePoint()
{ m_pFK = new CFK_createPoint ( this ); }
void CGDoc::OnUpdateCreatePoint(CCmdUI* pCmdUI)
{ m_pFK->UpdateFKmode ( pCmdUI, FK_CREATE_POINT ); }
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
void CGDoc::OnViewRotPerp()
{ if ( SetFKmodeForT ( FK_VIEW_ROT_PERP ) )
m_pFKT = new CFK_viewRotPerp ( this ); }
void CGDoc::OnUpdateViewRotPerp(CCmdUI* pCmdUI)
{ UpdateFKmodeForT ( pCmdUI, FK_VIEW_ROT_PERP ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CGDoc::SetFKmodeForT ( FK_MODE fk )
{
if ( m_pFKT == NULL )
// No FK-temp existed before, so create new one
return true; // m_pFKT = new CFK_viewRotPerp ( this );
else
{
if ( m_pFKT->m_FKmode == fk )
{ // FK-temp existed is the same one, so exit and go back to FK-perm
delete m_pFKT;
m_pFKT = NULL;
// Restore FK-permanent prompt message
m_pFK->NXS ( m_pFK->cxs );
return false; // No FK-temp needed
}
else
{ // Different FK-temp requested, so delete old & create new one
delete m_pFKT;
return true; // m_pFKT = new CFK_viewRotPerp ( this );
}
}
}
/////////////////////////////////////////////////////////////////////////////
void CGDoc::UpdateFKmodeForT ( CCmdUI* pCmdUI, FK_MODE fk )
{
if ( m_pFKT != NULL )
// If FK-temp exists, let it take care of update business
m_pFKT->UpdateFKmode ( pCmdUI, FK_VIEW_ROT_PERP );
else
// If FK-temp does not exist, always turn off display
pCmdUI->SetCheck(0);
}
/////////////////////////////////////////////////////////////////////////////

=========================================================================

KEY-IN TO CURRENT PLANE  - Orange color

Gxxx.cpp

void CGDoc::OnCoordCurPlane()
{
m_modeGlobalCP = ( m_modeGlobalCP == COORD_CUR_PLANE )
? COORD_GLOBAL : COORD_CUR_PLANE;
CreateDisplayList ( DL_CUR_PLANE );
ClearTempCoordinate();
InvalidateAllVpts ();
}
void CGDoc::OnUpdateCoordCurPlane(CCmdUI* pCmdUI)
{
if (m_modeGlobalCP == COORD_CUR_PLANE) pCmdUI->SetCheck(1);
else pCmdUI->SetCheck(0);
}
/////////////////////////////////////////////////////////////////////////////
void CGDoc::CreateDisplayList ( DISPLAY_LIST no )
{
glNewList ( no, GL_COMPILE);

switch ( no )
{
case DL_CUR_PLANE: /// Current plane
{
// Color of the current plane --- User-customizable 97-4-25
if ( m_modeGlobalCP == COORD_CUR_PLANE )
glColor3f (0.6f, 0.4f, 0.0f);
else
glColor3f (0.4f, 0.4f, 0.4f);

// const float increment = m_gridSize; // --- INPUT (1)
// const int total = m_gridTotal; // --- INPUT (2)

const float xMax = m_gridSize * m_gridTotal;
const float yMax = m_gridSize * m_gridTotal;
const float zMax = 0.0f;
float xx = m_gridSize;
float yy = m_gridSize;

glBegin ( GL_LINES );
for (int k = 0; k < m_gridTotal - 1; k++)
{
glVertex3f ( xMax, yy, zMax );
glVertex3f (-xMax, yy, zMax );
glVertex3f ( xMax, -yy, zMax );
glVertex3f (-xMax, -yy, zMax );
yy += m_gridSize;
glVertex3f ( xx, yMax, zMax );
glVertex3f ( xx, -yMax, zMax );
glVertex3f (-xx, yMax, zMax );
glVertex3f (-xx, -yMax, zMax );
xx += m_gridSize;
};
glEnd ();
// Draw negative X and Y axes (same color)
glBegin ( GL_LINE_STRIP );
glVertex3f (-xMax, 0.0f, zMax );
glVertex3f ( 0.0f, 0.0f, zMax );
glVertex3f ( 0.0f,-yMax, zMax );
glEnd ();
// Draw X axis with RED
glColor3f ( 1.0f, 0.0f, 0.0f );
glBegin ( GL_LINES );
glVertex3f ( xMax, 0.0f, zMax );
glVertex3f ( 0.0f, 0.0f, zMax );
glEnd ();
// Draw Y axis with GREEN
glColor3f ( 0.0f, 1.0f, 0.0f );
glBegin ( GL_LINES );
glVertex3f ( 0.0f, yMax, zMax );
glVertex3f ( 0.0f, 0.0f, zMax );
glEnd ();
break;
};
};
glEndList();
}

=========================================================================

SHOW THE REFERENCE POINT

Gxxx.cpp

void CGDoc::OnCoordRelative()
{
m_modeAbsRel = ( m_modeAbsRel == COORD_RELATIVE )
? COORD_ABSOLUTE : COORD_RELATIVE;
InvalidateAllVpts();
}
void CGDoc::OnUpdateCoordRelative(CCmdUI* pCmdUI)
{
if (m_modeAbsRel == COORD_RELATIVE) pCmdUI->SetCheck(1);
else pCmdUI->SetCheck(0);
}

/////////////////////////////////////////////////////////////////////////////
void CGDoc::DrawAllTempElems ()
{
int i;

// --------------------------------------------------- Points
if ( m_tempPointTotal )
{

// --------------------------------------------------- Lines
if ( m_tempLineTotal )
{

// ---------------------------------------------- Key-in reference pt
if ( m_modeAbsRel == COORD_RELATIVE ) // only if REL key-in mode
{
glPointSize (9.0);
glBegin ( GL_POINTS );
glColor3f ( 1.0f, 1.0f, 1.0f ); // Dot color - Yellow
glVertex3f ( m_ptReference.x,m_ptReference.y,m_ptReference.z );
glEnd ();
}

// ------------------------------------------------- Coordiate system

if ( m_tempCoordType > 0 )
{
if ( m_modeGlobalCP == COORD_CUR_PLANE ) // transform to CP
{

 

=========================================================================

CREATE 2D SHAPE / MODIFY 

Gxxx.cpp

void CFK_createShape2d::EventForKY3 ( UINT, CPoint)
{
CPoint3D pt;
switch (cxs)
case 1:
case 2:
pt = m_pDoc->GetKeyCoordinate (); // Input m_value1KEY,2,3
CreateShape2d ( m_FKmode, pt );
NXS (2);
break;
/////////////////////////////////////////////////////////////////////////////
void CFK_createShape2d::CreateShape2d ( FK_MODE fk, const CPoint3D& pt )
{
ELEM_TYPE et;
switch ( fk )
case FK_CREATE_BOX: et = ET_BOX; break;
case FK_CREATE_CIRCLE: et = ET_CIRCLE; break;
case FK_CREATE_ELLIPSE: et = ET_ELLIPSE; break;
case FK_CREATE_CAP: et = ET_CAP; break;
case FK_CREATE_DISH: et = ET_DISH; break;
case FK_CREATE_ELBOW: et = ET_ELBOW; break;
case FK_CREATE_SHAPE_I: et = ET_SHAPE_I; break;
case FK_CREATE_SHAPE_L: et = ET_SHAPE_L; break;
case FK_CREATE_SHAPE_V: et = ET_SHAPE_V; break;
m_pDoc->CreateAndDisplay ( et, pt, m_pCurPlane->GetMxAxisZ(),
m_pCurPlane->GetMxAxisY(), 1.0f, 1.0f );
/////////////////////////////////////////////////////////////////////////
void CGDoc::CreateAndDisplay (ELEM_TYPE type,
const CPoint3D& pt, // origin point
const CPoint3D& dir, // direction vector
const CPoint3D& ori, // orientation vector
float height, float width, float length )
{
// This function creates a new element and then displays it
// 1. Create C++ object (only persistent data set)
CElemBase1D* pE = NewElem ( type, pt, dir, ori, height, width, length );
if (pE == NULL) return; // New elem creation failed
// Save in FK class
m_pFK->m_pElemCur = pE;
// 2. Add to the list
m_elemList.AddTail (pE);
SetModifiedFlag();
// 3. Generate vertices
pE->GenerateVerticesAndCreateGLcalls ();
// 5. Display the element
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{
CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
// pView->Invalidate(); // Calls OnDraw();
pView->Invalidate(false); // Calls OnDraw();
///////////////////////////////////////////////////////////////////////////
void CElemBase1D::GenerateVerticesAndCreateGLcalls ()
{
// Combination of the two functions
GenerateVertices();
/VERIFY (wglMakeCurrent(m_master_hDC,m_master_hRC));
glNewList ((GLuint)this, GL_COMPILE);
CreateGLcalls ();
glEndList ();
/VERIFY (wglMakeCurrent (NULL, NULL));
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createShape2d::EventForKY2 ( UINT, CPoint)
{
switch (cxs)
case 2: // Modify width and height
m_pElemCur->SetWidth ( m_value1KEY );
m_pElemCur->SetHeight ( m_value2KEY );
m_pElemCur->GenerateVerticesAndCreateGLcalls ();
m_pDoc->InvalidateAllVpts ();
NXS (2);
break;
 

=========================================================================

CREATE EXTRUDE / MODIFY

Gxxx.cpp

void CFK_createExtrude::EventForKY1 ( UINT, CPoint)
{
CPoint3D pt;
switch (cxs)
{
case 2: // Key in length to create a new element
m_pDoc->CreateExtrude ( m_pElem2D, m_value1KEY );
NXS (3);
break;
case 3: // Key in length to modify the existing element
m_pElemCur->SetLength ( m_value1KEY );
m_pElemCur->GenerateVerticesAndCreateGLcalls();
m_pDoc->InvalidateAllVpts();
NXS (3);
break;
/////////////////////////////////////////////////////////////////////////////
void CGDoc::CreateAndDisplayExtrude ( CElemBase2D* pElem, float length )
{
// This function creates a new element and then displays it

CPoint3D pt = pElem->GetMxOrigin ();
// 1. Create C++ object (only persistent data set)
CElemBase1D* pE = new CElemExtrude ( pElem,
pElem->GetMxOrigin(),
pElem->GetMxAxisZ(),
pElem->GetMxAxisY(),
pElem->m_height,
pElem->m_width,
length );
if (pE == NULL) return; // New elem creation failed
// Whenever a new element is created, save in m_pElemCur
m_pFK->m_pElemCur = pE;
// 2. Add to the list
m_elemList.AddTail (pE);
SetModifiedFlag();
// 3. Generate vertices
pE->GenerateVerticesAndCreateGLcalls();
// 5. Display the element
for (POSITION pos = GetFirstViewPosition(); pos != NULL;)
{
CGView* pView = (CGView*) GetNextView (pos);
if (!pView->IsKindOf(RUNTIME_CLASS(CGView))) continue; // Whoops!
// pView->Invalidate(); // Calls OnDraw();
pView->Invalidate(false); // Calls OnDraw();
}
}

=========================================================================

RUBBER-BAND SPECIAL 3D LINE

Gxxx.cpp

void CGDoc::FromOnNewDocument()
{
m_bRubberBandSpecialLine = false;
m_bRubberBandSpecialBox = false;
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::EventForIND ( UINT, CPoint)
{
switch (cxs)
{
case 1:
if ( ! m_pDoc->m_bWhenIND ) return; // No piercing of CP
// save as pt1 for line
m_pDoc->m_pointArray [ m_pDoc->m_pointIndex++ ] = m_pDoc->m_ptIND;
// SetRubberBandAnchorAllVpts ( m_pDoc->m_savePt1 );
// was-- m_pRubberBandLine = new CRubberBandLineAllVpts
// ( &dc, pView, this, m_pDoc->m_savePt1, this );
NXS (2);
m_pDoc->TempPoint ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->TempMultiLine1 ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->InvalidateAllVpts ();
break;
case 2:
if ( ! m_pDoc->m_bWhenIND ) return; // No piercing of CP
// save as pt1 for line
m_pDoc->m_pointArray [ m_pDoc->m_pointIndex++ ] = m_pDoc->m_ptIND;
// SetRubberBandAnchorAllVpts ( m_pDoc->m_savePt1 );
// was-- m_pRubberBandLine = new CRubberBandLineAllVpts
// ( &dc, pView, this, m_pDoc->m_savePt1, this );
NXS (2);
m_pDoc->TempPoint ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->TempMultiLine1 ( RED, SOLID, m_pDoc->m_ptIND );
m_pDoc->InvalidateAllVpts ();
break;
}
RubberBandSpecialLineBegin ( m_ptIND );
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLine3d::EventForEND ( UINT, CPoint)
{
CPoint3D pt;
switch (cxs)
{
case 2:
// End the current multi-line creation
m_pDoc->CreateLine3D ( m_pDoc->m_pointArray [0] ); // CreateLine

// CleanRubberBandRelics();
NXS (1);
m_pDoc->m_pointIndex = 0;
m_pDoc->ClearTempAll ();
//m_skipViewing = true; // Do not route this event to VW-mode
break;
}
RubberBandSpecialLineEnd ();

/////////////////////////////////////////////////////////////////////////////
void CGDoc::RubberBandSpecialLineBegin ( const CPoint3D& pt )
{
// Create 3D ruuber-banding line to IND location in all vpts
m_bRubberBandSpecialLine = true;
m_rubberBand3dArray [0] = pt;
m_rubberBand3dTotal = 1;
m_rubberBand3dColor = YELLOW;
m_rubberBand3dStyle = DASH;
}
/////////////////////////////////////////////////////////////////////////////
void CGDoc::RubberBandSpecialLineEnd ()
{
m_bRubberBandSpecialLine = false;
}
/////////////////////////////////////////////////////////////////////////////
void CGDoc::RubberBandSpecialBoxBegin ( const CPoint2D& pt )
{
// Create 2D ruuber-banding box in one vpt
m_bRubberBandSpecialBox = true;
m_rubberBand2dArray [0] = pt;
m_rubberBand2dTotal = 1;
m_rubberBand2dColor = YELLOW;
m_rubberBand2dStyle = DASH;
}
/////////////////////////////////////////////////////////////////////////////
void CGDoc::RubberBandSpecialBoxEnd ()
{
m_bRubberBandSpecialBox = false;
}
/////////////////////////////////////////////////////////////////////////////
void CGView::OnMouseMove(UINT nFlags, CPoint point)
{
CGDoc* pDoc = GetDocument();

// Get delta-difference from mouse-down point
CPoint delta = m_oldMousePt - point;
if ( delta.x == 0 && delta.y == 0 ) return; // mouse did not move

if ( pDoc->m_pFKT == NULL ) // --- Permanent FK ---
{
pDoc->m_pFK->EventForMMV ( this, delta, nFlags, point );
}
else // --- Temporary FK ---
{
pDoc->m_pFKT->EventForMMV ( this, delta, nFlags, point );
goto JumpToEnd; // NOT ALWAYS ?????????????????? 97-11-9
}
// If true is returned, skip OnMMxxx. That is, FK takes over RBSetup.
// (RBSetup = RButtonSetup) Typically, Temporary FK takes over RBSetup
// also while permanent FK does not. 97-6-21

if (nFlags & MK_LBUTTON && nFlags & MK_RBUTTON) // BOTH mouse buttons
{
OnMouseMoveLRButtons (delta, nFlags, point);
}
else if (nFlags & MK_LBUTTON) // LEFT mouse button
{
OnMouseMoveLButton (delta, nFlags, point);
}
else if (nFlags & MK_RBUTTON) // RIGHT mouse button
{
OnMouseMoveRButton (delta, nFlags, point);
}
else // No mouse button held
{
// ------------- Dynamic Elem Highlight ---------------------
if ( pDoc->m_bElemDynHilite ) // Hilite as the cursor passes
{
if ( pDoc->m_pElemDynHilite != NULL )
{
pDoc->m_pElemDynHilite->Unhighlight ();
pDoc->m_pElemDynHilite = NULL;
}
if ( PickOperation ( point ) )
{
pDoc->m_pElemSEL->Highlight ();
pDoc->m_pElemDynHilite = pDoc->m_pElemSEL; // save
}
}
// ------------- Dynamic Point Snap ---------------------
if ( pDoc->m_bGridSnap ) // Grid Snap as the cursor passes
{
if ( GetWorldCPWhenIND ( point ) )
{
pDoc->GridSnapCheck();
pDoc->TempPointNew ( RED, SOLID, pDoc->m_ptIND );
}
}
// ------------- Rubber Banding Special --------------------
if ( pDoc->m_bRubberBandSpecialLine ) // 3D line
{
pDoc->m_rubberBand3dTotal = 0; // erase if no pierce
if ( GetWorldCPWhenIND ( point ) )
{
pDoc->m_rubberBand3dTotal = 1;
pDoc->m_rubberBand3dArray [1] = pDoc->m_ptIND;
}
}
if ( pDoc->m_bRubberBandSpecialBox ) // 2D Box
{
pDoc->m_rubberBand2dTotal = 0; // erase if no pierce
}

OnMouseMoveNoButton (delta, nFlags, point);
};
JumpToEnd: m_oldMousePt = point;
Invalidate(false); // (true)
CView::OnMouseMove(nFlags, point);
}
 

=========================================================================

ELEMENT MODIFY - SUBMENU

Gxxx.cpp

------------------------------------------------------------- GFK_base.h
class CFK_BASE
{
public:
int pxs;
int cxs;

CGDoc* m_pDoc;
CCurPlane* m_pCurPlane;

FK_MODE m_FKmode;
UINT m_stringID;

CDialog* m_pDlgSubmenu; // sub-menu pop-up 98-5-8

void ShowSubmenu ( UINT dialogID ){} ; // no need for virtual??
void HideSubmenu () ;
};
/////////////////////////////////////////////////////////////////////////////
void CFK_BASE::HideSubmenu ( )
{
if ( NULL == m_pDlgSubmenu ) return;
m_pDlgSubmenu->DestroyWindow();
}
---------------------------------------------------------------- GFK_editing.h
/////////////////////////////////////////////////////////////////////////////
class CFK_elemModify : public CFK_baseP
{
public:
CFK_elemModify ( CGDoc* pDoc );
~CFK_elemModify ();
virtual void NXS (int nxs) ;
virtual void InitializeFK ();
virtual void EventForSEL ( UINT, CPoint );
virtual void EventForKY1 ( UINT, CPoint );
virtual void EventForKY2 ( UINT, CPoint );
virtual void EventForKY3 ( UINT, CPoint );
virtual void EventForMENU ( UINT item );
void ShowSubmenu ( UINT dialogID ) ;
};
---------------------------------------------------------------- GFK_editing.cpp
#include "GGlobal.h"
#include "GUtil.h"
#include "GDoc.h"
#include "GView.h"
#include "GElem.h"

#include "GFK_base.h"
#include "GFK_editing.h"

// Sub-menus for FK elem modify
#include "SmElemModifyExtrude.h"
#include "SmElemModifyRevolve.h"
#include "SmElemModifyElbow3D.h"
/////////////////////////////////////////////////////////////////////////////
void CFK_elemModify::EventForSEL ( UINT, CPoint)
{
m_pElemSaved = m_pElemSEL;
ELEM_TYPE et = m_pElemSEL->m_elemType;

switch (cxs)
{
case 1:
case 2:
case 3:
case 4:
case 5:
if ( ET_POINT == et )
NXS (1);
else if ( ET_BOX == et || ET_SHAPE_L == et || ET_SHAPE_I == et ||
ET_SHAPE_V == et || ET_ELBOW == et )
{
if ( NULL != m_pDlgSubmenu ) HideSubmenu (); // always delete current
NXS (2);
}
else if ( ET_ELBOW_3D == et )
{
ShowSubmenu ( IDD_SM_ELEM_MODIFY_ELBOW3D );
NXS (3);
}
else if ( ET_REVOLVE == et )
{
ShowSubmenu ( IDD_SUB_ELEM_MODIFY_REVOLVE );
NXS (4);
}
else if ( ET_EXTRUDE == et )
{
ShowSubmenu ( IDD_SM_ELEM_MODIFY_EXTRUDE );
NXS (5);
}
break;
case 10:
if ( ET_POINT == et )
{
// Face 1 normal
m_pElemSaved->ModifyExtrude ( 1, m_pt1SEL ); // face 1
InvalidateAllVpts ();
break;
}
break;
case 11:
if ( ET_POINT == et )
{
// Face 2 normal
m_pElemSaved->ModifyExtrude ( 2, m_pt1SEL ); // face 1
InvalidateAllVpts ();
break;
}
break;
}
}

/////////////////////////////////////////////////////////////////////////////
void CFK_elemModify::ShowSubmenu ( UINT dialogID )
{
if ( NULL != m_pDlgSubmenu ) HideSubmenu (); // always delete current
CDialog* p;
switch ( dialogID )
{
case IDD_SM_ELEM_MODIFY_EXTRUDE: p = new CSmElemModifyExtrude ( this ); break;
case IDD_SM_ELEM_MODIFY_REVOLVE: p = new CSmElemModifyRevolve ( this ); break;
case IDD_SM_ELEM_MODIFY_ELBOW3D: p = new CSmElemModifyElbow3d ( this ); break;
}
p->Create ( dialogID );
m_pDlgSubmenu = (CDialog*) p;
}
/////////////////////////////////////////////////////////////////////////////
void CFK_elemModify::EventForMENU ( UINT item )
{
switch (cxs)
-------------------------------------------------------- SmElemModifyExtrude.h
class CFK_BASE; // Forward declaration

class CSmElemModifyExtrude : public CDialog
{
// Construction
public:
CDlgSubmenuExtrude(CWnd* pParent = NULL); // standard constructor
CDlgSubmenuExtrude ( CFK_BASE* pWhereDlgSubmenuPtrIsKept,
CWnd* pParent = NULL); // added
public:
CFK_BASE* m_pWhereDlgPtrIs; // added

-------------------------------------------------------- DlgSubmenuExtrude.cpp
#include "stdafx.h"
#include "g.h"
#include "DlgSubmenuExtrude.h"

#include "GGlobal.h"
#include "GUtil.h"
#include "GDoc.h"

#include "GFK_base.h"
#include "GFK_editing.h"

/////////////////////////////////////////////////////////////////////////////
CDlgSubmenuExtrude::CDlgSubmenuExtrude(CFK_BASE* pFK, CWnd* pParent)
: CDialog(CDlgSubmenuExtrude::IDD, pParent)
{
m_pWhereDlgPtrIs = (CFK_BASE*) pFK;
}
/////////////////////////////////////////////////////////////////////////////
void CDlgSubmenuExtrude::PostNcDestroy()
{
m_pWhereDlgPtrIs->m_pDlgSubmenu = NULL;
CDialog::PostNcDestroy();
delete this;
}

=========================================================================

FM ROTATE - VISUAL CUE (CIRCLE)

Gxxx.cpp

--------------------------------------------------------------- AGlobal.h
enum DISPLAY_LIST // Display list id
{
DL_ZERO_ILLEGAL,
DL_AXIS,
DL_CAGE,
DL_POINT,
DL_CUR_PLANE,
DL_CIRCLE,
};
------------------------------------------------------ CGDocFK_kernel.cpp
void CGDoc::FromOnNewDocument()
{
HGLRC hRC = wglGetCurrentContext(); // Check if any RC is "current"
HDC hDC = wglGetCurrentDC();
VERIFY (wglMakeCurrent (m_master_hDC, m_master_hRC));
CreateDisplayList ( DL_CAGE );
CreateDisplayList ( DL_AXIS );
CreateDisplayList ( DL_POINT );
CreateDisplayList ( DL_CUR_PLANE );
CreateDisplayList ( DL_CIRCLE );
if (hRC && hDC) ::wglMakeCurrent (hDC, hRC);
}
------------------------------------------------------ CGDocFK.cpp
void CGDoc::CreateDisplayList ( DISPLAY_LIST no )
{
glNewList ( no, GL_COMPILE);
switch ( no )
{
case DL_CIRCLE:
{
int total = 16;
float r = 1.0f;

float a = 0.3827f * r;
float b = 0.9239f * r;
float s = 0.7071f * r;
CPoint2D p[] = { CPoint2D ( 0, r ),
CPoint2D ( a, b ),
CPoint2D ( s, s ),
CPoint2D ( b, a ),
CPoint2D ( r, 0 ),
CPoint2D ( b,-a ),
CPoint2D ( s,-s ),
CPoint2D ( a,-b ),
CPoint2D ( 0,-r ),
CPoint2D (-a,-b ),
CPoint2D (-s,-s ),
CPoint2D (-b,-a ),
CPoint2D (-r, 0 ),
CPoint2D (-b, a ),
CPoint2D (-s, s ),
CPoint2D (-a, b ) };
glBegin ( GL_LINE_LOOP );
for ( int i = 0; i < total; i++ )
glVertex3f ( p[i].x , p[i].y , 0.0f );
glEnd ();
break;
};
case DL_AXIS: // Axis
glBegin ( GL_LINES );
glColor3f (1.0f, 0.0f, 0.0f);
glVertex3f ( 0.0f, 0.0f, 0.0f );
glVertex3f ( size, 0.0f, 0.0f );
glEnd();
case DL_POINT: // Point element
glPushAttrib ( GL_ALL_ATTRIB_BITS );
glDisable ( GL_LIGHTING );
glColor3f (1.0f, 1.0f, 0.0f);
glBegin ( GL_LINES );
glVertex3f ( 0.0f , 0.0f , s );
glVertex3f ( 0.0f , 0.0f , -s );
glVertex3f ( s , 0.0f , 0.0f );
glEnd();
glEnable ( GL_LIGHTING );
glPopAttrib ();
case DL_CUR_PLANE: /// Current plane
glColor3f (0.4f, 0.4f, 0.4f);
glBegin ( GL_LINES );
for (int k = 0; k < total; k++)
{
glVertex3f ( xxx, yy, zzz );
glVertex3f (-xxx, yy, zzz );
xx += increment;
};
glEnd ();
glEndList();
}
------------------------------------------------------ CGDocFK.cpp
void CGDoc::DrawAllTempElems ()
{
int i;
CFK_BASE* pFK = ( m_pFKT ) ? m_pFKT : m_pFK;

// --------------------------------------------------- Points
if ( m_tempPointTotal )
{
glPointSize (6.0);
glBegin ( GL_POINTS );
for ( i = 0; i < m_tempPointTotal; i++ )
{
glColor3f ( 1.0f, 0.0f, 1.0f ); // Yellow
glVertex3f ( m_tempPointArray[i].x ,
m_tempPointArray[i].y ,
m_tempPointArray[i].z );
// --------------------------------------------------- Lines
if ( m_tempLineTotal )
{
for ( i = 0; i < m_tempLineTotal; i++ )
{
SetTempColorAndStyle ( m_tempLineColor [i], m_tempLineStyle [i] );
// Color setting
glBegin ( GL_LINES );
glVertex3f ( m_tempLineArray[0][i].x ,
m_tempLineArray[0][i].y ,
m_tempLineArray[0][i].z );
glVertex3f ( m_tempLineArray[1][i].x ,
m_tempLineArray[1][i].y ,
m_tempLineArray[1][i].z );
glEnd ();
// Line style reset
if ( m_tempLineStyle [i] == DASH ) glDisable (GL_LINE_STIPPLE);
}
}
// ------------------------------------------------ Multi-Line 1
if ( m_tempMultiLineTotal1 )
{
glLineWidth ( 3.0 );
glBegin ( GL_LINE_STRIP );
for ( i = 0; i < m_tempMultiLineTotal1; i++ )
{
SetTempColorAndStyle ( m_tempMultiLineColor1, m_tempMultiLineStyle1 );
glVertex3f ( m_tempMultiLineArray1[i].x ,
m_tempMultiLineArray1[i].y ,
m_tempMultiLineArray1[i].z );
}
glEnd ();
}
// ------------------------------------------------ Circle
for ( i = 0; i < m_tempCircleTotal; i++ )
{
SetTempColorAndStyle ( m_tempCircleColor [i], m_tempCircleStyle [i] );
//---------- SetTempColorAndStyle ( -- )
// Construct [M] matrix based on the following:
CPoint3D orign = m_tempCircleArray [0][i]; // origin
CPoint3D zAxis = m_tempCircleArray [1][i]; // direction
float radius = m_tempCircleRadius [i]; // radius

CPoint3D x ( 1,0,0 );
CPoint3D y ( 0,1,0 );
CPoint3D xAxis, yAxis;

xAxis = x * zAxis;
if ( ! ( xAxis.Length() > 0.0f ) ) xAxis = y * zAxis;
xAxis = xAxis.Normalize();
zAxis = zAxis.Normalize();
yAxis = zAxis * xAxis;

// Scale by radius
xAxis = xAxis * radius;
yAxis = yAxis * radius;
zAxis = zAxis * radius;

// Put it in matrix form
GLfloat mmm[16] = { xAxis.x, xAxis.y, xAxis.z, 0.0f ,
yAxis.x, yAxis.y, yAxis.z, 0.0f ,
zAxis.x, zAxis.y, zAxis.z, 0.0f ,
orign.x, orign.y, orign.z, 1.0f };

// Apply the matrix just before displaying object
glLoadIdentity();
glMultMatrixf(mmm);
glCallList ( DL_CIRCLE );
glLoadIdentity();
}
/////////////////////////////////////////////////////////////////////////////
void CGDoc::SetTempColorAndStyle ( G_COLOR color, G_STYLE style )
{
// Color setting
if ( RED == color ) glColor3f (1.0f,0.0f,0.0f);
else if( GREEN == color ) glColor3f (0.0f,1.0f,0.0f);
else if( BLUE == color ) glColor3f (0.0f,0.0f,1.0f);
else if( YELLOW == color ) glColor3f (1.0f,1.0f,0.0f);
// Line style setting
if ( DASH == style )
{
glEnable (GL_LINE_STIPPLE);
glLineStipple (1, 0x00FF); // dashed line
glLineWidth (1.0);
}
}

=========================================================================

UNDO / REDO IMPLEMENTATION

Gxxx.cpp

----------------- Enable / Disable menu -----------------------

void CGDoc::OnEditRedo()
{
if ( m_pFKT == NULL ) m_pFK->Redo (); else m_pFKT->Redo (); // 1999-10-26
}
void CGDoc::OnUpdateEditRedo(CCmdUI* pCmdUI)
{
pCmdUI->Enable ((m_pFKT == NULL) ? m_pFK->m_bRedoable : m_pFKT->m_bRedoable);
}
void CGDoc::OnEditUndo()
{
if ( m_pFKT == NULL ) m_pFK->Undo (); else m_pFKT->Undo (); // 1999-10-26
}
void CGDoc::OnUpdateEditUndo(CCmdUI* pCmdUI)
{
pCmdUI->Enable ((m_pFKT == NULL) ? m_pFK->m_bUndoable : m_pFKT->m_bUndoable);
}

----------------- View.cpp --------------------------

void CGView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
case VK_F5: // msgType = MENU;
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->Undo ();
else pDoc->m_pFKT->Undo (); // 1999-10-9
break;
case VK_F9: // msgType = MENU;
if ( pDoc->m_pFKT == NULL ) pDoc->m_pFK->Redo ();
else pDoc->m_pFKT->Redo (); // 1999-10-9
break;

------------------------ FK BASE --------------------------

/////////////////////////////////////////////////////////////////////////////
int CFK_BASE::IncrementUndoLevel ()
{
// Cyclic array
return m_undoLevel = CyclicIncrement ( m_undoLevel, MAX_UNDO_LEVEL );
}
/////////////////////////////////////////////////////////////////////////////
int CFK_BASE::DecrementUndoLevel ()
{
// Cyclic array
return m_undoLevel = CyclicDecrement ( m_undoLevel, MAX_UNDO_LEVEL );
}
/////////////////////////////////////////////////////////////////////////////
void CFK_BASE::EnableUndo (int item)
{
// This function is called by FK to enable an undo for a specific undo-item.
// This, in turn, calls FK-specific EventForUNDO (item, ENABLE_UNDO) to prepare
// for the undo. The current undo-action-level is incremented and the item
// is marked undoable at that undo-level for this undo-item.

// Enabling a new undo-item automatically relinquishes all current and past
// redoable items
KillAllRedos ();

// Call EventForUNDO with ENABLE_UNDO
EventForUNDO ( item, ENABLE_UNDO );

// Update the current undo-action-level by incrementing by one
IncrementUndoLevel();

// Make the undo item given undoable at the current action level
m_undoable [m_undoLevel] = item;

// Check the current undo/redo status
m_bUndoable = (m_undoable [ m_undoLevel ] == 0) ? false : true;
m_bRedoable = (m_redoable [ m_undoLevel ] == 0) ? false : true;
}
/////////////////////////////////////////////////////////////////////////////
void CFK_BASE::Undo ( bool autoRedoSet )
{
// This function is called by View when the user action invoked an UNDO_EVENT event.
// This function, in turn, calls a FK-specific EventForUNDO (item, UNDO_EVENT) for
// a specific undo-item that is undoable at the current undo-action-level.
// This item is automatically set redoable at the new current level. FK can
// override this by setting autoRedoSet flag to false. (Default is true.)

// Undoable undo item number at the current undo action level
int item = m_undoable [ m_undoLevel ];

if ( item > 0 )
{
// Perform undo
EventForUNDO ( item, UNDO_EVENT );

// Disable undo at this level
m_undoable [ m_undoLevel ] = 0;

// Decrement the current undo action level
DecrementUndoLevel();

// Enable redo of the same item at this new level
if ( autoRedoSet ) m_redoable [ m_undoLevel ] = item;
}
// Check the current undo/redo status
m_bUndoable = (m_undoable [ m_undoLevel ] == 0) ? false : true;
m_bRedoable = (m_redoable [ m_undoLevel ] == 0) ? false : true;
}
/////////////////////////////////////////////////////////////////////////////
void CFK_BASE::Redo ( bool autoUndoSet )
{
// This function is called by View when the user action invoked a REDO_EVENT event.
// This function, in turn, calls a FK-specific EventForUNDO (item, REDO_EVENT) for
// a specific undo-item that is redoable at the current undo-action-level.
// This item is automatically set undoable at the new current level. FK can
// override this by setting autoUndoSet flag to false. (Default is true.)

// Redoable undo-item number at the current undo action level
int item = m_redoable [ m_undoLevel ];

if ( item > 0 )
{
// Perform redo
EventForUNDO ( item, REDO_EVENT );

// Disable redo at this level
m_redoable [ m_undoLevel ] = 0;

// Increment the current undo-action-level
IncrementUndoLevel();

// Enable undo of the same item at this new level
if ( autoUndoSet ) m_undoable [ m_undoLevel ] = item;
}
// Check the current undo/redo status
m_bUndoable = (m_undoable [ m_undoLevel ] == 0) ? false : true;
m_bRedoable = (m_redoable [ m_undoLevel ] == 0) ? false : true;
}
/////////////////////////////////////////////////////////////////////////////
void CFK_BASE::BackUndoLevels ( int n )
{
// Name change --- dont use KILL_REDO
// Name change --- dont use KILL_REDO
// Name change --- dont use KILL_REDO

// This function disables n levels of previous undo's starting from the
// current undo-action-level.

// Make sure it's no bigger than MAX
int nn = ( n <= MAX_UNDO_LEVEL ) ? n : MAX_UNDO_LEVEL;

for ( int i = 0; i < nn; i++ )
{
if ( m_undoable [m_undoLevel] == 0 ) break;
m_undoable [ m_undoLevel ] = 0;
// Decrement the current undo action level
DecrementUndoLevel ();
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_BASE::KillAllRedos ()
{
// This function is always called by EnableUndo (item). That is, whenever
// a new undoable item is added, any and all current and previous redoable
// items are thrown away permanently. This function is also called by FK
// when leaving redoable item(s) for good.

// This function will disable all redoable items in the m_redoable[] array.
// In the process, this function calls a FK-specific EventForUNDO (item, KILL_REDO)
// for as many items as needed. The purpose of a FK-specific EventForUNDO
// function is to do the cleanup chores resulting from a temporary
// undo operation. Example: no-show when undo and erase when leaving the
// redoable state permanently.
//
// Note: This function is harmless if there is no redoable items.

// Do not change the current level, so copy...
int level = m_undoLevel;

int count = 0;
for ( int i = 0; i < MAX_UNDO_LEVEL; i++ )
{
// Redoable item number at the current undo-action-level
int item = m_redoable [ level ];
// if ( item == 0 ) break;
if ( item == 0 ) continue;

// Call multiple times
EventForUNDO ( item, KILL_REDO );
count++;

// Disable redo at this level
m_redoable [ level ] = 0;

// Increment the current undo action level
level = CyclicIncrement ( level, MAX_UNDO_LEVEL );
}
}


HOW TO ADD COMBO-BOX ON THE TOOLBAR

Gxxx.cpp

<MainFrm.h>
/////////////////////////////////////////////////////////////////////////////
class CMainFrame : public CMDIFrameWnd
{
DECLARE_DYNAMIC(CMainFrame)
// Operations
public:
bool CreateComboBoxForLayer();
protected:
CComboBox m_comboBoxLayer;
...

<MainFrm.cpp>
/////////////////////////////////////////////////////////////////////////////
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
........
......
// if (!m_wndToolBar11.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
// | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
// !m_wndToolBar11.LoadToolBar(IDR_TOOLBAR11))
if (!CreateComboBoxForLayer()) // in place of tool bar 11 creation
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
/////////////////////////////////////////////////////////////////////////////
bool CMainFrame::CreateComboBoxForLayer ()
{
// This is to add a combo box (for default layer) on the toolbar

int index = 3; // The fourth item in the toolbar (index = 4 - 1)
int number = 10; // The number of items in the combo box to appear
int i, iID;

if (!m_wndToolBar11.CreateEx(this, TBSTYLE_FLAT,
WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY |
CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar11.LoadToolBar(IDR_TOOLBAR11))
{
TRACE0 ("Failed ---\n");
return false; // failed to create
}
// Set all buttons ??
iID = m_wndToolBar11.CommandToIndex(IDS_LAYER_1);
if (iID >= 0)
{
for (i = iID; i < (iID + number); i++)
m_wndToolBar11.SetButtonStyle(i, TBBS_CHECKGROUP);
}
// Add the combo
int nWidth = 100;
int nHeight = 300; // height of drop down list

// Configure the combo place holder
m_wndToolBar11.SetButtonInfo (index, IDC_COMBO_LAYER, TBBS_SEPARATOR, nWidth);

// Get the bar height of the 13th item (combo we are adding)
CRect rect;
m_wndToolBar11.GetItemRect (index, &rect);
rect.bottom = rect.top + nHeight;

// Create the combo box - m_comboBox is a member variable added
m_comboBoxLayer.Create (WS_CHILD | WS_VISIBLE | WS_VSCROLL |
CBS_DROPDOWNLIST, rect, &m_wndToolBar11, IDC_COMBO_LAYER);

// Fill the combo box
CString szStyle;
if (szStyle.LoadString(IDS_LAYER_1)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_2)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_3)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_4)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_5)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_6)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_7)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_8)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_9)) m_comboBoxLayer.AddString((LPCTSTR)szStyle);
if (szStyle.LoadString(IDS_LAYER_10))m_comboBoxLayer.AddString((LPCTSTR)szStyle);
return true;
}
=========================================================================

HOW TO HANDLE COMBO-BOX EVENT ON THE TOOLBAR

Gxxx.cpp

<MainFrm.h>
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnWindowVptProperty();
afx_msg void OnSelChangeLayer();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

<MainFrm.cpp>
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_COMMAND(ID_WINDOW_VPT_PROPERTY, OnWindowVptProperty)
//}}AFX_MSG_MAP
ON_CBN_SELCHANGE(IDC_COMBO_LAYER, OnSelChangeLayer)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
void CMainFrame::OnSelChangeLayer()
{
// Get the new combo selection
int index = m_comboBoxLayer.GetCurSel ();
if (index == CB_ERR) return;

// Get active document (below did not work for MDI)
// -- CGDoc* pDoc = (CGDoc*)GetActiveDocument ();
// -- if (pDoc) ...
CMDIChildWnd* pActiveChild = MDIGetActive();
CGDoc* pDoc;
if (pActiveChild == NULL || (pDoc = (CGDoc*)pActiveChild->GetActiveDocument()) == NULL)
{
TRACE0("Warning: No active document for WindowNew command.\n");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
return; // command failed
}
else // otherwise we have a new frame !
{
// Set the layer as default layer
pDoc->m_pData->m_layerDefault = index + 1;
pDoc->m_pData->m_pFK->SystemFeedbackMessage1 (" New default layer set");
}
}
 

 

How to add prompt messages to a command

1) Define prompts in NXS() method in the commnad

void CFK_cfdMyIbitsuTest::NXS ( int nxs )
{
switch ( nxs )
{
case 1: m_stringID = IDP_CFD_TEST_1; break;
case 2: m_stringID = IDP_CFD_TEST_2; break;
case 3: m_stringID = IDP_CFD_TEST_3; break;
}
CFK_BASE::NXS ( nxs ); // Call base function at the end
}

2) Define ID in G\Resource.h

#define IDP_CFD_TEST_1  36490
#define IDP_CFD_TEST_2  36491
#define IDP_CFD_TEST_3  36492

Ensure a new number is used

#define _APS_NEXT_COMMAND_VALUE 36493

Copy this Resource.h file to A_Include folder.

3) Define prompts in G.rc (use Find in Files search of ID)

     STRINGTABLE DISCARDABLE
     BEGIN
     IDP_CFD_TEST_1 "Click Space-bar to make structured list"
     IDP_CFD_TEST_2 "Click Tab-key to move grid plane"
     IDP_CFD_TEST_3 "Key in number of grids"
     END

FM Command

1)  GFK_cfd.h / cpp --- FM Command Implementation

     CFK_PipingAaa::CFK_PipingAaa (CData* pData) : CFK_baseP (pData) // constructor
     {
          // Add FK entry_time initialization below
          m_FKmode = FK_PIPING_AAA; // See Effective C++ enum???
          m_stringFM = IDP_PIPING_AAA_FM;
          NXS (1);
          SetSubmenu ();
     }
     CFK_PipingAaa::~CFK_PipingAaa () // desctructor
     {
     }
     void CFK_PipingAaa::InitializeFK ()
     {
          // This is just a test (only works on menu, nut toolbar icons
          CMenu* pM = AfxGetMainWnd()->GetMenu();
          ASSERT_VALID (pM);
          pM->EnableMenuItem (ID_GROUP_SELECT, MF_BYCOMMAND | MF_ENABLED);
          pM->EnableMenuItem (ID_FILE_NEW, MF_BYCOMMAND | MF_ENABLED);
     }
     void CFK_PipingAaa::NXS ( int nxs )
     {
          switch ( nxs )
          {
          case 1: m_stringID = IDP_PIPING_AAA_1; break;
          case 2: m_stringID = IDP_PIPING_AAA_2; break;
          case 3: m_stringID = IDP_PIPING_AAA_3; break;
          }
          CFK_BASE::NXS ( nxs ); // Call base function at the end
     }
     void CFK_PipingAaa::SetSubmenu ( UINT )
     {
          m_submenuType = A;
          m_submenuTotal = 4;
          m_submenu1 = IDSM_CREATE_POINT_1;
          m_submenu2 = IDSM_CREATE_POINT_2;
          ShowSubmenu ();
     }

2)  GDoc.h --- Message Map

      afx_msg void OnPipingAaa();
      afx_msg void OnUpdatePipingAaa();

3)  GDoc.cpp --- Message Map

     ON_COMMAND(ID_PIPING_AAA, OnPipingAaa)
     ON_UPDATE_COMMAND_UI(ID_PIPING_AAA, OnUpdatePipingAaa)

     void CGDoc::OnPipingAaa()
     { m_pData->m_pFK = new CFK_PipingAaa (m_pData); InitializeFK(); }
     void CGDoc::OnUpdatePipingAaa(CCmdUI* pCmdUI)
     { m_pData->m_pFK->UpdateFKmode (pCmdUI, FK_PIPING_AAA); }

4)  G\Resource.h --- Resource definition

     #define ID_PIPING_AAA 36420
     #define ID_PIPING_BBB 36421
     #define ID_PIPING_CCC 36422

5)  G.rc --- Resource file

     IDR_TOOLBAR12 TOOLBAR DISCARDABLE 16, 15    ---- For Toolbar
     BEGIN
     BUTTON ID_PIPING_AAA
     BUTTON ID_PIPING_BBB
     BUTTON ID_PIPING_CCC
     END

     POPUP "Piping"   ------- For menu
     BEGIN
     MENUITEM "AAA", ID_PIPING_AAA
     MENUITEM "BBB", ID_PIPING_BBB
     MENUITEM "CCC", ID_PIPING_CCC
     END

     STRINGTABLE DISCARDABLE    ------- For prompt message
     BEGIN
     IDP_PIPING_AAA_1 "1 Prompt One"
     IDP_PIPING_AAA_2 "2 Prompt Two"
     IDP_PIPING_AAA_3 "3 Prompt Three"
     END

 

=========================================================================

HOW TO A NEW FM (FUNCTION MODE)

Gxxx.cpp

// GGlobal.h
enum FK_MODE // Both FK_mode & FK_modeT
{
FK_CREATE_EDGE,
FK_CUR_PLANE_ORIGIN,

// Resource.h
IDP_CREATE_EDGE_FM; // FK title on Desktop
IDP_CREATE_EDGE_1; // Prompt 1,2,3,...
IDP_CREATE_EDGE_2;

// G.rc (Search for "IDP_CREATE_EDGE_FM" in Find in Files and double-click
Define messages and tool tips...

// Create FK class (.h/.cpp)

// Add menu item to invoke this FK

// Add toolbar icon for short-cut

// Use ClassWizard to activate this menu

// GDoc.h
afx_msg OnCfdGridGeneration
afx_msg OnUpdateCfdGridGeneration
// GDoc.cpp
ON_COMMAND CfdGridGeneration
ON_UPDATE_COMMAND CfdGridGeneration
-----
OnCfdGridGeneration
OnUpdateCfdGridGeneration
//-------------- FK permanent
/////////////////////////////////////////////////////////////////////////////
void CGDoc::OnCreateEdge()
{ m_pFK = new CFK_createEdge( this ); SetFocus(); }
void CGDoc::OnUpdateCreateEdge(CCmdUI* pCmdUI)
{ m_pFK->UpdateFKmode ( pCmdUI, FK_CREATE_EDGE ); }
/////////////////////////////////////////////////////////////////////////////

//-------------- FK temporary
/////////////////////////////////////////////////////////////////////////////
void CGDoc::OnCurPlaneOrigin()
{ if (SetFKmodeT(FK_CUR_PLANE_ORIGIN)) m_pFKT = new CFK_curPlaneOrigin(this); SetFocus(); }
void CGDoc::OnUpdateCurPlaneOrigin(CCmdUI* pCmdUI)
{ UpdateFKmodeT ( pCmdUI, FK_CUR_PLANE_ORIGIN ); }
/////////////////////////////////////////////////////////////////////////////

// --------------- How FK/FKT are Managed------------------------------
/////////////////////////////////////FK Permanent /////////////////
void CGDoc::OnElemMirror()
{ m_pData->m_pFK = new CFK_elemMirror (m_pData); SetFocus(); }
void CGDoc::OnUpdateElemMirror(CCmdUI* pCmdUI)
{ m_pData->m_pFK->UpdateFKmode ( pCmdUI, FK_ELEM_MIRROR ); }
/////////////////////////////////////////////////////////////////////////////
CFK_baseP::CFK_baseP (CData* pData) : CFK_BASE (pData)
{
if ( m_pData->m_pFK != NULL ) // Destroy the previous FK
{ ///////////////DELETE FK PERMANENT ///////////(3)
m_pData->m_pFK->EventForEXIT ();
delete m_pData->m_pFK;
}
if ( m_pData->m_pFKT != NULL ) // Destroy temporary FK
{ ///////////////DELETE FK TEMPO ///////////(1)
m_pData->m_pFKT->EventForEXIT();
CFK_BASE* p = m_pData->m_pFKT;
m_pData->m_pFKT = NULL; // Set NULL before deleting itself
delete p;
} }
////////////////////////////////////////FK Temporary ///////////////////
void CGDoc::OnGroupSelect()
{ if (SetFKmodeT(FK_GROUP_SELECT)) m_pData->m_pFKT = new CFK_groupSelect(m_pData, this); SetFocus();}
void CGDoc::OnUpdateGroupSelect(CCmdUI* pCmdUI)
{ UpdateFKmodeT ( pCmdUI, FK_GROUP_SELECT ); }
/////////////////////////////////////////////////////////////////////////////
BOOL CGDoc::SetFKmodeT ( FK_MODE fk )
{
if ( m_pData->m_pFKT == NULL )
// No FK-temp existed before, so create new one
return true; // m_pData->m_pFKT = new CFK_viewRotPerp ( this );
else
{ if ( m_pData->m_pFKT->m_FKmode == fk )
{ // FK-temp existed is the same one, so exit and go back to FK-perm
///////////////DELETE FK TEMPO ///////////(1)
m_pData->m_pFKT->EventForEXIT();
CFK_BASE* p = m_pData->m_pFKT;
m_pData->m_pFKT = NULL; // Set NULL before deleting itself
delete p;
/////////RESTORE FK PERMANENT ////////////(2)
// Since going back to FK-permanent, so restore prompt message (by NXS)
m_pData->m_pFK->NXS ( m_pData->m_pFK->cxs );
// Also restore submenu
m_pData->m_pFK->ShowSubmenu ();
// Restore key-in focus
CGView::GetMyActiveView()->SetFocus();
return false; // No FK-temp needed
}
else
{ // Different FK-temp requested, so delete old & create new one
///////////////DELETE FK TEMPO ///////////(1)
// Delete FK-temp
m_pData->m_pFKT->EventForEXIT();
CFK_BASE* p = m_pData->m_pFKT;
m_pData->m_pFKT = NULL; // Set NULL before deleting itself
delete p;
return true; // m_pData->m_pFKT = new CFK_viewRotPerp ( this );
} } // SetFocus();
/////////////////////////////////////////////////////////////////////////////
void CFK_baseT::EventForESC ( UINT nFlags, CPoint pt )
{ // Going back to FK-permanent, so delete this FK-temporary and restore
// prompt message (by NXS). Since we are deleting "this" object,
// make sure "delete this" is the very last statement.
/////////RESTORE FK PERMANENT ////////////(2)
m_pData->m_pFK->NXS ( m_pData->m_pFK->cxs );
m_pData->m_pFK->ShowSubmenu ();
// CGView::GetMyActiveView()->SetFocus(); //  commented for view access
///////////////DELETE FK TEMPO ///////////(1)
m_pData->m_pFKT->EventForEXIT();
CFK_BASE* p = m_pData->m_pFKT;
m_pData->m_pFKT = NULL; // Set NULL before deleting itself
delete p;
/////////////////////////////////////////////////////////////////////////////
void CGDoc::OnGroupSelect()
{ // Get out of temporary FK Group and go back to FK-permanent
// if (SetFKmodeT(FK_ELEM_GROUP)) m_pData->m_pFKT = new CFK_elemGroup(this);}
// This OK icon should be enabled only when FK Group (temp) is active.
// And FK Group should be enabled only when qualifying FKs are active. // -------
if (NULL == m_pData->m_pFKT) return;
///////////////DELETE FK TEMPO ///////////(1)
m_pData->m_pFKT->EventForEXIT();
CFK_BASE* p = m_pData->m_pFKT;
m_pData->m_pFKT = NULL; // Set NULL before deleting itself
delete p;
/////////RESTORE FK PERMANENT ////////////(2)
m_pData->m_pFK->NXS ( m_pData->m_pFK->cxs );
m_pData->m_pFK->ShowSubmenu ();
CGView::GetMyActiveView()->SetFocus(); //
// Generate EventForGROUP for permanent FK
m_pData->m_pFK->EventForGROUP();
}
=========================================================================

=========================================================================

FM PROGRAMMING

Gxxx.cpp

class CFK_createLineX : public CFK_baseP
{
public:
CFK_createLineX ( CGDoc* pDoc );
~CFK_createLineX ( );
virtual void InitializeFK ( );
virtual void NXS (int nxs) ;
virtual void CommonTaskForNXS (int nxs) ;
virtual void SetSubmenuTexts ( UINT );
virtual void EventForMENU ( UINT item );

virtual void EventForDEFPT ( UINT, CPoint );
virtual void EventForEND ( UINT, CPoint );
virtual void EventForESC ( UINT, CPoint );
virtual void EventForUNDO ( int, UNDO_EVT );

FK_SUB_MODE m_mode;
int m_pointIndex;
CPoint3D m_pointArray [300]; // change to dynamic later

int m_index, m_level;
CElemBase* m_pElemArr [MAX_UNDO_LEVEL];

void VisualCueTempLines ();
};
=========================================================================

HOW TO xxxxxx

Gxxx.cpp

// --------------------------------------------------------------------- //
// new F K C R E A T E L I N E X  //
// --------------------------------------------------------------------- //

CFK_createLineX::CFK_createLineX ( CGDoc* pDoc ) // constructor
: CFK_baseP ( pDoc )
{
// Add FK entry_time initialization below
m_FKmode = FK_CREATE_LINE_X; // See Effective C++ enum???
m_stringFM = IDP_CREATE_LINE_FM;
InitializeFK ();
NXS (1);
ShowSubmenu (A);
}
/////////////////////////////////////////////////////////////////////////////
CFK_createLineX::~CFK_createLineX () // desctructor
{
RubberBandSpecialLineEnd ();
}
///////////////////////////////////////////////////qaz//////////////////////////
void CFK_createLineX::InitializeFK ()
{
// FK initialization that application can call anytime. Ex. After NXS(1).

// Matrix created and saved here based on cur.plane
// --- so, if cur.plane is changed during this FK, we are in trouble...
m_vcMatrixM = CMat4x4 ( m_pDoc->m_pCurPlane->GetMxAxisX(),
m_pDoc->m_pCurPlane->GetMxAxisY(),
m_pDoc->m_pCurPlane->GetMxAxisZ(),
m_pDoc->m_pCurPlane->GetMxOrigin() );
m_vcMatrixT = m_vcMatrixM.InverseByTranspose();
m_index = 0;
m_mode = LINE2D;
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::NXS ( int nxs )
{
switch ( nxs )
{
case 1: m_stringID = IDP_CREATE_LINE_1; break;
case 2: m_stringID = IDP_CREATE_LINE_2; break;
case 3: m_stringID = IDP_CREATE_LINE_3; break;
}
CFK_BASE::NXS ( nxs ); // Call base function at the end
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::CommonTaskForNXS ( int nxs )
{
switch ( nxs )
{
case 1:
ClearTempAll ();
m_pointIndex = 0;
RubberBandSpecialLineEnd ();
InvalidateAllVpts ();
break;
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::SetSubmenuTexts ( UINT )
{
m_submenuTotal = 3;
m_submenu1 = IDSM_CREATE_POLYGON;
m_submenu2 = IDSM_CREATE_LINE_2D;
m_submenu3 = IDSM_CREATE_LINE_3D;
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::EventForMENU ( UINT item )
{
switch ( item )
{
case 1: m_stringFM = IDP_CREATE_POLYGON_FM;
ShowSubmenu (A);
m_mode = POLYGON;
break;
case 2: m_stringFM = IDP_CREATE_LINE_FM;
ShowSubmenu (A);
m_mode = LINE2D;
break;
case 3: m_stringFM = IDP_CREATE_LINE_3D_FM;
ShowSubmenu (A);
m_mode = LINE3D;
break;
}
NXS (1);
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::EventForDEFPT ( UINT, CPoint)
{
switch (cxs)
{
case 1: case 2: case 3: case 4:
{
CPoint3D ptFinal = m_ptDEFPT;
// project if 2D or polygon
if ( m_mode == POLYGON || m_mode == LINE2D )
{
// Now project onto current plane - show visual cue line
CPoint3D transformed = m_vcMatrixT.vM ( m_ptDEFPT ); // = [V] x [M]
transformed.z = 0.0f; // PROJECT !!!
ptFinal = m_vcMatrixM.vM ( transformed ); // = [V] x [M]
}
m_pointArray [ m_pointIndex++ ] = ptFinal;
// Set ref pt (since ref pt automatically set is m_ptDEFPT
m_ptReference = ptFinal;

VisualCueTempLines ();
if ( m_mode != LINE3D ) TempLine ( YELLOW, DASH, ptFinal, m_ptDEFPT );
RubberBandSpecialLineBegin ( ptFinal );

EnableUndo (2);

if ( 4 == cxs ) NXS (4);
else if ( 2 == cxs && m_mode != POLYGON ) NXS (4);
else NXS ( cxs + 1 );

InvalidateAllVpts ();
break;
}
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::VisualCueTempLines()
{
ClearTempLine(); // To avoid temp array overflow
// ClearTempAll(); // erases key-in visual cue
TempPointNew ( RED, SOLID, m_pointArray [0] );
for ( int i = 1; i < m_pointIndex; i++ )
{
TempPoint ( RED, SOLID, m_pointArray [i] );
TempLine ( GREEN, DASH, m_pointArray [i], m_pointArray [i-1] );
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::EventForEND ( UINT, CPoint)
{
switch (cxs)
{
case 4:
if ( m_mode == POLYGON )
m_pDoc->CreatePolygon ( m_pointIndex, m_pointArray );
else if ( m_mode == LINE2D )
m_pDoc->CreateLine ( m_pointIndex, m_pointArray );
else if ( m_mode == LINE3D )
m_pDoc->CreateLine3D ( m_pointIndex, m_pointArray );

// Remove all the previous entries for undo-item 2item 2 undoa
BackUndoLevels (m_pointIndex);
EnableUndo (1);
NXS (1);

RubberBandSpecialLineEnd ();
ClearTempAll ();
InvalidateAllVpts ();
break;
}
}
/////////////////////////////////////////////////////////////////////////////
void CFK_createLineX::EventForESC ( UINT, CPoint)
{
switch (cxs)
{
case 1: case 2: case 3: case 4:
KillAllRedos();
NXS (1);
break;
}
}
/////////////////////////////////////////////////////////////////////////////
//void CFK_createLineX::EventForUNDO ( int item, UNDO_EVT evt, int count )
void CFK_createLineX::EventForUNDO ( int item, UNDO_EVT evt )
{
// The item is an undo-able item number. The evt is an event type which is one
// of the following:

int MAX = MAX_UNDO_LEVEL;
switch (item)
{
case 1:
switch (evt)
{
case UNDO_EVENT:
// Decrement BEFORE
m_level = m_index = CyclicDecrement (m_index, MAX);
m_pElemArr[m_index]->Hide();
NXS (1);
InvalidateAllVpts();
break;
case REDO_EVENT:
// Increment AFTER
m_pElemArr[m_index]->Show();
m_level = m_index = CyclicIncrement (m_index, MAX);
NXS (1);
InvalidateAllVpts();
break;
case ENABLE_UNDO:
// Increment AFTER
m_pElemArr [m_index] = m_pElemCur;
m_index = CyclicIncrement (m_index, MAX);
break;
case KILL_REDO:
// Do not change m_index (use local index, m_level)
m_pDoc->DeleteElem ( m_pElemArr [m_level] );
m_level = CyclicIncrement (m_level, MAX);
break;
}
break;

case 2:
switch (evt)
{
case UNDO_EVENT:
{
m_pointIndex--;
m_ptReference = m_pointArray [m_pointIndex - 1];
ClearTempAll ();
VisualCueTempLines();
RubberBandSpecialLineBegin ( m_pointArray [m_pointIndex - 1] );
InvalidateAllVpts();
if (m_pointIndex > 3) NXS (4);
else if (m_pointIndex == 2 && m_mode != POLYGON) NXS (2);
else NXS (m_pointIndex + 1);
break;
}
case REDO_EVENT:
{
m_pointIndex++;
m_ptReference = m_pointArray [m_pointIndex - 1];
VisualCueTempLines();
RubberBandSpecialLineBegin ( m_pointArray [m_pointIndex - 1] );
InvalidateAllVpts();
if (m_pointIndex > 3) NXS (4);
else if (m_pointIndex == 2 && m_mode != POLYGON) NXS (2);
else NXS (m_pointIndex + 1);
break;
}
case KILL_REDO:
// m_pDoc->DeleteElem ( m_pElemCur );
// InvalidateAllVpts();
break;
}
break;
}
}
 

 

===============================================================================

Copyright © 2010-2012 Makoto Honda. All Rights Reserved.                                       www.iNET1000.com    

===============================================================================

 

     

10 Makoto Honda. All Rights Reserved.                                       www.iNET1000.com