3DS MAX9 导出插件 pMesh->GetNormal 无法获得正确的法线??

博客强调传入参数时,必须使用法线索引,而非顶点索引,这是信息技术中关于参数传入的关键要点。

 因为传入参数必须写法线索引,而不是顶点索引!

我正在学习天工CAD C++二次开发,下面的代码该如何实现参数化设计的拉伸效果? namespace pt = TGPart; namespace fw = TGFramework; namespace fwp = TGFrameworkSupport; // 获取Application fw::Application* application = TGAddinTemplate1App::GetApplication(); // 获取PartDocumentPtr pt::PartDocumentPtr partDoc = application->Documents->Add("SolidEdge.PartDocument"); // 新建草图 pt::SketchsPtr pSketchs = partDoc->Sketches; pt::SketchPtr pSketch = pSketchs->Add(); // 参考平面 pt::RefPlanesPtr pRefPlanes = partDoc->RefPlanes; pt::RefPlanePtr pRefPlane = pRefPlanes->Item(1);//xoy // 获取轮廓 pt::ProfilePtr pProfile = pSketch->GetProfiles()->Add(pRefPlane); // 添加圆,圆心(0,0),半径0.2 fwp::Circles2dPtr pCircle2d = pProfile->Circles2d; pCircle2d->AddByCenterRadius(0, 0, 0.2); auto profileStatus = pProfile->End(TGPart::ProfileValidationType::igProfileClosed); // Create the extended protrusion. ATL::CComSafeArray<IDispatch*> aProfiles(1); aProfiles[0] = pProfile; //// 单侧拉伸,igRight右侧(即法向侧),igLeft 左侧(法向反方向侧) // 基于圆的轮廓做拉伸,拉伸方向为右侧,长度为0.2 pt::ModelPtr model = partDoc->Models->AddFiniteExtrudedProtrusion(1, aProfiles.GetSafeArrayPtr(), TGPart::FeaturePropertyConstants::igRight, 0.2); // 对称拉伸0.2,两边各拉伸0.1 pt::ModelPtr pModelScd = partDoc->Models->AddFiniteExtrudedProtrusion(1, aProfiles.GetSafeArrayPtr(), TGPart::FeaturePropertyConstants::igSymmetric, 0.2); // 非对称拉伸 法向侧拉伸0.3 法向侧反方向拉伸0.5 pt::RefPlanePtr pTopPlane = pRefPlanes->AddParallelByDistance(pRefPlane, 0.3, pt::igNormalSide); pt::RefPlanePtr pBottomPlane = pRefPlanes->AddParallelByDistance(pRefPlane, -0.5, pt::igNormalSide); _variant_t argTop(pTopPlane.GetInterfacePtr()); _variant_t argBot(pBottomPlane.GetInterfacePtr()); pt::ModelPtr pModelTrd = partDoc->Models->AddFiniteExtrudedProtrusion(1, aProfiles.GetSafeArrayPtr(), TGPart::FeaturePropertyConstants::igRight, 0, vtMissing, vtMissing, argTop, argBot);
07-12
void qSlicerArielImplantPlanModuleWidgetPrivate::updateStemCutPlane() { Q_Q(qSlicerArielImplantPlanModuleWidget); if (curStemInfo.brand.empty() || curStemInfo.type.empty()) return; vtkNew<vtkMatrix4x4> stemPoseMatrix; stemPoseNode->GetMatrixTransformToParent(stemPoseMatrix); // 活动评估下 if (currentMode == qSlicerArielImplantPlanModuleWidgetPrivate::CollisionDetect) if (::isPoseValid(this->stemPoseMatrixRaw)) { stemPoseMatrix->DeepCopy(this->stemPoseMatrixRaw); } vtkNew<vtkMatrix4x4> identity; if (areMatricesEqual(stemPoseMatrix, identity)) return; double stemInfo[4]; stemInfo[0] = curStemInfo.neckLength; stemInfo[1] = curStemInfo.horizontalOffset; stemInfo[2] = curStemInfo.neckShaftAngle; stemInfo[3] = curStemInfo.cutAngle; // transform double origin[3], normal[3]; currentModuleLogic->getCutFemurPlaneOriginAndNormal(stemInfo, origin, normal); vtkNew<vtkPlane> stemCutPlane; currentModuleLogic->getTransformedPlane(origin, normal, stemPoseMatrix, stemCutPlane); stemCutPlane->GetOrigin(origin); stemCutPlane->GetNormal(normal); // Plane if (stemCutPlane && this->stemCutPlane) { std::cout << __FUNCTION__ << std::endl; //股骨柄切面高度 auto stemHeight = q->calculateCutFemurHeight(origin, normal); std::cout << u8"股骨柄切面高度:height=" << stemHeight << std::endl; //当前截骨面高度 auto distance = q->calculateCutFemurHeight(); std::cout << u8"矫正前截骨面高度:distance=" << distance << std::endl; //偏移=实际-理论 std::cout << u8"截骨偏移: cutPlaneOffset=" << cutPlaneOffset << std::endl; //高度or法向量 不相等:调节 if ((stemHeight + cutPlaneOffset) != distance) { //重置PlaneNode double newOrigin[3] = {0}; double newNormal[3] = {0}; memcpy(newNormal, normal, sizeof(double) * 3); if (cutPlaneOffset == 0.0) memcpy(newOrigin, origin, sizeof(double) * 3); else currentModuleLogic->calculatePositionOfCutPlaneByOffset(origin, normal, cutPlaneOffset, newOrigin); this->stemCutPlane->setPlaneNodeByPlaneType( PlaneType( {newNormal[0], newNormal[1], newNormal[2], newOrigin[0], newOrigin[1], newOrigin[2]}), this->cutPlaneRadius); //重置高度 q->resetCutFemurHeightSpinBoxValue(); //重新获取offset distance = q->calculateCutFemurHeight(); std::cout << u8"矫正后截骨面高度:distance=" << distance << ", stemHeight=" << stemHeight << std::endl; } } }
02-07
//将声明放入一个共同的头文件 #include"declares.h" //定义向量类 classCVector3 { public: CVector3();//构造函数 CVector3(floatx, floaty, floatz); voidSet(floatx, floaty, floatz); voidNormalize(); floatLength(); void operator += (CVector3&v);//运算符重载 CVector3 operator - (); friendCVector3 operator + (constCVector3&v1, constCVector3&v2); friendCVector3CrossProduct(constCVector3&v1, constCVector3&v2); union { }; }; struct { floatm_x, m_y, m_z; }; struct { floatr, g, b; }; //部分成员函数的实现 #include"declares.h" CVector3::CVector3(floatx, floaty, floatz) { m_x = x; m_y = y; m_z = z; } voidCVector3::Normalize() { floatl = 1.0f / Length(); m_x *= l; m_y *= l; m_z *= l; } CVector3 operator + (constCVector3&v1, constCVector3&v2) { returnCVector3(v1.m_x + v2.m_x, v1.m_y + v2.m_y, v1.m_z + v2.m_z); } CVector3CrossProduct(constCVector3&v1, constCVector3&v2)//叉积 { returnCVector3(v1*v2); } //定义光线类 classCRay { public: voidSetOrigin(CVector3&origin); //设置光线起点 voidSetDirection(CVector3&direction); //设置光线方向 CVector3&GetOrigin(); //获取起点 CVector3&GetDirection();//获取方向 private: CVector3m_origin; CVector3m_direction; }; //部分成员函数的实现 #include"declares.h" voidCRay::SetOrigin(CVector3&origin) { m_origin = origin; } CVector3&CRay::GetOrigin() { returnm_origin; } //材料类 classCMaterial { public: voidSetColor(CColor&color); CColorGetColor(); voidSetDiffuse(floatdiffuse); //漫反射光(镜面反射 光,反射光,与之类似) floatGetDiffuse(); voidSetRefractionIndex(floatrefractionIndex); floatGetRefractionIndex(); //折射率,折射指数 private: CColorm_color; floatm_diffuse; floatm_refractionIndex; }; //部分成员函数的实现 #include"declares.h" CMaterial::CMaterial() :m_color(CColor(0.8f, 0.8f, 0.8f)) { } m_reflection = 0.0f; m_diffuse = 0.6f; m_specular = 0.0f; m_refractionIndex = 1.5f; voidCMaterial::SetDiffuse(floatdiffuse) { m_diffuse = diffuse; } floatCMaterial::GetDiffuse() { returnm_diffuse; } voidCMaterial::SetRefractionIndex(floatrefractionIndex) { m_refractionIndex = refractionIndex; } floatCMaterial::GetRefractionIndex() { returnm_refractionIndex; } //原始类 classCPrimitive { public: enum{SPHERE = 1, PLANE}; CMaterial* GetMaterial(); voidSetMaterial(CMaterial&material); //下面是三个纯虚函数 virtualintGetType() = 0; virtualintIntersect(CRay&ray, float&t) = 0; virtualCVector3GetNormal(CPoint3&position) = 0; protected: CMaterialm_material; }; //部分成员函数的实现 #include"declares.h" CMaterial* CPrimitive::GetMaterial() { return&m_material; } voidCPrimitive::SetMaterial(CMaterial&material) { m_material = material; } //平面类 classCPlane : publicCPrimitive //公有继承原始类 { public: CPlane(CVector3normal, floatd); CVector3&GetNormal(); intIntersect(CRay&ray, float&t); private: CVector3m_normal; floatm_d; }; //部分成员函数的实现 #include"declares.h" CPlane::CPlane(CVector3normal, floatd): m_normal(normal) { m_d = d; }; intCPlane::Intersect(CRay&ray, float&t) { floatdot = DotProduct(m_normal, ray.GetDirection()); if(dot == 0) // parallel returnMISS; else { // t = -(N*O+d)/(N*V); floatt0 = -(DotProduct(m_normal, ray.GetOrigin()) + m_d) / dot; if (t0> 0 &&t0<t) { t = t0; returnHIT; } else returnMISS; } } CVector3CPlane::GetNormal(CPoint3&position) { returnm_normal; } //定义球类 classCSphere : publicCPrimitive//同样公有继承原始类 { public: CSphere(CPoint3&center, floatradius); intIntersect(CRay&ray, float&t); //光线和球面求交 CVector3GetNormal(CPoint3&position); private: CPoint3m_center; floatm_radius; }; //部分成员函数的实现 #include"declares.h" CSphere::CSphere(CPoint3&center, floatradius) { m_center = center; m_radius = radius; } CVector3CSphere::GetNormal(CPoint3&position) { returnCVector3(position - m_center) * (1.0f / m_radius); } intCSphere::Intersect(CRay&ray, float&t) { // a*t^2 + b*t + c = 0 // a = V·V floata = DotProduct(ray.GetDirection(), ray.GetDirection()); // b = 2*V·(O - C) floatb = 2 * DotProduct(ray.GetDirection(), (ray.GetOrigin() - m_center)); // c = ||O - C||^2 - r^2 floatc = (float)pow(CVector3(ray.GetOrigin() - m_center).Length(), 2) - m_radius * m_radius; // Δ = b^2 - 4*a*c floatdelta = b * b - 4 * a * c; intresult = MISS; if(delta> 0) { floatt1 = (-b - sqrtf(delta)) / (2 * a); floatt2 = (-b + sqrtf(delta)) / (2 * a); if (t2> 0) { if (t1< 0) { if (t2<t) { t = t2; result = INPRIM; } } else { if (t1<t) { t = t1; result = HIT; } } } } returnresult; } //定义场景类 classCScene { public: voidInitScene(); CPrimitive* GetPrimitive(intindex); private: CPrimitive** m_primitives; }; //部分成员函数的实现 #include"declares.h" CPrimitive* CScene::GetPrimitive(intindex) { returnm_primitives[index]; } voidCScene::InitScene()//场景内的初始化,以底面和球体为 例 { m_primitives = newCPrimitive*[100]; intindex; index = 0; m_primitives[index] = newCPlane(CVector3(0.0f, 1.0f, 0.0f), 0.0f); m_primitives[index]->SetName("bottom plane"); m_primitives[index]->GetMaterial()->SetReflection(0. 0f); m_primitives[index]->GetMaterial()->SetSpecular(0.0f ); m_primitives[index]->GetMaterial()->SetDiffuse(1.0f) ; m_primitives[index]->GetMaterial()->SetColor(CColor( 0.4f, 0.3f, 0.3f)); index++; m_primitives[index] = newCSphere(CPoint3(5.0f, 12.0f, 10.0f), 12.0f); m_primitives[index]->SetName("sphere1"); m_primitives[index]->GetMaterial()->SetReflection(0. 6f); m_primitives[index]->GetMaterial()->SetSpecular(0.6f ); ; m_primitives[index]->GetMaterial()->SetDiffuse(0.6f) m_primitives[index]->GetMaterial()->SetColor(CColor( 1.0f, 1.0f, 1.0f)); index++; m_primitives[index] = newCSphere(CPoint3(0.0f, 20.0f, 30.0f), 0.5f); m_primitives[index]->SetName("light source 1"); m_primitives[index]->SetLight(true); m_primitives[index]->GetMaterial()->SetColor(CColor( 1.0f, 1.0f, 1.0f)); } //光线跟踪 classCRayTracer { Public: voidSetBuffer(COLOR32 * pColorBuffer, intwidth, intheight); //色彩缓存 CScene* GetScene(); // CPrimitive* Raytrace(CRay&ray, CColor&totalColor, intdepth, floatreflactionIndex, float&t); voidInitRender(); //初始化渲染器 boolRender();//渲染 private: floatm_xLeft; //左绘制点 floatm_dy; //y 方向光线步长 CScene* m_pScene; //场景对象 COLOR32 * m_pColorBuffer; //色彩缓存 intm_width; intm_height; intm_currentLine; }; //部分成员函数的实现 #include"declares.h" voidCRayTracer::SetBuffer(COLOR32* pColorBuffer, intwidth, intheight) { m_pColorBuffer = pColorBuffer; m_width = width; m_height = height; } CScene* CRayTracer::GetScene() { returnm_pScene; } CPrimitive* CRayTracer::Raytrace(CRay&ray, CColor&totalColor, intdepth, floatreflactionIndex, float&t) { if (depth>TRACE_DEPTH) // 深度大于跟踪深度停止 returnNULL; t = 1000000.0f; CPrimitive* primitive = NULL; intresult; //获取最近的相交点 intnum = m_pScene->GetPrimitiveNum(); for (inti = 0; i<num; i++) { CPrimitive* currentPrimitive = m_pScene->GetPrimitive(i); intcurrentResult; currentResult = currentPrimitive->Intersect(ray, t); if(currentResult != MISS) { primitive = currentPrimitive; result = currentResult; } } if (primitive == NULL) //没有交点 return 0; if (primitive->IsLight()) //光线顺利到达 { totalColor = primitive->GetMaterial()->GetColor(); } else { CPoint3point; //交点计算 point = ray.GetOrigin() + ray.GetDirection() * t; intnum = m_pScene->GetPrimitiveNum(); for (inti = 0; i<num; i++) { CPrimitive* p = m_pScene->GetPrimitive(i); if (p->IsLight()) { CPrimitive * pLight = p; boolvisible = true; if (pLight->GetType() == CPrimitive::SPHERE) { CVector3direction(((CSphere*)p)->GetCenter() - point); floatt = direction.Length(); direction.Normalize(); CRayr = CRay(point+direction*EPSILON, direction); // whether it is visible for this light for (intj = 0; j<m_pScene->GetPrimitiveNum(); j++) { CPrimitive* p1 = m_pScene->GetPrimitive(j); if ((p1 != pLight) && (p1->Intersect(r, t))) { visible = false; break; } } } if (visible) { // 入射光 CVector3L = ((CSphere*)pLight)->GetCenter() - point; L.Normalize(); // normal CVector3N = primitive->GetNormal(point); // 计算漫反射光 if (primitive->GetMaterial()->GetDiffuse() > 0) { // k * I * (N·L) CColordiffuseColor = primitive->GetMaterial()->GetDiffuse()pLight->GetMateri al()->GetColor() * DotProduct(N, L)*primitive->GetMaterial()->GetColor(); totalColor += diffuseColor; } // 计算镜面反射光 if (primitive->GetMaterial()->GetSpecular() > 0) { // 视点光线 CVector3V = -ray.GetDirection(); // 反射光线, R = 2 * N * (N·L) - L CVector3R = 2.0f * N * DotProduct(N, L) - L; // I * W(θ) * (cosα)^n CColorspecularColor=pLight->GetMaterial()->GetColor() * primitive->GetMaterial()->GetSpecular()* powf(DotProduct(V, -R), 30) * primitive->GetMaterial()->GetColor(); totalColor += specularColor; } } } } // 计算反射 floatreflection = primitive->GetMaterial()->GetReflection(); if ((reflection> 0.0f) && (depth<TRACE_DEPTH)) { CVector3N = primitive->GetNormal(point); CVector3direction = ray.GetDirection() - 2.0f * DotProduct(ray.GetDirection(), N) * N; CRayreflectionRay(point + direction * EPSILON, direction); CColorreflectionColor(0.0f, 0.0f, 0.0f); floatt0; // 继续跟踪反射光线 Raytrace(reflectionRay, reflectionColor, depth + 1, reflactionIndex, t0); reflectionColor = reflection * reflectionColor * primitive->GetMaterial()->GetColor(); totalColor += reflectionColor; } } returnprimitive; } voidCRayTracer::InitRender() { m_currentLine = 0; m_xLeft = -40.0f; m_xRight = 40.0f; m_yTop = 30.0f; m_yBottom = -30.0f; m_dx = (m_xRight - m_xLeft) / m_width; m_dy = (m_yBottom - m_yTop) / m_height; } boolCRayTracer::Render() { if(m_currentLine>= m_height) returntrue; CPoint3o(0.0f, 3.0f, 80.0f); for (intx = 0; x<m_width; x++ ) { CColortotalColor(0.0f, 0.0f, 0.0f); CVector3direction(CPoint3(m_xLeft+x*m_dx, m_yTop+m_currentLine*m_dy, 0) - o); direction.Normalize(); CRayr(o, direction); floatt; Raytrace(r, totalColor, 1, 1.0f, t); intred, green, blue; red = min((int)(totalColor.r * 256), 255); green = min((int)(totalColor.g * 256), 255); blue = min((int)(totalColor.b * 256), 255); m_pColorBuffer[m_currentLine*m_width+x] = (red<< 16) + (green<< 8) + blue; } m_currentLine++; returnfalse; } //主函数 #include"declares.h" HWNDhWnd;//窗口句柄 BITMAPINFObmpInfo;//局部变量 HDChDC; COLOR32buffer[SCREEN_HEIGHT*SCREEN_WIDTH]; CRayTracer* tracer = 0; LRESULTCALLBACKWndProc(HWNDhWnd, UINTmessage, WPARAMwParam, LPARAMlParam); ATOM MyRegisterClass(HINSTANCEhInstance); BOOL InitInstance(HINSTANCEhInstance, intnCmdShow); intAPIENTRYWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstanc e,LPSTRlpCmdLine,intnCmdShow) { MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow)) { returnFALSE; } ZeroMemory(&bmpInfo, sizeof(bmpInfo)); bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 32; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biWidth = SCREEN_WIDTH; bmpInfo.bmiHeader.biHeight = -SCREEN_HEIGHT; hDC = GetDC(hWnd); tracer = newCRayTracer(); tracer->GetScene()->InitScene(); tracer->SetBuffer(buffer, SCREEN_WIDTH, SCREEN_HEIGHT); MSGmessage; tracer->InitRender(); while(1) { if(tracer->Render()) tracer->InitRender(); while(PeekMessage(&message, hWnd, 0, 0, PM_REMOVE)) { TranslateMessage(&message ); DispatchMessage(&message ); } StretchDIBits(hDC, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, buffer, &bmpInfo, DIB_RGB_COLORS, SRCCOPY); } return 1; } //窗口设置 ATOMMyRegisterClass(HINSTANCEhInstance) { //LPCWSTR str = L"RayTracing"; WNDCLASSEXwcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style wcex.lpfnWndProc wcex.cbClsExtra wcex.cbWndExtra wcex.hInstance wcex.hIcon wcex.hCursor wcex.hCursor = CS_HREDRAW | CS_VREDRAW; = (WNDPROC)WndProc; = 0; = 0; = hInstance; = NULL; = NULL; = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = LPCWSTR("Raytracing"); wcex.hIconSm = NULL; returnRegisterClassEx(&wcex); } //初始化窗口 BOOLInitInstance(HINSTANCEhInstance, intnCmdShow) { // hInst = hInstance; // make the window show at the center of the screen, and the client area size is 800*600 RECTrect; rect.left = 0; rect.top = 0; rect.right = SCREEN_WIDTH; rect.bottom = SCREEN_HEIGHT; AdjustWindowRect(&rect, WS_POPUP | WS_SYSMENU | WS_CAPTION, NULL); intwindowWidth = rect.right - rect.left; intwindowHeight = rect.bottom - rect.top; intscreenWidth = GetSystemMetrics(SM_CXSCREEN); intscreenHeight = GetSystemMetrics(SM_CYSCREEN); intwindowLeft = (screenWidth - windowWidth) / 2; intwindowTop = (screenHeight - windowHeight) / 2; hWnd = CreateWindow(LPCWSTR("Raytracing"), // class name LPCWSTR("Raytracing"), // title name of the window WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, // style of the window windowLeft, // initial horizontal position of the window windowTop, // initial vertical position of the window windowWidth, // width of the window windowHeight, / eight of the window NULL, // the parent or owner of the window NULL, // handle to a menu hInstance, // handle to the instance NULL); // parameter if(!hWnd) { returnFALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); returnTRUE; } //窗口消息函数 LRESULTCALLBACKWndProc(HWNDhWnd, UINTmessage, WPARAMwParam, LPARAMlParam) { switch(message) { caseWM_PAINT: StretchDIBits(hDC, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, buffer, &bmpInfo, DIB_RGB_COLORS, SRCCOPY); ValidateRect(hWnd, NULL); break; caseWM_CLOSE: ReleaseDC(hWnd, hDC); DestroyWindow(hWnd); ExitProcess(0); break; default: returnDefWindowProc(hWnd, message, wParam, lParam); } return 0; } 帮我修改完善这个代码
最新发布
12-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值