老师好:
为了便于沟通和交流,我重新创建了一个贴子。
通过老师点点滴滴的 指导 和 浏览论坛 其他的相关帖子 ,找到了 部分资料,并将代码编译通过了。但是仍旧有些问题。具体如下
我的业务场景是 当用户定义 一个 3D元素的时候,通过预览按钮 ,可以在 Generic 上显示出来该元素,但是目前 测试发现 Generic 上没有反应(没有显示该元素)。
具体业务逻辑是 :
当用户点击 预览按钮后 ,将根据定义好的数据 创建出来一个元素(CELL),最终通过调用 void drawCellDetail(MSDialogP dbP , DialogItem *diP , int is3d , MSElementDescrP cellDP)函数,将这个元素(CELL)显示到 Generic上,从而达到预览的效果(并且 要求 该元素(CELL) 不添加到当前的设计文件中,只是 预览的功能)。
其中 diP 是 Generic 句柄,
dbP是 diP ->GetDialog () ,
is3d 是 1,
cellDP是我代码创建的cell 通过 eehTmp.GetElementDescrP(); 获取的。
代码如下:
ppp=mdlDialog_itemGetByTypeAndId(dimP->db,RTYPE_Generic ,GENERICID_Cells , 0 );
drawCellDetail(ppp->GetDialog () , ppp , 1 , pz.ElementD);
编译通过的代码如下:
void drawCellDetail(MSDialogP dbP , DialogItem *diP , int is3d , MSElementDescrP cellDP) { ViewFlags viewflags; RotMatrix rMatrix; BSIRect localRect; Dpoint3d origin, newextent; int nDices; DRange3d dRangeVec=Bentley::DRange3d::From(0,0,0,0,0,0); // int status; //dRangeVec->From(0,0,0,0,0,0); localRect = diP->rect; mdlElmdscr_validate (cellDP, MASTERFILE); nDices = mdlModelRef_is3D (MASTERFILE); if (!is3d) { mdlRMatrix_getIdentity (&rMatrix); mdlCnv_scanRangeToDRange (&dRangeVec, &cellDP->el.hdr.dhdr.range); origin = dRangeVec.low; origin.z = 0.0; mdlVec_subtractPoint (&newextent,&dRangeVec.high,&origin); newextent.z = fc_1000; if (newextent.x < fc_1) newextent.x = fc_1000; if (newextent.y < fc_1) newextent.y = fc_1000; memset (&viewflags, 0, sizeof(viewflags)); viewflags.patterns = 1; viewflags.ed_fields = 1; viewflags.on_off = 1; viewflags.grid = 1; viewflags.constructs = 1; viewflags.dimens = 1; // mdlDialog_rectInset(&localRect, 3, 3); mdlWindow_clipRectSet ((MSWindow *)dbP, &localRect); mdlElmdscr_displayToWindow ((MSWindow *)dbP, &localRect,&viewflags ,cellDP, &rMatrix, &origin, &newextent, nDices, -1); mdlWindow_clipRectSet ((MSWindow *)dbP, NULL); } else { BSIRect localRectArray[4]; int deltaX; int deltaY; int winNumber; RotMatrix rMatrixArray[4]; //set up the views mdlView_getStandard (&rMatrixArray[0],StandardView::Top); mdlView_getStandard (&rMatrixArray[1],StandardView::Iso); mdlView_getStandard (&rMatrixArray[2],StandardView::Front); mdlView_getStandard (&rMatrixArray[3],StandardView::Right); deltaX = localRect.corner.x - localRect.origin.x; deltaY = localRect.corner.y - localRect.origin.y; localRectArray[0] = localRect; localRectArray[0].corner.y = localRect.origin.y+(deltaY/2); localRectArray[0].corner.x = localRect.origin.x+(deltaX/2); localRectArray[1] = localRect; localRectArray[1].origin.x = localRect.origin.x+(deltaX/2); localRectArray[1].corner.y = localRect.origin.y+(deltaY/2); localRectArray[2] = localRect; localRectArray[2].origin.y = localRect.origin.y+(deltaY/2); localRectArray[2].corner.x = localRect.corner.x-(deltaX/2); localRectArray[3] = localRect; localRectArray[3].origin.x = localRect.origin.x+(deltaX/2); localRectArray[3].origin.y = localRect.origin.y+(deltaY/2); for (winNumber = 0;winNumber <4 ;winNumber++ ) { mdlCnv_scanRangeToDRange (&dRangeVec, &cellDP->el.hdr.dhdr.range); mdlRMatrix_multiplyRange (&dRangeVec.low,&dRangeVec.high,&rMatrixArray[winNumber]); mdlVec_subtractPoint (&newextent,&dRangeVec.high,&dRangeVec.low); mdlRMatrix_multiplyTransposePoint(&dRangeVec.low, &rMatrixArray[winNumber]); if (newextent.z< fc_1) newextent.z = fc_1000; if (newextent.x < fc_1) newextent.x = fc_1000; if (newextent.y < fc_1) newextent.y = fc_1000; memset (&viewflags, 0, sizeof(viewflags)); viewflags.patterns = 1; viewflags.ed_fields = 1; viewflags.on_off = 1; viewflags.grid = 1; viewflags.constructs = 1; viewflags.dimens = 1; // mdlDialog_rectInset(&localRectArray[winNumber], 2, 2); mdlWindow_clipRectSet ((MSWindow *)dbP, &localRect); mdlElmdscr_displayToWindow ((MSWindow *)dbP, &localRectArray[winNumber],&viewflags ,cellDP, &rMatrixArray[winNumber], &dRangeVec.low, &newextent, nDices, -1); mdlDialog_rectDrawEdge (dbP,&localRectArray[winNumber],TRUE); mdlWindow_clipRectSet ((MSWindow *)dbP, NULL); } } mdlElmdscr_freeAll (&cellDP); }
希望老师在百忙之中 ,帮忙分析一下 ,是什么原因,辛苦老师了!!感激!!!
看到您之前的帖子了。调试代码比较费时,请耐心等待我们的答复。
好的,感谢老师!!!!
Bentley 二次开发小白一枚
您这个 是可以的,但是 从理论上 ,感觉没有问题啊,所以 老师能不能 看一下 我那个简单 场景的 测试代码,是否有问题,或者让说 原理上 是否存在 问题!!!!
平凡人生 said:if(dimP->messageType == DITEM_MESSAGE_BUTTON )
跟踪一下代码,看这个条件进入了吗?另外,你这样判断会被调用两次,因为Button事件有按下和抬起两次调用。一个按钮控件最好关联一个命令号,在命令处理函数中调用updateDialog
另外,我把你的代码加入到了我的代码中去显示,没有调用AddToModel,也是正常的。
显示结果如下图所示:
如果还是找不到原因,请提交一个完整的可调试项目,最好排除其他无关因素,就抽取这个功能发给我。我帮你逐行查看一下。不过这样会比较耽误时间。最好还是自己调试找原因。
我 整理了一个 可以执行的,还是辛苦您 帮忙 查看一下!我确实 找不到头绪!!!辛苦老师了!!!!
编译后 ,是一个对话框 界面,界面上有一个 预览按钮。
附近是 可执行的工程。
8233.UI_code.zip
其实你的预览功能是正确的,只不过你把对话框设计得太大了,稍微一动就会发生对话框更新事件(DIALOG_MESSAGE_UPDATE),这个Generic类型的控件会被重新刷新,你绘制的图形就消失了。
我对你的代码做了多处修改,包括对话框高度、某些ID的名称和编号的不合适设置等。在你源代码中也写了注释。
最主要的修改是给对话框增加了一个钩函数(DlgBasic_hookFunc),它是通过钩函数标识符HOOKID_DlgBasic与资源关联起来的。
在对话框刷新消息下又重新绘制了图形。为了懒省事,将你的代码复制了一份过来,你将来要抽取成一份代码。同时,为了控制首次打开时不显示图形,设计了一个全局变量g_firstStart。
修改后的项目源代码如下:
8371.UI_code.7z
执行结果如下图所示:
如您所说,确实已经添加到 对话框上的预览框上了,但是现在有如下问题:
1、具体效果如下:
对应的代码段如下:
造成这个原因的 是什么呢?请老师 给与指正!!!!
我查看了代码 分析可能是和我使用了 //viewflags.renderMode = (UInt32)MSRenderMode::SmoothShade; 这个语句有关。
如果我注释掉该语句,则会出现如下效果
是和尺寸大小有关系吗?包括显示的是 线框图 也是这个原因吗?
我采用的视图是 mdlView_getStandard(&rMatrix, StandardView::RightIso );
辛苦老师了,或者 说如果想让 预览的元素 在指定 预览窗口的位置 应该怎么设置呢?
Iso或RightIso都是轴侧图,此种情况下计算范围确实有一定的难度,需要考虑一下对元素范围的坐标变换。
如下修改一下就能正确显示Iso视角的元素了。
效果如下:
Answer Verified By: 平凡人生
如果想显示出渲染效果,可以添加如下两行:
viewflags.renderMode = (UInt32)MSRenderMode::SmoothShade; viewflags.ignoreSceneLights = 1; //use view default light
效果如下图所示: