《OpenNURBS》part1 3DMViewer
来源:互联网 发布:js设置请求头解决跨域 编辑:程序博客网 时间:2024/05/16 12:37
《OpenNURBS》part1 3DMViewer
最近在做曲线拟合、曲线动态编辑,多段线、Spline、B-Spline、NURBS等资料蛮多,眼花缭乱,能看懂的同时能使用的不多,很多时候需要自己重新写。
这里使用的是OpenNURBS库,Rhino出的,Rhino自不用解释,大学时机械设计时的神器之一。言归正传,该库可以去官网上下载,是一个VS2010版的解决方案,VS2010以上版本都可以编译通过,github上的貌似需要openthread支持。目前最好使用官网提供的源码和素材,能够轻松编译通过。
1、VS2010及以上版本编译,编译很简单,不详细说。
2、配置环境,编译好了,自己建一个文件夹,老三样:include、lib、bin。
3、测试用例:
1)openNURBS自带的有五个样例,还有一个gl的,但是没有加入到项目中,可以自己试着调试看看。自带的五个都能编译通过,可以自行测试,看看能不能用。
2)我用的GitHub上的一个例子,3DMViewer,该例子需要OpenNURBS和OSG3.3.1的支持了,没有编译OSG的童鞋留心了,要不自己编译,要不止步在上条就可以了。
4、调试3DMViewer,前提是三方库和路径、lib、dll都配置好了。三个文件,如下:
(1)RhinoReader.h
#ifndef _RHINOREADER_H_#define _RHINOREADER_H_#include <osg/Group>#include <opennurbs.h>/*** @breif Rhino opennurbs 3DM file reader.*/class RhinoReader{public: RhinoReader(const std::string& theFileName); ~RhinoReader(void); osg::Node* GetRhinoModel(void); void SetEdgePrecision(double thePrecision); void SetFacePrecision(double thePrecision);private: void Read3DM(const std::string& theFileName); osg::Node* BuildBrep(const ON_Brep* theBrep); osg::Node* BuildEdge(const ON_Brep* theBrep); osg::Node* BuildWireFrameFace(const ON_BrepFace* theFace); osg::Node* BuildShadedFace(const ON_BrepFace* theFace);private: double mEdgePrecision; double mFacePrecision; ONX_Model mRhinoModel; osg::Node* mRhinoNode;};#endif // _RHINOREADER_H_
(2)RhinoReader.cpp
#include "RhinoReader.h"#include <osg/Geode>#include <osg/Geometry>#include <osgUtil/SmoothingVisitor>#include <osgUtil/DelaunayTriangulator>const double TOLERANCE_EDGE = 1e-6;const double TOLERANCE_FACE = 1e-6;RhinoReader::RhinoReader(const std::string& theFileName): mRhinoNode(NULL){ Read3DM(theFileName);}RhinoReader::~RhinoReader(void){}osg::Node* RhinoReader::GetRhinoModel(){ return mRhinoNode;}void RhinoReader::Read3DM(const std::string& theFileName){ if (!mRhinoModel.Read(theFileName.c_str())) { return ; } osg::Group* aRoot = new osg::Group(); for (int i = 0; i < mRhinoModel.m_object_table.Count(); ++i) { ONX_Model_Object anObject = mRhinoModel.m_object_table[i]; const ON_Brep* aBrep = dynamic_cast<const ON_Brep*> (anObject.m_object); if (aBrep) { aRoot->addChild(BuildBrep(aBrep)); } } mRhinoNode = aRoot;}osg::Node* RhinoReader::BuildBrep(const ON_Brep* theBrep){ osg::ref_ptr<osg::Group> aGroup = new osg::Group(); //aGroup->addChild(BuildEdge(theBrep)); for (int i = 0; i < theBrep->m_F.Count(); ++i) { ON_BrepFace* aFace = theBrep->Face(i); aGroup->addChild(BuildWireFrameFace(aFace)); //aGroup->addChild(BuildShadedFace(aFace)); } //theBrep->Dump(ON_TextLog()); return aGroup.release();}osg::Node* RhinoReader::BuildEdge(const ON_Brep* theBrep){ osg::ref_ptr<osg::Geode> aGeode = new osg::Geode(); for (int i = 0; i < theBrep->m_E.Count(); ++i) { osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> aVertices = new osg::Vec3Array(); ON_BrepEdge* anEdge = theBrep->Edge(i); double t0 = 0.0; double t1 = 0.0; double d = 0.0; anEdge->GetDomain(&t0, &t1); d = (t1 - t0) / 5.0; for (double t = t0; (t - t1) < TOLERANCE_EDGE; t += d) { ON_3dPoint aPoint = anEdge->PointAt(t); aVertices->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z)); } aGeometry->setVertexArray(aVertices); aGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, aVertices->size())); aGeode->addDrawable(aGeometry); } return aGeode.release();}osg::Node* RhinoReader::BuildWireFrameFace(const ON_BrepFace* theFace){ osg::ref_ptr<osg::Geode> aGeode = new osg::Geode(); ON_NurbsSurface aSurface; if (theFace->GetNurbForm(aSurface) == 0) { return NULL; } double u0 = aSurface.Domain(0).Min(); double u1 = aSurface.Domain(0).Max(); double v0 = aSurface.Domain(1).Min(); double v1 = aSurface.Domain(1).Max(); double d0 = 0.0; double d1 = 0.0; d0 = (u1 - u0) / 10.0; d1 = (v1 - v0) / 10.0; for (double u = u0; (u - u1) < TOLERANCE_FACE; u += d0) { osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> aVertices = new osg::Vec3Array(); for (double v = v0; (v - v1) < TOLERANCE_FACE; v += d1) { ON_3dPoint aPoint = aSurface.PointAt(u, v); aVertices->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z)); } aGeometry->setVertexArray(aVertices); aGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, aVertices->size())); aGeode->addDrawable(aGeometry); } for (double v = v0; (v - v1) < TOLERANCE_FACE; v += d1) { osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> aVertices = new osg::Vec3Array(); for (double u = u0; (u - u1) < TOLERANCE_FACE; u += d0) { ON_3dPoint aPoint = aSurface.PointAt(u, v); aVertices->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z)); } aGeometry->setVertexArray(aVertices); aGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, aVertices->size())); aGeode->addDrawable(aGeometry); } return aGeode.release();}osg::Node* RhinoReader::BuildShadedFace(const ON_BrepFace* theFace){ osg::ref_ptr<osg::Geode> aGeode = new osg::Geode(); ON_NurbsSurface aSurface; if (theFace->GetNurbForm(aSurface) == 0) { return NULL; } osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> aUVPoints = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> aPoints = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> aBounds = new osg::Vec3Array(); osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator(); osg::ref_ptr<osgUtil::DelaunayConstraint> dc = new osgUtil::DelaunayConstraint(); // add loop for the face. for (int i = 0; i < theFace->LoopCount(); ++i) { ON_BrepLoop* aLoop = theFace->Loop(i); if (aLoop->m_type == ON_BrepLoop::outer) { for (int j = 0; j < aLoop->TrimCount(); ++j) { ON_BrepTrim* aTrim = aLoop->Trim(j); const ON_Curve* aPCurve = aTrim->TrimCurveOf(); if (aPCurve) { ON_3dPoint aStartPoint = aPCurve->PointAtStart(); ON_3dPoint aEndPoint = aPCurve->PointAtEnd(); aUVPoints->push_back(osg::Vec3(aStartPoint.x, aStartPoint.y, 0.0)); aUVPoints->push_back(osg::Vec3(aEndPoint.x, aEndPoint.y, 0.0)); } } } else if (aLoop->m_type == ON_BrepLoop::inner) { for (int j = 0; j < aLoop->TrimCount(); ++j) { } } } dc->setVertexArray(aBounds); dc->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, aBounds->size())); // triangulate the parametric space. //dt->addInputConstraint(dc); dt->setInputPointArray(aUVPoints); dt->triangulate(); //dt->removeInternalTriangles(dc); for (osg::Vec3Array::const_iterator j = aUVPoints->begin(); j != aUVPoints->end(); ++j) { // evaluate the point on the surface ON_3dPoint aPoint = aSurface.PointAt((*j).x(), (*j).y()); aPoints->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z)); } //aGeometry->setVertexArray(aUVPoints); aGeometry->setVertexArray(aPoints); aGeometry->addPrimitiveSet(dt->getTriangles()); aGeode->addDrawable(aGeometry); // use smoothing visitor to set the average normals //osgUtil::SmoothingVisitor sv; //sv.apply(*aGeode); return aGeode.release();}
(3)main.cpp
#include <iostream>// OpenSceneGraph library.#include <osgGA/StateSetManipulator>#include <osgViewer/Viewer>#include <osgViewer/ViewerEventHandlers>#include "RhinoReader.h"#ifdef _DEBUG #pragma comment(lib, "osgd.lib") #pragma comment(lib, "osgGAd.lib") #pragma comment(lib, "osgUtild.lib") #pragma comment(lib, "osgViewerd.lib") // OpenNURBS toolkit. #pragma comment(lib, "opennurbs_d.lib")#else #pragma comment(lib, "osg.lib") #pragma comment(lib, "osgGA.lib") #pragma comment(lib, "osgUtil.lib") #pragma comment(lib, "osgViewer.lib") // OpenNURBS toolkit. #pragma comment(lib, "opennurbs.lib")#endifint main(int argc, char* argv[]){ //if (argc < 2) //{ // std::cout << "please input the 3dm file..." << std::endl; // return 0; //} ON::Begin(); RhinoReader aReader(/*argv[1]*/"v1"); osgViewer::Viewer viewer; viewer.setSceneData(aReader.GetRhinoModel()); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); ON::End(); return viewer.run();}
注:此处的main函数被我注释了,调试时尽量使用上面的方法按F5进入调试,直接ctrl+F5会出错。
5、运行结果
在另外一台没联网的电脑上调试通过的,自己的电脑没有环境配置。那么结果图就略了。
阅读全文
0 0
- 《OpenNURBS》part1 3DMViewer
- Rhino3dmIO Toolkit (OpenNURBS build)
- part1
- PART1
- PART1
- DataGrid Web控件深度历险(3) part1
- 第一次PCB画板实战-MiniDV-Part1/3
- Cocos3.3横版游戏-Part1
- Behind the 3D scenes - part1
- [G+smo]openNurbs相关的CAD文件格式转换
- 算法设计与分析课程Part1笔记(3)
- Linux入门 Part1: 使用控制台(3)-shell,command & parameter(s)
- 读书《MySQL5权威指南(第 3 版)》------part1入门
- SyntaxHighlighter part1
- MileStone(part1)
- struts part1
- js part1
- Part1:CException
- 服务端 I/O 性能大比拼:Node、PHP、Java 和 Go
- JavaScript 最新特性实现的三大黑科技
- 自然语言处理基础(1)--基本分词方法
- iOS 从0到1搭建高可用App框架
- python2 + opencv2 + windows 8
- 《OpenNURBS》part1 3DMViewer
- 机房夜话
- Pycharm软件申请学生免费使用的许可证步骤
- 图像拼接原理与相关技术
- SSM实现多条件查询
- MySQL的复制流程
- c++面试总结1
- WebView自定义长按选择,实现收藏/分享选中文本。
- 游戲中的时间倒回系统