DXF笔记:对齐尺寸标注的绘制

一些概念

  • 尺寸标注倾斜度
    相对于水平X轴而言
    在这里插入图片描述

  • 尺寸标注样式字段
    40 DIMSCALE 设置应用于标注变量(可指定大小、距离或偏移量)的全局比例因子
    41 DIMASZ 控制尺寸线、引线箭头的大小
    42 DIMEXO 指定尺寸界线偏离原点的距离
    44 DIMEXE 指定尺寸线超出尺寸界线的距离
    140 DIMTXT 指定标注文字的高度(除非当前文字样式具有固定的高度)

  • 箭头
    箭头大小为长度,高度则为0.2*箭头大小,若放不下,增加的引线长也为箭头长度即可。

  • 文字倾斜角度
    在文字样式中增加了倾斜角度

  • 尺寸标注箭头太大时,autocad的处理方式
    在这里插入图片描述

  • 标注样式替代
    在这里插入图片描述
    在这里插入图片描述

代码实现

代码只是用来演示绘制思路,依赖其他一些代码,故不可直接运行。

  • 总体思路
	//标注点
	auto pDimPointGeom = DrawDimPoints();
	if (pDimPointGeom) pRtOsgGeode->addDrawable(pDimPointGeom);

	//绘制尺寸标注线
	auto pDimLineGeom = DrawDimLine();
	if (pDimLineGeom) pRtOsgGeode->addDrawable(pDimLineGeom);

	//绘制两根尺寸界线
	auto pDimBorderLineGeom = DrawDimBorderLine();
	if (pDimBorderLineGeom) pRtOsgGeode->addDrawable(pDimBorderLineGeom);

	//绘制箭头
	auto pArrowGeom = DrawArrow();
	if (pArrowGeom) pRtOsgGeode->addDrawable(pArrowGeom);

	//绘制文字
	DrawDimText(nModelFlag, pRtOsgGeode);
  • 部分代码
osg::ref_ptr<osg::Drawable> DrawerGMAlignedDimension::DrawDimPoints()
{
	osg::Geometry* pDimPointGeom = new osg::Geometry();
	osg::Vec3dArray* pVertexArray = new osg::Vec3dArray();
	pVertexArray->push_back(osg::Vec3d(m_ptDimPoint1.x,
		m_ptDimPoint1.y, m_ptDimPoint1.z));
	pVertexArray->push_back(osg::Vec3d(m_ptDimPoint2.x,
		m_ptDimPoint2.y, m_ptDimPoint2.z));
	pDimPointGeom->setVertexArray(pVertexArray);
	pDimPointGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS,
		0, pVertexArray->size()));

	return pDimPointGeom;
}

osg::ref_ptr<osg::Drawable> DrawerGMAlignedDimension::DrawDimLine()
{
	AcGeVector3d vDimPtToDimLineOffset = m_ptDimLinePoint - m_ptDimPoint2;//标注点到标注线的偏移向量
	AcGePoint3d ptDimLineStart = m_ptDimPoint1 + vDimPtToDimLineOffset;//标注线起点
	AcGePoint3d ptDimLineEnd = m_ptDimPoint2 + vDimPtToDimLineOffset;//标注线末点

	osg::Geometry* pDimLineGeom = new osg::Geometry();
	osg::Vec3dArray* pVertexArray = new osg::Vec3dArray();
	pVertexArray->push_back(osg::Vec3d(ptDimLineStart.x,
		ptDimLineStart.y, ptDimLineStart.z));
	pVertexArray->push_back(osg::Vec3d(ptDimLineEnd.x,
		ptDimLineEnd.y, ptDimLineEnd.z));
	pDimLineGeom->setVertexArray(pVertexArray);
	pDimLineGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,
		0, pVertexArray->size()));

	return pDimLineGeom;
}

