home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1997 June / PC_Shareware-1997-06.iso / programy / genesis / patch.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-17  |  7.0 KB  |  298 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    256
  20.  
  21. class PatchTool: public Tool
  22.     {
  23.     private:
  24.         Vec        avecPoint[POINT_BUFFER_SIZE];
  25.         ushort        usNumPoints;
  26.         HanVertex    ahver[POINT_BUFFER_SIZE];
  27.         ushort        usNumVerts;
  28.         HanPatch    ahpat[POINT_BUFFER_SIZE-2];
  29.         ushort        usNumPats;
  30.         char        szErrTitle[20];
  31.         HanObject    hobj;
  32.         HanCoorSys    hcsysPatch;
  33.  
  34.     private:
  35.         Redraw _cppdyn OnSelect(Vec &vec);
  36.         Redraw _cppdyn OnUnSelect(bool *pbOkToChange);
  37.         void _cppdyn OnConfigure();
  38.         Redraw _cppdyn OnSet(Vec &vec);
  39.         Redraw _cppdyn OnUndo();
  40.         Redraw _cppdyn OnDo(Vec &vec);
  41.         void _cppdyn DrawSoFar(HDC hdc, HanCoorSys hcsys, void *pvViewData, bool bInvalid);
  42.  
  43.     public:
  44.         _cppdyn ~PatchTool() {};
  45.     };
  46.  
  47. IMPLEMENT_OBJECT(PatchTool)
  48.  
  49. //---------------------------------------------------------------------------
  50. // OnSelect - Called when the tool is selected from the control bar's
  51. //          button box
  52.  
  53. Redraw _cppdyn PatchTool::OnSelect(Vec &vec)
  54.     {
  55.     /* Initially no points */
  56.  
  57.     usNumPoints=0;
  58.  
  59.     /* Write message (resource with id IDS_ONSELECT) in status bar */
  60.  
  61.     WriteMessage(IDS_ONSELECT);
  62.     return REDRAW_NONE;
  63.     }
  64.  
  65. //---------------------------------------------------------------------------
  66. // OnUnSelect - Simply remove points drawn
  67.  
  68. Redraw _cppdyn PatchTool::OnUnSelect(bool *pbOkToChange)
  69.     {
  70.     *pbOkToChange=TRUE;
  71.     usNumPoints=0;
  72.     EditInThisView(NULL_HANDLE);
  73.     return REDRAW_REFRESH;
  74.     }
  75.  
  76. //---------------------------------------------------------------------------
  77. // OnConfigure - Calls up the autosmooth dialog for configuration
  78.  
  79. void _cppdyn PatchTool::OnConfigure()
  80.     {
  81.     AutosmoothDlg();
  82.     return;
  83.     }
  84.  
  85. //---------------------------------------------------------------------------
  86. // OnSet - Called when the control bar's 'Set' button is pressed
  87.  
  88. Redraw _cppdyn PatchTool::OnSet(Vec &vec)
  89.     {
  90.     ulong        ulRef;
  91.     CoorSysInfo    csi;
  92.  
  93.     /* Find currently selected object */
  94.  
  95.     if (usNumPoints==0)
  96.         {
  97.         hcsysPatch=hcsysActive;
  98.         ulRef=0;
  99.         hobj=GetNextSelected(hcsysPatch, &ulRef, OBJECT_HANDLE);
  100.         if (hobj==NULL_HANDLE)
  101.             {
  102.             MessageBox(IDS_ERR_TITLE, IDS_NO_OBJECT_SELECTED, MB_ICONEXCLAMATION);
  103.             return REDRAW_NONE;
  104.             }
  105.         if (GetNextSelected(hcsysPatch, &ulRef, OBJECT_HANDLE)!=NULL_HANDLE)
  106.             {
  107.             MessageBox(IDS_ERR_TITLE, IDS_ONLY_SELECT_ONE_OBJECT, MB_ICONEXCLAMATION);
  108.             return REDRAW_NONE;
  109.             }
  110.         EditInThisView(hcsysPatch);
  111.         }
  112.  
  113.     /* Do not allow user to create more points than buffer will hold */
  114.  
  115.     if (usNumPoints==POINT_BUFFER_SIZE)
  116.         {
  117.         MessageBox(IDS_ERR_TITLE, IDS_TOO_MANY_POINTS, MB_ICONEXCLAMATION);
  118.         return REDRAW_NONE;
  119.         }
  120.  
  121.     /* Add point to list */
  122.  
  123.     avecPoint[usNumPoints++]=vec;
  124.     return REDRAW_TOOL;
  125.     }
  126.  
  127. //---------------------------------------------------------------------------
  128. // OnUndo - Called when 'Undo' is selected from the 'Edit' menu
  129.  
  130. Redraw _cppdyn PatchTool::OnUndo()
  131.     {
  132.     ushort            us, usNorm;
  133.     HanNormal        ahnor[MAX_PATCH_EDGES];
  134.     PatchInfo        pi;
  135.  
  136.     /* Remove patches */
  137.  
  138.     pi.ahver=NULL;
  139.     pi.ahnor=ahnor;
  140.     for (us=usNumPats; us--;)
  141.         {
  142.         pi.usNumEdges=MAX_PATCH_EDGES;
  143.         QryPatch(hobj, ahpat[us], &pi);
  144.         DelPatch(hobj, ahpat[us]);
  145.  
  146.         /* If curved, delete normals for this patch */
  147.  
  148.         if (!(pi.usFlags & PI_FLAT))
  149.             {
  150.             for (usNorm=pi.usNumEdges; usNorm--;)
  151.                 DelNormal(hobj, ahnor[usNorm]);    // Dont check for in use (all will eventually be del.)
  152.             }
  153.         }
  154.  
  155.     /* Remove all verticies */
  156.  
  157.     for (us=usNumVerts; us--;)
  158.         DelVertex(hobj, ahver[us]);
  159.  
  160.     usNumPoints=0;
  161.     EditInThisView(NULL_HANDLE);
  162.     return REDRAW_ALL;
  163.     }
  164.  
  165. //---------------------------------------------------------------------------
  166. // OnDo - Called when the control bar's 'Do' button is pressed
  167.  
  168. Redraw _cppdyn PatchTool::OnDo(Vec &vec)
  169.     {
  170.     ushort            us;
  171.     GeomErr            gerr;
  172.     HanSurf            hsur;
  173.     SurfType        st;
  174.  
  175.     /* Not enough points */
  176.  
  177.     if (usNumPoints<3)
  178.         {
  179.         MessageBox(IDS_ERR_TITLE, IDS_NOT_ENOUGH_POINTS);
  180.         return REDRAW_TOOL;
  181.         }
  182.  
  183.     /* Check to see if a surface is selected */
  184.  
  185.     hsur=hsurActive;
  186.     if (hsur==NULL_HANDLE)
  187.         {
  188.         /* Use any old surface type, if one exists */
  189.  
  190.         GetFirstSurfType(&hsur);
  191.         if (hsur==NULL_HANDLE)
  192.             {
  193.             /* No surfaces exist so define a default surface type */
  194.  
  195.             st.col.byRed=255;
  196.             st.col.byGrn=255;
  197.             st.col.byBlu=255;
  198.             st.usFlags=0;
  199.             st.usSpecRefChar=SRC_DULL;
  200.             st.fShineCoef=1.0;
  201.             st.fTransCoef=0.0;
  202.             DefSurfType(&st, FALSE, &hsur);
  203.             }
  204.         }
  205.  
  206.     /* Create a Geometry vertex at each point */
  207.  
  208.     usNumVerts=usNumPoints;
  209.     for (us=0; us<usNumVerts; us++)
  210.         {
  211.         gerr=::AddVertex(hobj, avecPoint[us], ahver+us);
  212.         if (gerr!=GERR_OK)
  213.             {
  214.             /* Many errors can occur during patch creation. Rather than worrying
  215.                about creating our own error messages for each case, let Geometry
  216.                build the error string and stick it in a message box */
  217.  
  218.             usNumPoints=0;
  219.             MessageBox(IDS_ERR_TITLE, gerr);
  220.             return REDRAW_TOOL;
  221.             }
  222.         }
  223.  
  224.     /* Define patch on Genesis, using info from current settings */
  225.  
  226.     usNumPats=256;
  227.     gerr=::DefPatch(hobj,
  228.             usNumPoints,
  229.             usSmoothFlags | DP_ATTEMPT_TO_FIX_PLANE,
  230.             fSmoothAng,
  231.             ahver,
  232.             NULL,
  233.             hsur,
  234.             &usNumPats,
  235.             ahpat);
  236.     if (gerr!=GERR_OK)
  237.         {
  238.         /* Remove verticies */
  239.  
  240.         for (us=usNumPoints; us--;)
  241.             DelVertex(hobj, ahver[us]);
  242.  
  243.         /* Get description of error from Geometry, and put it in
  244.            a message box */
  245.  
  246.         MessageBox(IDS_ERR_TITLE, gerr);
  247.         }
  248.     usNumPoints=0;
  249.     EditInThisView(NULL_HANDLE);
  250.     ModifiedScene();
  251.  
  252.     return REDRAW_ALL;
  253.     }
  254.  
  255. //---------------------------------------------------------------------------
  256. // DrawSoFar - Called when the view gets repainted and we're in the middle of
  257. //           constructing, so we can draw what we have so far
  258.  
  259. void _cppdyn PatchTool::DrawSoFar(HDC hdc, HanCoorSys hcsys, void *pvViewData, bool bInvalid)
  260.     {
  261.     HPEN            hpen, hpenOld;
  262.     float            fStartX, fStartY, fEndX, fEndY;
  263.     ushort            us;
  264.     int            iOldMode;
  265.  
  266.     if (usNumPoints==0)
  267.         return;
  268.  
  269.     /* Create solid and dotted green pens with which to draw the patch */
  270.  
  271.     hpen=CreatePen(PS_DOT, 1, RGB(0, 200, 0));
  272.     hpenOld=(HPEN) SelectObject(hdc, (HGDIOBJ) hpen);
  273.     iOldMode=SetBkMode(hdc, TRANSPARENT);
  274.  
  275.     /* Draw each edge of the patch so far */
  276.  
  277.     for (us=1; us<usNumPoints; us++)
  278.         {
  279.         Get3DLine(hcsysPatch, avecPoint[us], avecPoint[us-1],
  280.               &fStartX, &fStartY, &fEndX, &fEndY);
  281.         MoveToEx(hdc, (int) fStartX, (int) fStartY, NULL);
  282.         LineTo(hdc, (int) fEndX, (int) fEndY);
  283.         }
  284.  
  285.     /* Draw endpoint marker */
  286.  
  287.     if (Get3DPoint(hcsysPatch, avecPoint[usNumPoints-1],
  288.                &fStartX, &fStartY)==GERR_OK)
  289.         DrawMarker(hdc, (int) fStartX, (int) fStartY, MT_BOX);
  290.  
  291.     /* We must restore the state of the DC before returning */
  292.  
  293.     SetBkMode(hdc, iOldMode);
  294.     SelectObject(hdc, hpenOld);
  295.     DeleteObject(hpen);
  296.     return;
  297.     }
  298.