graphics

来源:互联网 发布:关晓彤人品知乎 编辑:程序博客网 时间:2024/04/30 04:30
#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();// Overridespublic: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個分量為0yVec[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;// 給矩陣賦值// XNormalizeVector(xVec, xVec);for (int i = 0; i < 3; ++i){csysMatrix[0][i] = xVec[i];}// YNormalizeVector(yVec, yVec);for (int j = 0; j < 3; ++j){csysMatrix[1][j] = yVec[j];}// ZNormalizeVector(zVec, zVec);for (int k = 0; k < 3; ++k){csysMatrix[2][k] = zVec[k];}// translationfor (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;ProLinestyleoldLineStyle; ProColortypeoldColor; // 設定新的線條顏色和線條類型 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'fileextern "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-applicationextern "C" void user_terminate(){return;}