osg::ref_ptr<osg::Drawable> DrawerGMAlignedDimension::DrawDimBorderLine()
{
	//标注点到标注线的偏移向量
	AcGeVector3d vDimPtToDimLineOffset = m_ptDimLinePoint - m_ptDimPoint2;

	//dxf文档中说标注点在第二根线上,不能由倾斜度纠正出标注点,
	//因为autocad带倾斜的标注就没导出这个倾斜度
	AcGeVector3d vBorderDir = m_ptDimLinePoint - m_ptDimPoint2;
	vBorderDir.normalize();

	//第一根界线
	AcGePoint3d ptBorder1Start = m_ptDimPoint1 + vBorderDir * (m_dDIMSCALE*m_dDIMEXO);
	AcGePoint3d ptBorder1End = m_ptDimPoint1 + vDimPtToDimLineOffset + vBorderDir *m_dDIMSCALE * m_dDIMEXE;

	//第二根界线
	AcGePoint3d ptBorder2Start = m_ptDimPoint2 + vBorderDir * (m_dDIMSCALE*m_dDIMEXO);
	AcGePoint3d ptBorder2End = m_ptDimPoint2 + vDimPtToDimLineOffset + vBorderDir *m_dDIMSCALE * m_dDIMEXE;


	osg::Geometry* pBorderLineGeom = new osg::Geometry();
	osg::Vec3dArray* pVertexArray = new osg::Vec3dArray();
	pVertexArray->push_back(osg::Vec3d(ptBorder1Start.x,
		ptBorder1Start.y, ptBorder1Start.z));
	pVertexArray->push_back(osg::Vec3d(ptBorder1End.x,
		ptBorder1End.y, ptBorder1End.z));
	pVertexArray->push_back(osg::Vec3d(ptBorder2Start.x,
		ptBorder2Start.y, ptBorder2Start.z));
	pVertexArray->push_back(osg::Vec3d(ptBorder2End.x,
		ptBorder2End.y, ptBorder2End.z));
	pBorderLineGeom->setVertexArray(pVertexArray);
	pBorderLineGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,
		0, pVertexArray->size()));

	return pBorderLineGeom;
}

osg::ref_ptr<osg::Drawable> DrawerGMAlignedDimension::DrawArrow()
{
	AcGeVector3d vDimPtToDimLineOffset = m_ptDimLinePoint - m_ptDimPoint2;标注点到标注线的偏移向量
	
	//获取箭头大小
	//箭头大小为长度,高度的一半为0.2*大小,若放不下,增加的引线长也为箭头长度即可。
	double dArrowSize = m_dDIMASZ * m_dDIMSCALE;

	//计算箭头水平、垂直方向需要的偏移向量
	AcGeVector3d vDimLineDir = m_ptDimPoint2 - m_ptDimPoint1;//标注线方向 
	AcGeVector3d vArrowHOffset = vDimLineDir; //箭头水平方向 
	AcGeVector3d vArrowVOffset = vDimLineDir; //箭头垂直方向
	vArrowVOffset.rotateBy(PI / 2.0, AcGeVector3d::kZAxis);
	vArrowHOffset.normalize();
	vArrowVOffset.normalize();
	vArrowHOffset = vArrowHOffset * dArrowSize; //箭头水平偏移向量
	vArrowVOffset = vArrowVOffset * dArrowSize * 0.2; //箭头垂直方向偏移向量


	osg::Geometry* pArrowGeom = new osg::Geometry();
	osg::Vec3dArray* pVertexArray = new osg::Vec3dArray();


	//起点箭头
	{
		AcGePoint3d ptDimLineStart = m_ptDimPoint1 + vDimPtToDimLineOffset;//标注线起点

		AcGePoint3d ptFirst, ptSencond, ptThird;
		ptFirst = (ptDimLineStart + vArrowHOffset) + vArrowVOffset;
		ptSencond = (ptDimLineStart + vArrowHOffset) - vArrowVOffset;
		ptThird = ptDimLineStart;

		pVertexArray->push_back( osg::Vec3d(ptFirst.x, ptFirst.y, ptFirst.z)); //start point
		pVertexArray->push_back(osg::Vec3d(ptSencond.x, ptSencond.y, ptSencond.z)); //same as start point
		pVertexArray->push_back(osg::Vec3d(ptThird.x, ptThird.y, ptThird.z));
	}

	//末点箭头
	{
		AcGePoint3d ptDimLineEnd = m_ptDimPoint2 + vDimPtToDimLineOffset;//标注线末点

		AcGePoint3d ptFirst, ptSencond, ptThird;
		ptFirst = (ptDimLineEnd - vArrowHOffset) + vArrowVOffset;
		ptSencond = (ptDimLineEnd - vArrowHOffset) - vArrowVOffset;
		ptThird = ptDimLineEnd;

		pVertexArray->push_back(osg::Vec3d(ptFirst.x, ptFirst.y, ptFirst.z)); //start point
		pVertexArray->push_back(osg::Vec3d(ptSencond.x, ptSencond.y, ptSencond.z)); //same as start point
		pVertexArray->push_back(osg::Vec3d(ptThird.x, ptThird.y, ptThird.z));
	}

	pArrowGeom->setVertexArray(pVertexArray);
	pArrowGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 
		0, pVertexArray->size()));
	
	return pArrowGeom;
}

