home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------------------------------
- PatchTool
- ---------
-
- Patch tool class
-
- (C) Silicon Dream Ltd 1994
-
- ---------------------------------------------------------------------------
-
- Changes: Date:
- * Created file 27/12/94
- */
-
- #include <tool.h>
-
- #include "resource.h"
-
- #define POINT_BUFFER_SIZE 256
-
- class PatchTool: public Tool
- {
- private:
- Vec avecPoint[POINT_BUFFER_SIZE];
- ushort usNumPoints;
- HanVertex ahver[POINT_BUFFER_SIZE];
- ushort usNumVerts;
- HanPatch ahpat[POINT_BUFFER_SIZE-2];
- ushort usNumPats;
- char szErrTitle[20];
- HanObject hobj;
- HanCoorSys hcsysPatch;
-
- private:
- Redraw _cppdyn OnSelect(Vec &vec);
- Redraw _cppdyn OnUnSelect(bool *pbOkToChange);
- void _cppdyn OnConfigure();
- Redraw _cppdyn OnSet(Vec &vec);
- Redraw _cppdyn OnUndo();
- Redraw _cppdyn OnDo(Vec &vec);
- void _cppdyn DrawSoFar(HDC hdc, HanCoorSys hcsys, void *pvViewData, bool bInvalid);
-
- public:
- _cppdyn ~PatchTool() {};
- };
-
- IMPLEMENT_OBJECT(PatchTool)
-
- //---------------------------------------------------------------------------
- // OnSelect - Called when the tool is selected from the control bar's
- // button box
-
- Redraw _cppdyn PatchTool::OnSelect(Vec &vec)
- {
- /* Initially no points */
-
- usNumPoints=0;
-
- /* Write message (resource with id IDS_ONSELECT) in status bar */
-
- WriteMessage(IDS_ONSELECT);
- return REDRAW_NONE;
- }
-
- //---------------------------------------------------------------------------
- // OnUnSelect - Simply remove points drawn
-
- Redraw _cppdyn PatchTool::OnUnSelect(bool *pbOkToChange)
- {
- *pbOkToChange=TRUE;
- usNumPoints=0;
- EditInThisView(NULL_HANDLE);
- return REDRAW_REFRESH;
- }
-
- //---------------------------------------------------------------------------
- // OnConfigure - Calls up the autosmooth dialog for configuration
-
- void _cppdyn PatchTool::OnConfigure()
- {
- AutosmoothDlg();
- return;
- }
-
- //---------------------------------------------------------------------------
- // OnSet - Called when the control bar's 'Set' button is pressed
-
- Redraw _cppdyn PatchTool::OnSet(Vec &vec)
- {
- ulong ulRef;
- CoorSysInfo csi;
-
- /* Find currently selected object */
-
- if (usNumPoints==0)
- {
- hcsysPatch=hcsysActive;
- ulRef=0;
- hobj=GetNextSelected(hcsysPatch, &ulRef, OBJECT_HANDLE);
- if (hobj==NULL_HANDLE)
- {
- MessageBox(IDS_ERR_TITLE, IDS_NO_OBJECT_SELECTED, MB_ICONEXCLAMATION);
- return REDRAW_NONE;
- }
- if (GetNextSelected(hcsysPatch, &ulRef, OBJECT_HANDLE)!=NULL_HANDLE)
- {
- MessageBox(IDS_ERR_TITLE, IDS_ONLY_SELECT_ONE_OBJECT, MB_ICONEXCLAMATION);
- return REDRAW_NONE;
- }
- EditInThisView(hcsysPatch);
- }
-
- /* Do not allow user to create more points than buffer will hold */
-
- if (usNumPoints==POINT_BUFFER_SIZE)
- {
- MessageBox(IDS_ERR_TITLE, IDS_TOO_MANY_POINTS, MB_ICONEXCLAMATION);
- return REDRAW_NONE;
- }
-
- /* Add point to list */
-
- avecPoint[usNumPoints++]=vec;
- return REDRAW_TOOL;
- }
-
- //---------------------------------------------------------------------------
- // OnUndo - Called when 'Undo' is selected from the 'Edit' menu
-
- Redraw _cppdyn PatchTool::OnUndo()
- {
- ushort us, usNorm;
- HanNormal ahnor[MAX_PATCH_EDGES];
- PatchInfo pi;
-
- /* Remove patches */
-
- pi.ahver=NULL;
- pi.ahnor=ahnor;
- for (us=usNumPats; us--;)
- {
- pi.usNumEdges=MAX_PATCH_EDGES;
- QryPatch(hobj, ahpat[us], &pi);
- DelPatch(hobj, ahpat[us]);
-
- /* If curved, delete normals for this patch */
-
- if (!(pi.usFlags & PI_FLAT))
- {
- for (usNorm=pi.usNumEdges; usNorm--;)
- DelNormal(hobj, ahnor[usNorm]); // Dont check for in use (all will eventually be del.)
- }
- }
-
- /* Remove all verticies */
-
- for (us=usNumVerts; us--;)
- DelVertex(hobj, ahver[us]);
-
- usNumPoints=0;
- EditInThisView(NULL_HANDLE);
- return REDRAW_ALL;
- }
-
- //---------------------------------------------------------------------------
- // OnDo - Called when the control bar's 'Do' button is pressed
-
- Redraw _cppdyn PatchTool::OnDo(Vec &vec)
- {
- ushort us;
- GeomErr gerr;
- HanSurf hsur;
- SurfType st;
-
- /* Not enough points */
-
- if (usNumPoints<3)
- {
- MessageBox(IDS_ERR_TITLE, IDS_NOT_ENOUGH_POINTS);
- return REDRAW_TOOL;
- }
-
- /* Check to see if a surface is selected */
-
- hsur=hsurActive;
- if (hsur==NULL_HANDLE)
- {
- /* Use any old surface type, if one exists */
-
- GetFirstSurfType(&hsur);
- if (hsur==NULL_HANDLE)
- {
- /* No surfaces exist so define a default surface type */
-
- st.col.byRed=255;
- st.col.byGrn=255;
- st.col.byBlu=255;
- st.usFlags=0;
- st.usSpecRefChar=SRC_DULL;
- st.fShineCoef=1.0;
- st.fTransCoef=0.0;
- DefSurfType(&st, FALSE, &hsur);
- }
- }
-
- /* Create a Geometry vertex at each point */
-
- usNumVerts=usNumPoints;
- for (us=0; us<usNumVerts; us++)
- {
- gerr=::AddVertex(hobj, avecPoint[us], ahver+us);
- if (gerr!=GERR_OK)
- {
- /* Many errors can occur during patch creation. Rather than worrying
- about creating our own error messages for each case, let Geometry
- build the error string and stick it in a message box */
-
- usNumPoints=0;
- MessageBox(IDS_ERR_TITLE, gerr);
- return REDRAW_TOOL;
- }
- }
-
- /* Define patch on Genesis, using info from current settings */
-
- usNumPats=256;
- gerr=::DefPatch(hobj,
- usNumPoints,
- usSmoothFlags | DP_ATTEMPT_TO_FIX_PLANE,
- fSmoothAng,
- ahver,
- NULL,
- hsur,
- &usNumPats,
- ahpat);
- if (gerr!=GERR_OK)
- {
- /* Remove verticies */
-
- for (us=usNumPoints; us--;)
- DelVertex(hobj, ahver[us]);
-
- /* Get description of error from Geometry, and put it in
- a message box */
-
- MessageBox(IDS_ERR_TITLE, gerr);
- }
- usNumPoints=0;
- EditInThisView(NULL_HANDLE);
- ModifiedScene();
-
- return REDRAW_ALL;
- }
-
- //---------------------------------------------------------------------------
- // DrawSoFar - Called when the view gets repainted and we're in the middle of
- // constructing, so we can draw what we have so far
-
- void _cppdyn PatchTool::DrawSoFar(HDC hdc, HanCoorSys hcsys, void *pvViewData, bool bInvalid)
- {
- HPEN hpen, hpenOld;
- float fStartX, fStartY, fEndX, fEndY;
- ushort us;
- int iOldMode;
-
- if (usNumPoints==0)
- return;
-
- /* Create solid and dotted green pens with which to draw the patch */
-
- hpen=CreatePen(PS_DOT, 1, RGB(0, 200, 0));
- hpenOld=(HPEN) SelectObject(hdc, (HGDIOBJ) hpen);
- iOldMode=SetBkMode(hdc, TRANSPARENT);
-
- /* Draw each edge of the patch so far */
-
- for (us=1; us<usNumPoints; us++)
- {
- Get3DLine(hcsysPatch, avecPoint[us], avecPoint[us-1],
- &fStartX, &fStartY, &fEndX, &fEndY);
- MoveToEx(hdc, (int) fStartX, (int) fStartY, NULL);
- LineTo(hdc, (int) fEndX, (int) fEndY);
- }
-
- /* Draw endpoint marker */
-
- if (Get3DPoint(hcsysPatch, avecPoint[usNumPoints-1],
- &fStartX, &fStartY)==GERR_OK)
- DrawMarker(hdc, (int) fStartX, (int) fStartY, MT_BOX);
-
- /* We must restore the state of the DC before returning */
-
- SetBkMode(hdc, iOldMode);
- SelectObject(hdc, hpenOld);
- DeleteObject(hpen);
- return;
- }
-