1.使用的工具
libDxf-负责解析dxf文件,提取图形元素
open_Nurbs-负责spline曲线的计算
2.效果如下
左图是CAD绘制的spline曲线,右图是程序中显示的曲线,红色点是在CAD中作图时鼠标点击的拟合点。
3.main.cpp代码
#include"zmDXF.h"
#include"myCanvus.h"
#include"opennurbs_public.h"
#include<iostream>
#include<QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//封装了libDxf,解析dxf文件
zmDXF dxf;
dxf.read("F:/Temp/QtTest/1.dxf");
//自定义一个画布,简单显示一下曲线
myCanvus canvus;
canvus.show();
//处理每一条曲线
for(int i = 0; i < dxf.getSplines().size(); i++)
{
zmSpline spline = dxf.getSplines()[i];
ON_NurbsCurve curve;
//创建一条NURBS曲线
//3维 x,y,z
//有理
//阶数=多项式次数+1
//控制点数量
curve.Create(3, true, spline.m_info.degree + 1, spline.m_ctrlPts.size());
//对每个控制点赋值
for(int j = 0; j < spline.m_ctrlPts.size(); j++)
{
ON_3dPoint point;
point.x = spline.m_ctrlPts[j].x;
point.y = spline.m_ctrlPts[j].y;
point.z = spline.m_ctrlPts[j].z;
curve.SetCV(j, point);
}
//节点和dxf读取的不一致,假如读取的节点是0,0,0,1,2,2,2
//要设置的节点实际是0,0,1,2,2
//图形学中:节点数量=控制点数量+阶数,与dxf文件一致
//ON_NurbsCurve中节点数量比上面少2个
for(int j = 0; j < spline.m_knots.size() - 2; j++) {
curve.SetKnot(j, spline.m_knots[j + 1].k);
}
//获取节点向量取值范围
double range[2] = {0, 0};
curve.GetDomain(range, range + 1);
double domain = range[1] - range[0];
//每条线计算100个点进行显示
QVector<QPointF>pointfs;
int resolution = 100;
for(int j = 0; j < resolution; j++)
{
ON_3dPoint pt = curve.PointAt(range[0] + domain * j / (resolution - 1));
pointfs.append(QPointF(pt.x, pt.y));
}
//提取拟合点,用红色显示
QVector<QPointF>fitPoints;
for(int j = 0; j < spline.m_fitPts.size(); j++)
{
QPointF point;
point.setX(spline.m_fitPts[j].x);
point.setY(spline.m_fitPts[j].y);
fitPoints.append(point);
}
canvus.addPath(pointfs);
canvus.addPoints(fitPoints);
}
return a.exec();
}
4.对libDXF的简单封装
#ifndef ZMDXF_H
#define ZMDXF_H
#include<QPointF>
#include"zmSpline.h"
#include"zmPoint.h"
#include"zmLine.h"
#include"zmArc.h"
#include"zmPolyLine.h"
class zmDXF : public DL_CreationAdapter
{
public:
zmDXF();
void read(const char *file);
const std::vector<zmSpline> &getSplines()const;
private:
void addPoint(const DL_PointData &) override; //解析单个点
void addLine(const DL_LineData &) override; //解析直线
void addPolyline(const DL_PolylineData &) override; //解析多段线
void addVertex(const DL_VertexData &) override; //解析顶点
void addArc(const DL_ArcData &) override; //解析圆弧
void addCircle(const DL_CircleData &) override; //解析圆
void addSpline(const DL_SplineData &) override;//样条曲线
void addControlPoint(const DL_ControlPointData &) override; //样条控制点
void addFitPoint(const DL_FitPointData &) override; //样条拟合点
void addKnot(const DL_KnotData &) override; //样条节点
void addBlock(const DL_BlockData &) override;//块数据
void addText(const DL_TextData &) override;
void addMText(const DL_MTextData &) override;
private:
std::vector<zmArc>m_arcs;
std::vector<zmLine>m_lines;
std::vector<zmPoint>m_points;
std::vector<zmPolyLine>m_polyLines;
std::vector<zmSpline>m_splines;
};
#endif // ZMDXF_H
5.下一步看看能不能自己写一个spline的解析,非均匀有理样条公式有点复杂