void DrawerGMAlignedDimension::DrawDimText(INT nModelFlag,
	osg::ref_ptr<osg::Geode>& pRtOsgGeode)
{
	if (!m_pGRSolidFactoryImp)
	{
		return;
	}

	//
	//暂只实现了文字居中、放置上标注线上方的逻辑
	//

	//标注文字值,要处理使用测量值的情况
	CString strDimText = m_strDimText;
	if (strDimText.IsEmpty())//文字替换为空,则使用测量值
	{
		double dDistance = m_ptDimPoint1.distanceTo(m_ptDimPoint2);
		switch (m_nDIMDEC)
		{
		case 0:
			strDimText.Format(_T("%.0f"), dDistance);
			break;
		case 1:
			strDimText.Format(_T("%.1f"), dDistance);
			break;
		case 2:
			strDimText.Format(_T("%.2f"), dDistance);
			break;
		case 3:
			strDimText.Format(_T("%.3f"), dDistance);
			break;
		case 4:
			strDimText.Format(_T("%.4f"), dDistance);
			break;
		case 5:
			strDimText.Format(_T("%.5f"), dDistance);
			break;
		case 6:
			strDimText.Format(_T("%.6f"), dDistance);
			break;
		default:
			strDimText.Format(_T("%.0f"), dDistance);
		}
		RemoveBackZero(strDimText);
	}

	//文字标注方向
	AcGeVector3d vDimTextDir = (m_ptDimPoint2 - m_ptDimPoint1).normal();
	//实现居中、上方的文字位置 shanql 2022.7.25
	//文字延着标注线垂直方向向上偏移指定距离。
	//标注线方向的确定: 标注方向 = 标注第二点 - 标注第一点
	//1、使用点积判断
	//若标注方向与x轴正向平行,标注方向取+x;
	//否则,若标注方向与x轴垂直,标注方向取+y;
	//否则,若标注方向与x轴点积 < 0, 则标注方向取反
	//否则标注方向不变
	//
	//2、使用angleTo求出两向量[0-pi]的夹角
	//若为0或pi,则表示与x轴平行,标注方向取+x
	//否则若为pi/2, 则表示与x轴垂直,标注方向取+y;
	//否则若>pi/2, 则标注方向取反
	//否则标注方向不变
	//ptTextPosTemp = ptDimMid + (m_dDIMGAP + m_dDIMTXT / 2.0) * m_dDIMSCALE * vecTextOffsetDir;
	if (vDimTextDir.isCodirectionalTo(AcGeVector3d::kXAxis))
	{//平行x轴
		vDimTextDir = AcGeVector3d::kXAxis;
	}
	else if (vDimTextDir.isPerpendicularTo(AcGeVector3d::kXAxis))
	{//垂直x轴
		vDimTextDir = AcGeVector3d::kYAxis;
	}
	else
	{
		if (vDimTextDir.angleTo(AcGeVector3d::kXAxis) > PI / 2.0)
		{
			vDimTextDir = -vDimTextDir;
		}
	}



	std::shared_ptr<GMText> pGMText = std::make_shared<GMText>(strDimText);
	pGMText->SetExtendDir(vDimTextDir);
	pGMText->SetNormal(AcGeVector3d::kZAxis);

	AcGePoint3d ptTextPosTemp = m_ptTextPos;
	if (ptTextPosTemp.isEqualTo(AcGePoint3d::kOrigin))
	{
		AcGeVector3d vecTextOffsetDir = vDimTextDir;
		vecTextOffsetDir.rotateBy(PI / 2.0, AcGeVector3d::kZAxis);

		//求出标注中点
		AcGeVector3d vDimPtToDimLineOffset = m_ptDimLinePoint - m_ptDimPoint2;//标注点到标注线的偏移向量
		AcGePoint3d ptDimLineStart = m_ptDimPoint1 + vDimPtToDimLineOffset;//标注线起点
		AcGePoint3d ptDimLineEnd = m_ptDimPoint2 + vDimPtToDimLineOffset;//标注线末点
		AcGePoint3d ptDimMid = (ptDimLineStart + ptDimLineEnd.asVector()) / 2.0;

		//求出文字位置
		ptTextPosTemp = ptDimMid + (m_dDIMGAP + m_dDIMTXT / 2.0) * m_dDIMSCALE * vecTextOffsetDir;
	}
	pGMText->SetPosition(ptTextPosTemp);//文字位置 

	pGMText->SetAttachment(GMText::AttachmentType::MiddleCenter);
	
	
	double dTextHeight = m_dDIMTXT * m_dDIMSCALE;
	pGMText->SetHeight(dTextHeight);//文字高度
	pGMText->SetWidth(dTextHeight*1.0);
	
	m_pGRSolidFactoryImp->Create(pGMText, nModelFlag, pRtOsgGeode);
}

运行截图

在这里插入图片描述

与autocad的对比图
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值