#pragma once #ifndef __AFXWIN_H__ #error "include 'stdafx.h' before including this file for PCH" #endif #include "resource.h" // main symbols #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static const double PI = 3.1415926; const int SegmentNum = 40; const double PRECISION = 0.00001; int frameId = 100; // CGraphicsDrawApp // See GraphicsDraw.cpp for the implementation of this class // class CGraphicsDrawApp : public CWinApp { public: CGraphicsDrawApp(); // Overrides public: virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP() }; uiCmdAccessState GraphicsDrawAccessFn(uiCmdAccessMode access_mode) { return ACCESS_AVAILABLE; } // // 複製向量 // void CopyVector(ProVector from, ProVector to) { for (int i = 0; i < 3; ++i) { to[i] = from[i]; } } // // 兩向量的叉積 // void ProductVectors(ProVector vec1, ProVector vec2, ProVector productVec) { productVec[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1]; productVec[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2]; productVec[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0]; } // // 向量單位化 // void NormalizeVector(ProVector originVec, ProVector normlizedVec) { double len = sqrt(pow(originVec[0], 2) + pow(originVec[1], 2) + pow(originVec[2], 2)); for (int i = 0; i < 3; ++i) { normlizedVec[i] = originVec[i] / len; } } // // 根據給定的Z向量構造一個單位化坐標矩陣 // void ContructorMatrixGivedZVector(ProVector zVecOrigin, ProPoint3d origin, ProMatrix csysMatrix) { ProVector xVec; ProVector yVec; ProVector zVec; // 將Z向量保存 CopyVector(zVecOrigin, zVec); // 根據兩個非0向量的點積為0,則兩個向量相互垂直的原理進行拼湊Y向量 yVec[0] = 0.0; if (abs(zVec[2]) < PRECISION) { // 如果Z向量的第3個分量為0 yVec[1] = 0.0; yVec[2] = 1.0; } else { yVec[1] = 1.0; yVec[2] = -1 * zVec[1] / zVec[2]; } // 由y X z得到x向量 ProductVectors(yVec, zVec, xVec); // 矩陣初始化 for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { csysMatrix[i][j] = 0.0; } } csysMatrix[3][3] = 1.0; // 給矩陣賦值 // X NormalizeVector(xVec, xVec); for (int i = 0; i < 3; ++i) { csysMatrix[0][i] = xVec[i]; } // Y NormalizeVector(yVec, yVec); for (int j = 0; j < 3; ++j) { csysMatrix[1][j] = yVec[j]; } // Z NormalizeVector(zVec, zVec); for (int k = 0; k < 3; ++k) { csysMatrix[2][k] = zVec[k]; } // translation for (int n = 0; n < 3; ++n) { csysMatrix[3][n] = origin[n]; } } ProError DrawCircle(ProPoint3d center, double radius, ProVector drawDirect, ProColortype *color) { ProError status = PRO_TK_NO_ERROR; ProLinestyle oldLineStyle; ProColortype oldColor; // 設定新的線條顏色和線條類型 status = ProLinestyleSet(PRO_LINESTYLE_SOLID, &oldLineStyle); status = ProGraphicsColorSet(*color, &oldColor); // 將圓弧分成N段,然後用直線連接這些等分點,得到圓的近似圖 ProPoint3d drawPos; double stepAngle = 2 * PI / SegmentNum; double A = drawDirect[0]; double B = drawDirect[1]; double C = drawDirect[2]; // 想法,將GRAPHICS的坐標轉換為當前模型的坐標 // GRAPHICS對應的坐標系為((1,0,0),(0,1,0),(0,0,1)) // 只將GRAPHICS對應的Z方向轉換成當前模型的Z方向就可以達到效果了。 // 方法一 // 以drawDirect為Z向構造坐標系 ProMatrix virtualMatrix; ContructorMatrixGivedZVector(drawDirect, center, virtualMatrix); for (int i = 0; i <= SegmentNum; ++i) { double cosa = cos(stepAngle * i); double sina = sin(stepAngle * i); drawPos[0] = radius * cosa; drawPos[1] = radius * sina; drawPos[2] = 0.0; ProPoint3d realPos; ProPntTrfEval(drawPos, virtualMatrix, realPos); if (i == 0) { // 設置起始點 ProGraphicsPenPosition(realPos); } ProGraphicsLineDraw(realPos); } 方法二 C = 0的情況 //if (abs(C) < PRECISION) //{ // double vecLen = sqrt( pow(A, 2) + pow(B, 2)); // double cosa = -1 * B / vecLen; // double sina = A / vecLen; // for (int i = 0; i <= SegmentNum; ++i) // { // double cosb = cos(stepAngle * i); // double sinb = sin(stepAngle * i); // drawPos[0] = center[0] + radius * cosb * cosa; // drawPos[1] = center[1] + radius * cosb * sina; // drawPos[2] = center[2] + radius * sinb; // if (i == 0) // { // // 設置起始點 // ProGraphicsPenPosition(drawPos); // } // ProGraphicsLineDraw(drawPos); // } //} //else //{ // for (int i = 0; i <= SegmentNum; ++i) // { // double cosa = cos(stepAngle * i); // double sina = sin(stepAngle * i); // double Acosa_Bsina = A * cosa + B * sina; // double down = sqrt( pow(C, 2) + pow(Acosa_Bsina, 2) ); // double cosb = C / down; // double sinb = -1 * Acosa_Bsina / down; // drawPos[0] = center[0] + radius * cosa * cosb; // drawPos[1] = center[1] + radius * sina * cosb; // drawPos[2] = center[2] + radius * sinb; // if (i == 0) // { // // 設置起始點 // ProGraphicsPenPosition(drawPos); // } // ProGraphicsLineDraw(drawPos); // } //} // 恢復舊的線條顏色和線條類型 status = ProLinestyleSet(oldLineStyle, &oldLineStyle); status = ProGraphicsColorSet(oldColor, &oldColor); return PRO_TK_NO_ERROR; } ProError DrawCircleInModel() { // 1. 選擇平面 ProError status; ProSelection *userSels; int selCount = 0; status = ProSelect("datum,surface", 1, NULL, NULL, NULL, NULL, &userSels, &selCount); if (status != PRO_TK_NO_ERROR || selCount < 1) { return PRO_TK_USER_ABORT; } // 2. 獲取所選平面的位置 ProPoint3d origin; status = ProSelectionPoint3dGet(userSels[0], origin); if (status != PRO_TK_NO_ERROR) { return PRO_TK_USER_ABORT; } // 3. 獲取所選平面的法向 ProModelitem selItem; ProGeomitemdata *surfData; ProVector direction; status = ProSelectionModelitemGet(userSels[0], &selItem); status = ProGeomitemdataGet(&selItem, &surfData); CopyVector(surfData->data.p_surface_data->srf_shape.plane.e3, direction); status = ProGeomitemdataFree(&surfData); // 4. 如果當前模型是組立檔,須將方向轉換成組立中的方向 ProMdl currMdl; ProMdlType mdlType; status = ProMdlCurrentGet(&currMdl); status = ProMdlTypeGet(currMdl, &mdlType); if (mdlType == PRO_MDL_ASSEMBLY) { ProAsmcomppath userSelPath; ProMatrix transformMatrix; status = ProSelectionAsmcomppathGet(userSels[0], &userSelPath); status = ProAsmcomppathTrfGet(&userSelPath, PRO_B_TRUE, transformMatrix); ProVector tempVec; status = ProVectorTrfEval(direction, transformMatrix, tempVec); CopyVector(tempVec, direction); ProPoint3d tempPos; status = ProPntTrfEval(origin, transformMatrix, tempPos); CopyVector(tempPos, origin); } // 5. 在用戶點選的位置上繪制一個圓 double radius = 3.0; ProColortype drawColor = PRO_COLOR_HIGHLITE; status = ProDisplist3dCreate(frameId++, (ProDisplistCallback)DrawCircle, origin, radius, direction, &drawColor); return PRO_TK_NO_ERROR; } // // 圖形繪製 // ProError GraphicsDrawAct() { ProError status; ProMdl currMdl; status = ProMdlCurrentGet(&currMdl); if (status != PRO_TK_NO_ERROR || currMdl == NULL) { AfxMessageBox("當前窗口沒有檔案!"); return status; } // 繪制圓 DrawCircleInModel(); return PRO_TK_NO_ERROR; } /// // EMX-application is started by Pro/ENGINEER-'protk.dat'file extern "C" int user_initialize(int argc, char* argv[], char* version, char* build, wchar_t errbuf[80]) { ProError status; // // 此段用二創建檔案目錄樹 ProName msgFile; ProStringToWstring(msgFile, "GraphicsDraw.txt"); uiCmdCmdId graphicsDrawCmdId; status = ProCmdActionAdd ("GraphicsDraw",(uiCmdCmdActFn)GraphicsDrawAct,uiProeImmediate,GraphicsDrawAccessFn,PRO_B_TRUE,PRO_B_TRUE,&graphicsDrawCmdId); status = ProMenubarmenuPushbuttonAdd ("Help", "GraphicsDraw", "GraphicsDraw", "GraphicsDraw_Help", NULL, PRO_B_TRUE, graphicsDrawCmdId, msgFile); return 0; } /// // Terminate EMX-application extern "C" void user_terminate() { return; }
graphics
最新推荐文章于 2023-09-05 15:20:18 发布