home *** CD-ROM | disk | FTP | other *** search
/ Computerworld 1996 March / Computerworld_1996-03_cd.bin / idg_cd3 / grafika / 3d_graf / genv10 / toolexmp / patch.cpp next >
Encoding:
C/C++ Source or Header  |  1995-07-13  |  6.0 KB  |  245 lines

  1. /*---------------------------------------------------------------------------
  2.                 PatchTool
  3.                 ---------
  4.  
  5.     Patch tool class
  6.  
  7.     (C) Silicon Dream Ltd 1994
  8.  
  9.   ---------------------------------------------------------------------------
  10.  
  11. Changes:                            Date:
  12. * Created file                            27/12/94
  13. */
  14.  
  15. #include <tool.h>
  16.  
  17. #include "resource.h"
  18.  
  19. #define POINT_BUFFER_SIZE    40
  20.  
  21. class PatchTool: public Tool
  22.     {
  23.     private:
  24.         Vec        avecPoint[POINT_BUFFER_SIZE];
  25.         ushort        usNumPoints;
  26.         char        szErrTitle[20];
  27.         HanObject    hobj;
  28.  
  29.         Redraw _cppdyn OnSelect(Vec &vec);
  30.         Redraw _cppdyn OnSet(Vec &vec);
  31.         Redraw _cppdyn OnUndo();
  32.         Redraw _cppdyn OnDo(Vec &vec);
  33.         void _cppdyn DrawSoFar(HDC hdc, HanCoorSys hcsys, void *pvViewData, bool bInvalid);
  34.  
  35.     public:
  36.         _cppdyn ~PatchTool();
  37.     };
  38.  
  39. IMPLEMENT_OBJECT(PatchTool)
  40.  
  41. //---------------------------------------------------------------------------
  42. // Destructor
  43.  
  44. _cppdyn PatchTool::~PatchTool()
  45.     {
  46.     }
  47.  
  48. //---------------------------------------------------------------------------
  49. // OnSelect - Called when the tool is selected from the control bar's
  50. //          button box
  51.  
  52. Redraw _cppdyn PatchTool::OnSelect(Vec &vec)
  53.     {
  54.     /* Initially no points */
  55.  
  56.     usNumPoints=0;
  57.  
  58.     /* Write message (resource with id IDS_ONSELECT) in status bar */
  59.  
  60.     WriteMessage(IDS_ONSELECT);
  61.     return REDRAW_NONE;
  62.     }
  63.  
  64. //---------------------------------------------------------------------------
  65. // OnSet - Called when the control bar's 'Set' button is pressed
  66.  
  67. Redraw _cppdyn PatchTool::OnSet(Vec &vec)
  68.     {
  69.     char        szName[MAX_NAME_BUFF_LEN];
  70.  
  71.     /* Find currently selected object */
  72.  
  73.     if (usNumPoints==0)
  74.         {
  75.         GetSelectedObjects(szName, MAX_NAME_BUFF_LEN);
  76.         if ((hobj=GetObjectHandle(szName))==NULL_HANDLE)
  77.             {
  78.             MessageBox(IDS_ERR_TITLE, IDS_NO_OBJECT_SELECTED, MB_ICONEXCLAMATION);
  79.             return REDRAW_NONE;
  80.             }
  81.         }
  82.  
  83.     /* Do not allow user to create more points than buffer will hold */
  84.  
  85.     if (usNumPoints==POINT_BUFFER_SIZE)
  86.         {
  87.         MessageBox(IDS_ERR_TITLE, IDS_TOO_MANY_POINTS, MB_ICONEXCLAMATION);
  88.         return REDRAW_NONE;
  89.         }
  90.  
  91.     /* Add point to list */
  92.  
  93.     avecPoint[usNumPoints++]=vec;
  94.     return REDRAW_TOOL;
  95.     }
  96.  
  97. //---------------------------------------------------------------------------
  98. // OnUndo - Called when 'Undo' is selected from the 'Edit' menu and
  99. //        this tool is in the middle of constructing, or if it performed
  100. //        the last editing action
  101.  
  102. Redraw _cppdyn PatchTool::OnUndo()
  103.     {
  104.     ushort            usNumPats, us;
  105.     HanObject        hobj;
  106.     HanPatch        ahpat[POINT_BUFFER_SIZE-1];
  107.  
  108.     /* If we are in the middle of constructing a patch, remove the last
  109.        point */
  110.  
  111.     if (usNumPoints>0)
  112.         {
  113.         usNumPoints--;
  114.         return REDRAW_TOOL;
  115.         }
  116.  
  117.     /* Undo the effect of the entire session */
  118.  
  119. //    GetUndo(&hobj, sizeof(HanObject));
  120. //    GetUndo(&usNumPats, sizeof(ushort));
  121. //    GetUndo(ahpat, usNumPats*sizeof(HanPatch));
  122. //    for (us=usNumPats; us--;)
  123. //        DelPatch(hobj, ahpat[us]);
  124.  
  125.     return REDRAW_ALL;
  126.     }
  127.  
  128. //---------------------------------------------------------------------------
  129. // OnDo - Called when the control bar's 'Do' button is pressed
  130.  
  131. Redraw _cppdyn PatchTool::OnDo(Vec &vec)
  132.     {
  133.     HanVertex        ahver[POINT_BUFFER_SIZE];
  134.     HanPatch        ahpat[POINT_BUFFER_SIZE-1];
  135.     ushort            us, usNumPats;
  136.     GeomErr            gerr;
  137.     HanSurf            hsur;
  138.  
  139.     /* Check to see if a surface is selected */
  140.  
  141.     hsur=GetCurrentSurf();
  142.     if (hsur==NULL_HANDLE)
  143.         {
  144.         MessageBox(IDS_ERR_TITLE, IDS_ERR_NO_SURF);
  145.         return REDRAW_TOOL;
  146.         }
  147.  
  148.     /* Create a Geometry vertex at each point */
  149.  
  150.     for (us=0; us<usNumPoints; us++)
  151.         {
  152.         gerr=::AddVertex(hobj, avecPoint[us], ahver+us);
  153.         if (gerr!=GERR_OK)
  154.             {
  155.             /* Many errors can occur during patch creation. Rather than worrying
  156.                about creating our own error messages for each case, let Geometry
  157.                build the error string and stick it in a message box */
  158.  
  159.             usNumPoints=0;
  160.             MessageBox(IDS_ERR_TITLE, gerr);
  161.             return REDRAW_TOOL;
  162.             }
  163.         }
  164.  
  165.     /* Define patch on Genesis, using info from current settings */
  166.  
  167.     usNumPats=40;
  168.     gerr=::DefPatch(hobj,
  169.             usNumPoints,
  170.             0,
  171.             0.0,
  172.             ahver,
  173.             NULL,
  174.             hsur,
  175.             &usNumPats,
  176.             ahpat);
  177.     if (gerr!=GERR_OK)
  178.         {
  179.         /* Remove verticies */
  180.  
  181.         for (us=usNumPoints; us--;)
  182.             DelVertex(hobj, ahver[us]);
  183.  
  184.         /* Get description of error from Geometry, and put it in
  185.            a message box */
  186.  
  187.         MessageBox(IDS_ERR_TITLE, gerr);
  188.         }
  189.     usNumPoints=0;
  190.  
  191.     /* All we need to 'undo' is the patch handle(s), as deleting a patch will also
  192.        delete its verticies if no other patch is using them. NB. There could be
  193.        more than one if Geometry had to split up the patch drawn */
  194.  
  195. //    SaveUndo(&hobj, sizeof(HanObject));
  196. //    SaveUndo(&usNumPats, sizeof(ushort));
  197. //    SaveUndo(ahpat, sizeof(HanPatch)*usNumPats);
  198.  
  199.     return REDRAW_ALL;
  200.     }
  201.  
  202. //---------------------------------------------------------------------------
  203. // DrawSoFar - Called when the view gets repainted and we're in the middle of
  204. //           constructing, so we can draw what we have so far
  205.  
  206. void _cppdyn PatchTool::DrawSoFar(HDC hdc, HanCoorSys hcsys, void *pvViewData, bool bInvalid)
  207.     {
  208.     HPEN            hpen, hpenOld;
  209.     float            fStartX, fStartY, fEndX, fEndY;
  210.     ushort            us;
  211.     int            iOldMode;
  212.  
  213.     if (usNumPoints==0)
  214.         return;
  215.  
  216.     /* Create solid and dotted green pens with which to draw the patch */
  217.  
  218.     hpen=CreatePen(PS_DOT, 1, RGB(0, 200, 0));
  219.     hpenOld=(HPEN) SelectObject(hdc, (HGDIOBJ) hpen);
  220.     iOldMode=SetBkMode(hdc, TRANSPARENT);
  221.  
  222.     /* Draw each edge of the patch so far */
  223.  
  224.     for (us=1; us<usNumPoints; us++)
  225.         {
  226.         Get3DLine(hcsysOnSelect, avecPoint[us], avecPoint[us-1],
  227.               &fStartX, &fStartY, &fEndX, &fEndY);
  228.         MoveTo(hdc, (int) fStartX, (int) fStartY);
  229.         LineTo(hdc, (int) fEndX, (int) fEndY);
  230.         }
  231.  
  232.     /* Draw endpoint marker */
  233.  
  234.     if (Get3DPoint(hcsysOnSelect, avecPoint[usNumPoints-1],
  235.                &fStartX, &fStartY)==GERR_OK)
  236.         DrawMarker(hdc, (int) fStartX, (int) fStartY, MT_BOX);
  237.  
  238.     /* We must restore the state of the DC before returning */
  239.  
  240.     SetBkMode(hdc, iOldMode);
  241.     SelectObject(hdc, hpenOld);
  242.     DeleteObject(hpen);
  243.     return;
  244.     }
  245.