home *** CD-ROM | disk | FTP | other *** search
/ The Houseplan Collection / HRCD2005.ISO / data1.cab / Zusatz / 3DS / DATA2.Z / CTorusDlg.cpp < prev    next >
C/C++ Source or Header  |  1998-05-28  |  14KB  |  491 lines

  1. // CTorusDlg.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "CTorus.h"
  6. #include "CTorusDlg.h"
  7. #include "ArConEventSink.h"
  8.  
  9. #include <AfxCtl.h>
  10. #include <math.h>
  11.  
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17.  
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CTorusDlg dialog
  20.  
  21. CTorusDlg::CTorusDlg(CWnd* pParent /*=NULL*/)
  22.     : CDialog(CTorusDlg::IDD, pParent)
  23. {
  24.     //{{AFX_DATA_INIT(CTorusDlg)
  25.         // NOTE: the ClassWizard will add member initialization here
  26.     //}}AFX_DATA_INIT
  27.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  28.   m_events = NULL;
  29.   m_pArCon = NULL;
  30. }
  31.  
  32. CTorusDlg::~CTorusDlg()
  33. {
  34.   if (m_events) {
  35.     AfxConnectionUnadvise(m_pArCon, DIID__ArConEvents, 
  36.         m_events->GetIDispatch(FALSE), FALSE, m_eventCookie);
  37.     m_events->ExternalRelease();
  38.     m_events = NULL;
  39.   }
  40.   if (m_pArCon)
  41.     m_pArCon->Release();
  42. }
  43.  
  44. void CTorusDlg::DoDataExchange(CDataExchange* pDX)
  45. {
  46.     CDialog::DoDataExchange(pDX);
  47.     //{{AFX_DATA_MAP(CTorusDlg)
  48.         // NOTE: the ClassWizard will add DDX and DDV calls here
  49.     //}}AFX_DATA_MAP
  50. }
  51.  
  52. BEGIN_MESSAGE_MAP(CTorusDlg, CDialog)
  53.     //{{AFX_MSG_MAP(CTorusDlg)
  54.     ON_WM_PAINT()
  55.     ON_WM_QUERYDRAGICON()
  56.     ON_BN_CLICKED(IDC_MIT, ErzeugeTorusMitLoechern)
  57.     ON_BN_CLICKED(IDC_OHNE, ErzeugeEinfachenTorus)
  58.     //}}AFX_MSG_MAP
  59. END_MESSAGE_MAP()
  60.  
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CTorusDlg message handlers
  63.  
  64. BOOL CTorusDlg::OnInitDialog()
  65. {
  66.     CDialog::OnInitDialog();
  67.  
  68.     SetIcon(m_hIcon, TRUE);            // Set big icon
  69.     SetIcon(m_hIcon, FALSE);        // Set small icon
  70.  
  71.   // Erzeuge ein ArCon Server Objekt
  72.     HRESULT res = CoCreateInstance(CLSID_ArCon, NULL, CLSCTX_LOCAL_SERVER, IID_IArCon, (void**)&m_pArCon);
  73.   if (FAILED(res)) {
  74.     TRACE("CoCreateInstance ist fehlgeschlagen: 0x%x\n", res);
  75.     PostQuitMessage(0);
  76.     return TRUE;
  77.   }
  78.   
  79.   // Starte die ArCon Verbindung
  80.   CString helpFileName = "";
  81.   VARIANT_BOOL ok;
  82.   m_pArCon->StartMe((long)m_hWnd, helpFileName.AllocSysString(), &ok);
  83.   
  84.   // Erzeuge die Senke fⁿr die ArCon-Ereignisse
  85.   m_events = new ArConEventSink();
  86.   if (!AfxConnectionAdvise(m_pArCon, DIID__ArConEvents, 
  87.       m_events->GetIDispatch(FALSE), FALSE, &m_eventCookie))
  88.   {
  89.     TRACE("Konnte die Event-Verbindung nicht herstellen!\n");
  90.   }
  91.  
  92.   // ArCon Modus ermitteln, evtl. neues Projekt erzeugen und in den Design-Modus schalten
  93.   long mode;
  94.   m_pArCon->get_Mode(&mode);
  95.   if (mode == AC_NoMode)
  96.     m_pArCon->CreateProject(NULL);
  97.     
  98.   if (mode != AC_ModeDesign)
  99.     m_pArCon->put_Mode(AC_ModeDesign);
  100.     return TRUE;  // return TRUE  unless you set the focus to a control
  101. }
  102.  
  103. // If you add a minimize button to your dialog, you will need the code below
  104. //  to draw the icon.  For MFC applications using the document/view model,
  105. //  this is automatically done for you by the framework.
  106.  
  107. void CTorusDlg::OnPaint() 
  108. {
  109.     if (IsIconic())
  110.     {
  111.         CPaintDC dc(this); // device context for painting
  112.  
  113.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  114.  
  115.         // Center icon in client rectangle
  116.         int cxIcon = GetSystemMetrics(SM_CXICON);
  117.         int cyIcon = GetSystemMetrics(SM_CYICON);
  118.         CRect rect;
  119.         GetClientRect(&rect);
  120.         int x = (rect.Width() - cxIcon + 1) / 2;
  121.         int y = (rect.Height() - cyIcon + 1) / 2;
  122.  
  123.         // Draw the icon
  124.         dc.DrawIcon(x, y, m_hIcon);
  125.     }
  126.     else
  127.     {
  128.         CDialog::OnPaint();
  129.     }
  130. }
  131.  
  132. HCURSOR CTorusDlg::OnQueryDragIcon()
  133. {
  134.     return (HCURSOR) m_hIcon;
  135. }
  136.  
  137. #define PI      3.1415926f
  138. #define TWOPI   (PI * 2.0f)
  139.     
  140. #define FACX    30
  141. #define FACY    16
  142. #define RRAT    0.8f
  143. #define FAK     0.2f
  144. #define FAK2    0.3f
  145.  
  146. #define TEXTURE_NAME   ">wand\\tapete\\kinder\\kaefer1.bmp"
  147.  
  148. struct Point {
  149.   float x, y, z, u, v;
  150. };
  151.  
  152. static Point ps[FACY][FACX];
  153.  
  154. void CTorusDlg::GeneratePoints()
  155. {
  156.   float cth, cah, dct, dst, st, ct, ct1, st1, dca, dsa, ca, sa;
  157.   int a, t;
  158.   CString msg("Punktkoordinaten berechnen");
  159.   m_pArCon->SetProgressbarSubTitle(msg.AllocSysString());
  160.   
  161.   dct = (float)cos(TWOPI / FACX);
  162.   dst = (float)sqrt(1.0f - (dct * dct));
  163.   dca = (float)cos(TWOPI / FACY);
  164.   dsa = (float)sqrt(1.0f - (dca * dca));
  165.   ca = RRAT;
  166.   sa = 0.0f;
  167.   for (a = 0; a < FACY; a++) {
  168.     m_pArCon->SetProgressbarValue(a * 10 / FACY);
  169.     ct = 1.0f + sa;
  170.     st = 0.0f;
  171.     ct1 = 1.0f;
  172.     st1 = 0.0f;
  173.     for (t = 0; t < FACX; t++) {
  174.       ps[a][t].u = t * 3.0f / FACX;
  175.       ps[a][t].v = a * 3.0f / FACY;
  176.       ps[a][t].x = ct;
  177.       ps[a][t].y = st;
  178.       ps[a][t].z = ca;
  179.       cth = ct;
  180.       ct = ct * dct - st * dst;
  181.       st = st * dct + cth * dst;
  182.       cth = ct1;
  183.       ct1 = ct1 * dct - st1 * dst;
  184.       st1 = st1 * dct + cth * dst;
  185.     }
  186.     cah = ca;
  187.     ca = ca * dca - sa * dsa;
  188.     sa = sa * dca + cah * dsa;
  189.   }
  190. }
  191.  
  192. typedef Point ConturType[4];
  193. static void PointsToVariant(ConturType &contur, VARIANT &v)
  194. {
  195.   // Das C-Array in ein OLE SafeArray konvertieren
  196.   SAFEARRAY * array;
  197.   SAFEARRAYBOUND bounds[2];
  198.   bounds[0].lLbound = 0;
  199.   bounds[0].cElements = 5;
  200.   bounds[1].lLbound = 0;
  201.   bounds[1].cElements = 4;
  202.   array = SafeArrayCreate(VT_R4, 2, bounds);
  203.   void * mem = NULL;
  204.   SafeArrayAccessData(array, &mem);
  205.   memcpy(mem, contur, sizeof contur);
  206.   SafeArrayUnaccessData(array);
  207.  
  208.   VariantInit(&v);
  209.   v.vt = VT_ARRAY|VT_R4;
  210.   v.parray = array;
  211. }
  212.  
  213. void CTorusDlg::GenPoly(IObjectConstructor* constr, int a, int t, int ap, int tp)
  214. {
  215.   // ▄ber gebe eine Polygoncontur als Array. Dazu die vier Punkt in ein C-Array kopieren
  216.   Point contur[4];
  217.   contur[0] = ps[a][t];
  218.   contur[1] = ps[ap][t];
  219.   contur[2] = ps[ap][tp];
  220.   contur[3] = ps[a][tp];
  221.  
  222.   VARIANT v;
  223.   PointsToVariant(contur, v);
  224.   constr->SetContur(4, v);
  225.   VariantClear(&v);
  226. }
  227.  
  228. void CTorusDlg::InstanceIntoWorld(IObjectConstructor* constr)
  229. {
  230.   // Eine Einheitsmatrix als "model to world" Transformation
  231.   float m2w[4][4];
  232.   memset(m2w, 0, sizeof m2w);
  233.   int i;
  234.   for (i = 0; i < 4; i++)
  235.     m2w[i][i] = 1.0f;
  236.  
  237.   IObject3D * inst = NULL;
  238.   constr->Create(NULL, 0, &inst);
  239.   if (!inst) {
  240.     AfxMessageBox("Konstruktion des Torus ist fehlgeschlagen!");
  241.     return;
  242.   }
  243.   inst->put_Flags(AC_3DFL_DBLCLICK | AC_3DFL_CONSTMODE | AC_3DFL_DESIGNMODE);
  244.  
  245.   // Matrix in ein SafeArray verpacken
  246.   VARIANT v;
  247.   VariantInit(&v);
  248.   v.vt = VT_ARRAY|VT_R4;
  249.   SAFEARRAYBOUND bounds[2];
  250.   bounds[0].lLbound = 0;
  251.   bounds[0].cElements = 4;
  252.   bounds[1].lLbound = 0;
  253.   bounds[1].cElements = 4;
  254.   v.parray = SafeArrayCreate(VT_R4, 2, bounds);
  255.   void *mem = NULL;
  256.   SafeArrayAccessData(v.parray, &mem);
  257.   memcpy(mem, m2w, sizeof m2w);
  258.   SafeArrayUnaccessData(v.parray);
  259.  
  260.   // Transformation setzen
  261.   VARIANT_BOOL ok;
  262.   inst->SetModelToWorldTransformation(v, &ok);
  263.  
  264.   // SafeArray freigeben
  265.   SafeArrayDestroy(v.parray);
  266.  
  267.   // und in die Welt einfⁿgen
  268.   inst->InsertIntoWorld(0, &ok);
  269. }
  270.  
  271. void CTorusDlg::ErzeugeTorusMitLoechern() 
  272. {
  273.   CString textureName(TEXTURE_NAME);
  274.   DWORD start, end;
  275.  
  276.   start = GetTickCount();
  277.   IObjectConstructor * constr = NULL;
  278.   m_pArCon->NewObjectConstructor(0, TWOPI / 360 * 105, &constr);
  279.  
  280.   IMaterial * mat = NULL;
  281.   m_pArCon->NewMaterial(&mat);
  282.   mat->put_AmbientCoefficient(0.2f);
  283.   mat->put_DiffuseCoefficient(0.4f);
  284.   mat->put_SpecularCoefficient(0.4f);
  285.   mat->put_DiffuseColor(RGB(255, 255, 255));
  286.   mat->put_SpecularColor(RGB(255, 255, 255));
  287.   mat->put_Transparent(0);
  288.   mat->put_Flags(ACMATFL_ISTEXTURED | ACMATFL_TWOSIDED);
  289.  
  290.   CString msg("Erzeuge einen Torus mit Lochpolygonen");
  291.   m_pArCon->StartProgressbar(msg.AllocSysString(), 0);
  292.  
  293.   GeneratePoints();
  294.  
  295.   int a, t, ap, tp;
  296.  
  297.   msg = "FlΣchen erzeugen";
  298.   m_pArCon->SetProgressbarSubTitle(msg.AllocSysString());
  299.  
  300.   for (a = 0; a < FACY; a++) {
  301.       m_pArCon->SetProgressbarValue(10 + a * 90 / FACY);
  302.       ap = a + 1;
  303.       if (ap >= FACY) ap = 0;
  304.       for (t = 0; t < FACX; t++) {
  305.           tp = t + 1;
  306.           if (tp >= FACX) tp = 0;
  307.           GenHolePoly(constr, a, t, ap, tp);
  308.           constr->AddPolygonWithHoles(0, mat, textureName.AllocSysString());
  309.       }
  310.   }
  311.   m_pArCon->SetProgressbarValue(100);
  312.   msg = "Nachbarschaften & Normalen berechnen";
  313.   m_pArCon->SetProgressbarSubTitle(msg.AllocSysString());
  314.   msg = "Der Torus";
  315.   VARIANT_BOOL ok;
  316.   constr->Finish(msg.AllocSysString(), 0, ACO_DURATION_CACHEABLE, &ok);
  317.   m_pArCon->StopProgressbar();
  318.  
  319.   // Konstruktion ist abgeschlossen, in die Welt damit
  320.   InstanceIntoWorld(constr);
  321.  
  322.   // OLE Objekte wieder freigeben
  323.   mat->Release();
  324.   constr->Release();
  325.  
  326.   end = GetTickCount();
  327.   msg.Format("Zeit: %lu ms", end - start);
  328.   m_pArCon->SetStatusText(msg.AllocSysString());
  329. }
  330.  
  331. void CTorusDlg::ErzeugeEinfachenTorus() 
  332. {
  333.   DWORD start, end;
  334.  
  335.   start = GetTickCount();
  336.   CString textureName(TEXTURE_NAME);
  337.  
  338.   IObjectConstructor * constr = NULL;
  339.   m_pArCon->NewObjectConstructor(0, TWOPI / 360 * 105, &constr);
  340.  
  341.   IMaterial * mat = NULL;
  342.   m_pArCon->NewMaterial(&mat);
  343.   mat->put_AmbientCoefficient(0.2f);
  344.   mat->put_DiffuseCoefficient(0.4f);
  345.   mat->put_SpecularCoefficient(0.4f);
  346.   mat->put_DiffuseColor(RGB(255, 255, 255));
  347.   mat->put_SpecularColor(RGB(255, 255, 255));
  348.   mat->put_Transparent(0);
  349.   mat->put_Flags(ACMATFL_ISTEXTURED);
  350.  
  351.   CString msg("Erzeuge einen einfachen Torus");
  352.   m_pArCon->StartProgressbar(msg.AllocSysString(), 0);
  353.  
  354.   GeneratePoints();
  355.  
  356.   int a, t, ap, tp;
  357.  
  358.   msg = "FlΣchen erzeugen";
  359.   m_pArCon->SetProgressbarSubTitle(msg.AllocSysString());
  360.  
  361.   for (a = 0; a < FACY; a++) {
  362.       m_pArCon->SetProgressbarValue(10 + a * 90 / FACY);
  363.       ap = a + 1;
  364.       if (ap >= FACY) ap = 0;
  365.       for (t = 0; t < FACX; t++) {
  366.           tp = t + 1;
  367.           if (tp >= FACX) tp = 0;
  368.           GenPoly(constr, a, t, ap, tp);
  369.           constr->AddPolygonWithHoles(0, mat, textureName.AllocSysString());
  370.       }
  371.   }
  372.   m_pArCon->SetProgressbarValue(100);
  373.   msg = "Nachbarschaften & Normalen berechnen";
  374.   m_pArCon->SetProgressbarSubTitle(msg.AllocSysString());
  375.   msg = "Der Torus";
  376.   VARIANT_BOOL ok;
  377.   constr->Finish(msg.AllocSysString(), 0, ACO_DURATION_CACHEABLE, &ok);
  378.   m_pArCon->StopProgressbar();
  379.  
  380.   // Konstruktion ist abgeschlossen, in die Welt damit
  381.   InstanceIntoWorld(constr);
  382.  
  383.   // OLE Objekte wieder freigeben
  384.   mat->Release();
  385.   constr->Release();
  386.  
  387.   end = GetTickCount();
  388.   msg.Format("Zeit: %lu ms", end - start);
  389.   m_pArCon->SetStatusText(msg.AllocSysString());
  390. }
  391.  
  392. void CTorusDlg::GenHolePoly(IObjectConstructor* constr, int a, int t, int ap, int tp)
  393. {
  394.   VARIANT v;
  395.   
  396.   // ▄ber gebe eine Polygoncontur als Array. Dazu die vier Punkt in ein C-Array kopieren
  397.   Point contur[4];
  398.   contur[0] = ps[a][t];
  399.   contur[1] = ps[ap][t];
  400.   contur[2] = ps[ap][tp];
  401.   contur[3] = ps[a][tp];
  402.   
  403.   PointsToVariant(contur, v);
  404.   constr->SetHoleContur(0, 4, v);
  405.   VariantClear(&v);
  406.  
  407.   Point loch1[4];
  408.   Point loch2[4];
  409.   float d;
  410.   Point hp, hp2;
  411.   d = (ps[ap][t].x - ps[a][t].x) + (ps[a][tp].x - ps[a][t].x);
  412.   hp.x = ps[a][t].x + d * FAK;
  413.   hp2.x = ps[a][t].x + d * FAK2;
  414.   d = (ps[ap][t].y - ps[a][t].y) + (ps[a][tp].y - ps[a][t].y);
  415.   hp.y = ps[a][t].y + d * FAK;
  416.   hp2.y = ps[a][t].y + d * FAK2;
  417.   d = (ps[ap][t].z - ps[a][t].z) + (ps[a][tp].z - ps[a][t].z);
  418.   hp.z = ps[a][t].z + d * FAK;
  419.   hp2.z = ps[a][t].z + d * FAK2;
  420.   d = (ps[ap][t].u - ps[a][t].u) + (ps[a][tp].u - ps[a][t].u);
  421.   hp.u = ps[a][t].u + d * FAK;
  422.   hp2.u = ps[a][t].u + d * FAK2;
  423.   d = (ps[ap][t].v - ps[a][t].v) + (ps[a][tp].v - ps[a][t].v);
  424.   hp.v = ps[a][t].v + d * FAK;
  425.   hp2.v = ps[a][t].v + d * FAK2;
  426.   loch1[0] = hp;
  427.   loch1[1] = hp2;
  428.  
  429.   d = (ps[ap][tp].x - ps[ap][t].x) + (ps[a][t].x - ps[ap][t].x);
  430.   hp.x = ps[ap][t].x + d * FAK;
  431.   hp2.x = ps[ap][t].x + d * FAK2;
  432.   d = (ps[ap][tp].y - ps[ap][t].y) + (ps[a][t].y - ps[ap][t].y);
  433.   hp.y = ps[ap][t].y + d * FAK;
  434.   hp2.y = ps[ap][t].y + d * FAK2;
  435.   d = (ps[ap][tp].z - ps[ap][t].z) + (ps[a][t].z - ps[ap][t].z);
  436.   hp.z = ps[ap][t].z + d * FAK;
  437.   hp2.z = ps[ap][t].z + d * FAK2;
  438.   d = (ps[ap][tp].u - ps[ap][t].u) + (ps[a][t].u - ps[ap][t].u);
  439.   hp.u = ps[ap][t].u + d * FAK;
  440.   hp2.u = ps[ap][t].u + d * FAK2;
  441.   d = (ps[ap][tp].v - ps[ap][t].v) + (ps[a][t].v - ps[ap][t].v);
  442.   hp.v = ps[ap][t].v + d * FAK;
  443.   hp2.v = ps[ap][t].v + d * FAK2;
  444.   loch2[0] = hp;
  445.   loch2[3] = hp2;
  446.  
  447.   d = (ps[a][tp].x - ps[ap][tp].x) + (ps[ap][t].x - ps[ap][tp].x);
  448.   hp.x = ps[ap][tp].x + d * FAK;
  449.   hp2.x = ps[ap][tp].x + d * FAK2;
  450.   d = (ps[a][tp].y - ps[ap][tp].y) + (ps[ap][t].y - ps[ap][tp].y);
  451.   hp.y = ps[ap][tp].y + d * FAK;
  452.   hp2.y = ps[ap][tp].y + d * FAK2;
  453.   d = (ps[a][tp].z - ps[ap][tp].z) + (ps[ap][t].z - ps[ap][tp].z);
  454.   hp.z = ps[ap][tp].z + d * FAK;
  455.   hp2.z = ps[ap][tp].z + d * FAK2;
  456.   d = (ps[a][tp].u - ps[ap][tp].u) + (ps[ap][t].u - ps[ap][tp].u);
  457.   hp.u = ps[ap][tp].u + d * FAK;
  458.   hp2.u = ps[ap][tp].u + d * FAK2;
  459.   d = (ps[a][tp].v - ps[ap][tp].v) + (ps[ap][t].v - ps[ap][tp].v);
  460.   hp.v = ps[ap][tp].v + d * FAK;
  461.   hp2.v = ps[ap][tp].v + d * FAK2;
  462.   loch2[1] = hp;
  463.   loch2[2] = hp2;
  464.  
  465.   d = (ps[a][t].x - ps[a][tp].x) + (ps[ap][tp].x - ps[a][tp].x);
  466.   hp.x = ps[a][tp].x + d * FAK;
  467.   hp2.x = ps[a][tp].x + d * FAK2;
  468.   d = (ps[a][t].y - ps[a][tp].y) + (ps[ap][tp].y - ps[a][tp].y);
  469.   hp.y = ps[a][tp].y + d * FAK;
  470.   hp2.y = ps[a][tp].y + d * FAK2;
  471.   d = (ps[a][t].z - ps[a][tp].z) + (ps[ap][tp].z - ps[a][tp].z);
  472.   hp.z = ps[a][tp].z + d * FAK;
  473.   hp2.z = ps[a][tp].z + d * FAK2;
  474.   d = (ps[a][t].u - ps[a][tp].u) + (ps[ap][tp].u - ps[a][tp].u);
  475.   hp.u = ps[a][tp].u + d * FAK;
  476.   hp2.u = ps[a][tp].u + d * FAK2;
  477.   d = (ps[a][t].v - ps[a][tp].v) + (ps[ap][tp].v - ps[a][tp].v);
  478.   hp.v = ps[a][tp].v + d * FAK;
  479.   hp2.v = ps[a][tp].v + d * FAK2;
  480.   loch1[3] = hp;
  481.   loch1[2] = hp2;
  482.  
  483.   PointsToVariant(loch1, v);
  484.   constr->SetHoleContur(1, 4, v);
  485.   VariantClear(&v);
  486.  
  487.   PointsToVariant(loch2, v);
  488.   constr->SetHoleContur(2, 4, v);
  489.   VariantClear(&v);
  490. }
  491.