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
===============================================================================
|