问题描述: 

在涉及视口切换或者模型查看等功能时使用zcedSetCurrentView是经常会用到的接口,但是有不少开发者反馈使用zcedSetCurrentView设置视口时候会有些小问题在里面,

比如说下面我们会介绍一个给视口做平移的功能,传入视口中心点为相同值,但是平移缩放时候出现不一样的效果的问题。

示例:

例如下面代码是给一个视口设置往中心点往右偏移四分之一位置的示例,但是实际执行效果是多次执行这个函数视口平移不一致。

Acad::ErrorStatus zcedGetCurrentView(AcDbViewTableRecord &);

AcGePoint3d pan(const AcGePoint3d& ptTarget, bool movelefthalftwo)
{
	AcGePoint3d returnPoint = ptTarget;

	AcDbViewTableRecord view;
	zcedGetCurrentView(view);

	ads_point wTarget;
	wTarget[X] = ptTarget[X];
	wTarget[Y] = ptTarget[Y];
	wTarget[Z] = ptTarget[Z];


	struct resbuf rb;
	struct resbuf wcs, dcs, ccs; // acedTrans coord system flags
	ads_point vpDir;
	ads_point wdcsTarget;   // windows corners in device coords
	AcGeVector3d viewDir;
	AcGePoint2d cenPt; ads_real lenslength,
		viewtwist,
		frontz,
		backz;
	ads_point target; int viewmode,
		tilemode,
		cvport;
	wcs.restype = RTSHORT; // WORLD coord system flag
	wcs.resval.rint = 0;
	ccs.restype = RTSHORT; // CURRENT coord system flag
	ccs.resval.rint = 1;
	dcs.restype = RTSHORT; // DEVICE coord system flag
	dcs.resval.rint = 2; // Get the 'VPOINT' direction vector
	acedGetVar(L"VIEWDIR", &rb); //VIEWDIR is reported in UCS
	acedTrans(rb.resval.rpoint, &ccs, &wcs, 0, vpDir);
	viewDir.set(vpDir[X], vpDir[Y], vpDir[Z]); // convert upper right window corner to DCS
	acedTrans(wTarget, &ccs, &dcs, 0, wdcsTarget); // convert lower left window corner to DCS

	// 计算居中点(默认中心)
	double centerX = wdcsTarget[X];
	double centerY = wdcsTarget[Y];

	resbuf rb1 = { 0 }, rb2 = { 0 };
	acedGetVar(_T("SCREENSIZE"), &rb1);
	acedGetVar(_T("VIEWSIZE"), &rb2);
	double view_width = rb1.resval.rpoint[0] / rb1.resval.rpoint[1] * rb2.resval.rreal;
	double view_height = rb2.resval.rreal;
	view.setHeight(view_height);
	view.setWidth(view_width);

	double width = view.width();
	// 让右边留 1/4 空间
	centerX += width * 0.25;

	cenPt.set(centerX, centerY);


	view.setCenterPoint(cenPt); // set view height and width and direction

	acedSetCurrentView(&view, NULL);

	return returnPoint;
}


问题原因:

问题根源在于ZWCAD对dbTarget的定义存在差异。三维非透视视口的DB数据中存放了一个target变量和一个centerPoint变量,视口的target叠加其centerPoint在投影平面上的x和y分量后才是真正用于显示计算的相机的target坐标。其他CAD以视口target为其dbTarget,而ZWCAD以相机target为dbTarget,dbTarget决定了dcs(显示坐标系)的原点,导致了dcs坐标到wcs坐标的变换结果不同

解决方法:

可以通过在二开代码中获取正确target参数计算变换矩阵,再用该矩阵参与计算来替换acedTrans接口:

可以在 ads_point wTarget;
wTarget[X] = ptTarget[X];
wTarget[Y] = ptTarget[Y];
wTarget[Z] = ptTarget[Z];后面 加:

    wTarget[X] += view. centerPoint().x;
    wTarget[Y] += view.centerPoint().y;

来解决这个问题。


英文空间链接


★中望CAD 2025以上版本三维视图样式中zcedSetCurrentView设置视口容易出现“抖动”怎么解决?https://confluence.zwcad.com/pages/viewpage.action?pageId=301140555

  • No labels