![]() |
How to get parameters of curve?
![]() APITest_EXE.zip Updated: 5/7/2004 Size: 0.019 Curve::GetBCurveParams is a difficult API to use because you must deal with Variants. This sample code is an MFC-based dialog application that shows how to use Curve::GetBCurveParams. It shows how to correctly deal with Variants and access the data contained in a Variant. The equivalent VBA code is provided for reference and contrast. |
回复: How to get parameters of curve?
// APITest_EXEDlg.cpp : implementation file
// #include "stdafx.h" #include "APITest_EXE.h" #include "APITest_EXEDlg.h" #include "smartvars.h" //Header for SolidWorks' SAFEARRAY template classes #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAPITest_EXEDlg dialog CAPITest_EXEDlg::CAPITest_EXEDlg(CWnd* pParent /*=NULL*/) : CDialog(CAPITest_EXEDlg::IDD, pParent) { //{{AFX_DATA_INIT(CAPITest_EXEDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CAPITest_EXEDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAPITest_EXEDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAPITest_EXEDlg, CDialog) //{{AFX_MSG_MAP(CAPITest_EXEDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BTN_CONNECT, OnBtnConnect) ON_BN_CLICKED(IDC_BTN_DATE, OnBtnDate) ON_BN_CLICKED(IDC_BTN_START, OnBtnStart) ON_BN_CLICKED(IDC_BTN_API_TEST, OnBtnAPI_Test) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAPITest_EXEDlg message handlers BOOL CAPITest_EXEDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here return TRUE; // return TRUE unless you set the focus to a control } void CAPITest_EXEDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID + 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CAPITest_EXEDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CAPITest_EXEDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } //------------------------------------------------------------------------ void CAPITest_EXEDlg::OnBtnConnect() { // connects to an already running instance of SW // will assert if SW has not been started CComPtr <IUnknown> pUnk; CComQIPtr <IDispatch> pSldWorks; CLSID clsid; HRESULT hr = S_OK; hr = CLSIDFromProgID(OLESTR("SldWorks.Application"), &clsid); ASSERT(S_OK == hr); hr = GetActiveObject(clsid, NULL, &pUnk); ASSERT(S_OK == hr); ASSERT(pUnk); pSldWorks = pUnk; ASSERT(pSldWorks); // Detach since m_pSldWorks will Release when it goes out of scope m_pSldWorks.AttachDispatch(pSldWorks.Detach()); } //------------------------------------------------------------------------ void CAPITest_EXEDlg::OnBtnStart() { // connects to an already running instance of SW // or will start SW if not already running m_pSldWorks.CreateDispatch("SldWorks.Application"); ASSERT(m_pSldWorks.m_lpDispatch); } //------------------------------------------------------------------------ void CAPITest_EXEDlg::OnBtnDate() { ASSERT(m_pSldWorks.m_lpDispatch); long nDateCode = -1; CComBSTR sRevNum; CString sMsg; sRevNum = m_pSldWorks.RevisionNumber(); nDateCode = m_pSldWorks.DateCode(); // note upper case S format specifier since CComBSTR is Unicode sMsg.Format("Revision Number = %ld\nDate Code = %S", nDateCode, sRevNum); AfxMessageBox(sMsg); } //------------------------------------------------------------------------ void CAPITest_EXEDlg::OnBtnAPI_Test() { union Ints { double value; int intval[2]; }; HRESULT hr = S_OK; IModeler pModeler; IModelDoc2 pModel; ISelectionMgr pSelMgr; IEdge pEdge; ICurve pCurve; BOOL bRet = FALSE; VARIANT vBCurveParam; long lUBound = -1; Ints iDim_Order; Ints iCtrlPts_Periodicity; long nNumKnots = -1; CString sTempStr; int i = -1; VariantInit(&vBCurveParam); vBCurveParam.vt = VT_ARRAY | VT_R8; pModeler = m_pSldWorks.GetModeler(); ASSERT(pModeler.m_lpDispatch); pModel = m_pSldWorks.GetActiveDoc(); ASSERT(pModel.m_lpDispatch); pSelMgr = pModel.GetSelectionManager(); ASSERT(pSelMgr.m_lpDispatch); pEdge = pSelMgr.GetSelectedObject5(1); ASSERT(pEdge.m_lpDispatch); pCurve = pEdge.GetCurve(); ASSERT(pCurve.m_lpDispatch); vBCurveParam = pCurve.GetBCurveParams(TRUE); ASSERT(VT_EMPTY != vBCurveParam.vt); ASSERT(VT_ARRAY | VT_R8 == vBCurveParam.vt); hr = SafeArrayGetUBound(vBCurveParam.parray, 1, &lUBound); ASSERT(S_OK == hr); ASSERT(lUBound > 0); SafeDoubleArray sdaData(lUBound); sdaData = vBCurveParam; // dump modeller settings OutputDebugString("Modeller Settings:\n"); sTempStr.Format(" BSCurveOutputTol = %f\n", pModeler.GetToleranceValue(swBSCurveOutputTol)); OutputDebugString(sTempStr); sTempStr.Format(" BSCurveNonRationalOutputTol = %f\n", pModeler.GetToleranceValue(swBSCurveNonRationalOutputTol)); OutputDebugString(sTempStr); sTempStr.Format(" UVCurveOutputTol = %f\n", pModeler.GetToleranceValue(swUVCurveOutputTol)); OutputDebugString(sTempStr); sTempStr.Format(" SurfChordTessellationTol = %f\n", pModeler.GetToleranceValue(swSurfChordTessellationTol)); OutputDebugString(sTempStr); sTempStr.Format(" SurfAngularTessellationTol = %f\n", pModeler.GetToleranceValue(swSurfAngularTessellationTol)); OutputDebugString(sTempStr); sTempStr.Format(" CurveChordTessellationTol = %f\n", pModeler.GetToleranceValue(swCurveChordTessellationTol)); OutputDebugString(sTempStr); OutputDebugString("\n"); iDim_Order.value = sdaData[0]; iCtrlPts_Periodicity.value = sdaData[1]; nNumKnots = iDim_Order.intval[1] + iCtrlPts_Periodicity.intval[0]; sTempStr.Format("File = %s\n", pModel.GetPathName()); OutputDebugString(sTempStr); sTempStr.Format(" Dimension = %d\n", iDim_Order.intval[0]); OutputDebugString(sTempStr); sTempStr.Format(" Order = %d\n", iDim_Order.intval[1]); OutputDebugString(sTempStr); sTempStr.Format(" Num Ctrl Pts = %d\n", iCtrlPts_Periodicity.intval[0]); OutputDebugString(sTempStr); sTempStr.Format(" Periodicity = %d\n", iCtrlPts_Periodicity.intval[1]); OutputDebugString(sTempStr); sTempStr.Format(" Num Knots = %d\n", nNumKnots); OutputDebugString(sTempStr); OutputDebugString("\n"); for (i = 0; i < nNumKnots; i++) { // knot weights should be increasing monotonically sTempStr.Format(" Knot(%d) = %f\n", i, sdaData[2 + i]); OutputDebugString(sTempStr); } if (3 == iDim_Order.intval[0]) { for (i = 2 + nNumKnots; i < lUBound; i = i + 3) { sTempStr.Format(" Ctrl(%d) = (%f, %f, %f) mm\n", (i - 2 - nNumKnots) / 3, sdaData[i + 0] * 1000.0, sdaData[i + 1] * 1000.0, sdaData[i + 2] * 1000.0); OutputDebugString(sTempStr); } } else { // WARNING - untested code! for (i = 2 + nNumKnots; i < lUBound; i = i + 4) { sTempStr.Format(" Ctrl(%d) = (%f, %f, %f) mm [%f]\n", (i - 2 - nNumKnots) / 4, sdaData[i + 0] * 1000.0, sdaData[i + 1] * 1000.0, sdaData[i + 2] * 1000.0, sdaData[i + 3]); OutputDebugString(sTempStr); } } } |
所有的时间均为北京时间。 现在的时间是 11:32 PM. |