动态函数OnDynamicFrame绘制cel单元,cel始终无法显示!急!

动态函数OnDynamicFrame绘制cel单元,cel始终无法显示。但是,将单元换成一段直线可在指定位置动态显示,就是如果调用cel单元库里面的模型,该CEL显示不出来

动态函数OnDynamicFrame

 /// <summary>
        /// 实现onDynamicFramce函数(动态绘制)
        /// </summary>
        /// <param name="ev"></param>
        protected override void OnDynamicFrame(DgnButtonEvent ev)//
        {
            
            DVector3d vecT = outPnt - m_onPnt;
            Angle ang = m_onVec.AngleToXY(vecT);
            DVector3d equVec;
            if (ang.Radians > 0)
            {
                equVec = m_onVec.RotateXY(Angle.FromRadians(Math.PI / 2));
            }
            else
            {
                equVec = m_onVec.RotateXY(Angle.FromRadians(-Math.PI / 2));
            }

            equVec.TryNormalize(out equVec);
            DPoint3d equPnt = m_onPnt + equVec * 5 * 10000;//距离中心线5米,
            DgnModel model = Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModel();
            DgnFile dgnFile = Session.Instance.GetActiveDgnFile();
            String cellName = _form.CellTypeSelected;//如ZDJ9//用于动态绘制
            var pcDef = ParametricCellDefinitionElement.FindByName(cellName, dgnFile);
            ParametricCellElement pc = ParametricCellElement.Create(pcDef, null, model);
            
            // pc.Origin = insertPt;
            pc.Origin = equPnt;
            RedrawElems redrawElems = new RedrawElems();
            redrawElems.DrawMode = DgnDrawMode.TempDraw;
            redrawElems.DrawPurpose = DrawPurpose.Dynamics;
            redrawElems.SetViewport(ev.Viewport);
            redrawElems.SetDynamicsViewsFromActiveViewSet(ev.Viewport);
            redrawElems.DoRedraw(pc);

            //pc.AddToModel();
        }

按键操作中调用动态绘制

//按键操作中调用动态绘制
protected override bool OnDataButton(DgnButtonEvent ev)
        {
            Bentley.DgnPlatformNET.HitPath hitPath = DoLocate(ev, true, 1);
            if (hitPath == null)
                return false;

            Element el = hitPath.GetCursorElement();
            if (el == null)
                return false;
            CurveVector curvec = CurvePathQuery.ElementToCurveVector(el);//侧线
            DTransform3d transf3d = new DTransform3d(ev.Viewport.GetRotation());
            DMatrix4d mat4d = DMatrix4d.From(transf3d);
            CurveLocationDetail loc = curvec.ClosestPointBoundedXY(ev.RawPoint, mat4d);

            m_onPnt = loc.Point;//侧线上的最近点

            curvec.GetAt((int)loc.ComponentIndex).FractionToPoint(loc.ComponentFraction, out m_onPnt, out m_onVec);
			
#if VERSION_NEW
            ConsensusConnection con = new ConsensusConnection(el.DgnModelRef);
            Alignment al = (el.ParentElement == null) ? Alignment.CreateFromElement(con, el) : Alignment.CreateFromElement(con, el.ParentElement);
#else
            Alignment al = (el.ParentElement == null) ? Alignment.CreateFromElement(el) : Alignment.CreateFromElement(el.ParentElement);
#endif

            if (al == null)
                return false;

            if (_form.SelectType == "selectLine")
            {
                if (m_toolState == 0)
                {
                    m_aligment = al;
                    _form.SecondAlignment = al;
                    if (threeDModel == null)
                    {
                        if (m_aligment.ActiveLinearEntity3d != null)
                        {
                            threeDModel = m_aligment.ActiveLinearEntity3d.Element.DgnModel;
                        }
                    }
                    _form.Visible = false;
                    _form.TopMost = false;

                    BeginDynamics();//启动动态绘制函数
                    m_toolState = 1;
                    return true;
                }
                else
                {
                    _form.addDeviceByTwoLine();
                    ExitTool();
                    return true;
                }
            }

  • 补充:该CEL单元是可以用程序直接放置上去(注:此处不是动态绘制,而是直接放置落定模型)

    放置CEL单元

     /// <summary>
            /// 放置cell
            /// </summary>
            /// <param name="dgnFile">当前的dgn文件</param>
            /// <param name="dgnModel">当前的dgnModel</param>
            /// <param name="cellName">cell名称</param>
            /// <param name="insertPt">插入点</param>
            /// <param name="rotateMatrix">旋转矩阵</param>
            /// <returns>cell实例对象</returns>
            public static ParametricCellElement PlaceParametricCell(DgnFile dgnFile, DgnModel dgnModel, string cellName,
                                                                     DPoint3d insertPt, DMatrix3d rotateMatrix)
            {
                var pcDef = ParametricCellDefinitionElement.FindByName(cellName, dgnFile);
                if (pcDef == null)
                {
                    var cellModel = LocateCellModel(cellName);
                    if (cellModel == null)
                    {
                     Bentley.MstnPlatformNET.   MessageCenter.Instance.ShowErrorMessage("没有找到cell " + cellName, null, false);
                        return null;
                    }
                    var hdlr = DgnComponentDefinitionModelHandler.GetForModel(cellModel);
                    var status = hdlr.DefinitionModelHandler.CreateCellDefinition(dgnFile);
                    string name = dgnFile.GetFileName();
                    if (status == ParameterStatus.Success  )
                    {
                        pcDef = ParametricCellDefinitionElement.FindByName(cellName, dgnFile);
                    }
                    else if (  status == ParameterStatus.DuplicateName)
                    {
                        Bentley.MstnPlatformNET.MessageCenter.Instance.ShowErrorMessage("创建cell定义时" + cellName + "重名失败!", null, false);
                        return null;
                    }
                    else
                    {
                        Bentley.MstnPlatformNET.MessageCenter.Instance.ShowErrorMessage("创建cell定义" + cellName + "失败!", null, false);
                        return null;
                    }
                }
                ParametricCellElement pc = ParametricCellElement.Create(pcDef, null, dgnModel);
                if (pc == null)
                {
                    Bentley.MstnPlatformNET.MessageCenter.Instance.ShowErrorMessage("创建cell" + cellName + "失败!", null, false);
                    return null;
                }
                pc.Origin = insertPt;
                pc.Rotation = rotateMatrix;
                pc.AddToModel();
                return pc;
            }
    

  • 您的创建ParametricCell的函数中需要传入插入点参数,在OnDynamicFrame中,每次从DgnButtonEvent参数中获得光标点坐标,用该坐标创建ParametricCell,这样才能实现动态。请看如下代码样例:

    protected override void OnDynamicFrame(DgnButtonEvent ev)
            {
                double width = double.Parse(m_pcForm.cabinet_w.Text);
                Element pc = CreateElements.CreateParametricCell(ev.Point, width);
                if (null == pc)
                    return;
    
                RedrawElems redrawElems = new RedrawElems();
                redrawElems.SetDynamicsViewsFromActiveViewSet(Bentley.MstnPlatformNET.Session.GetActiveViewport());
                redrawElems.DrawMode = DgnDrawMode.TempDraw;
                redrawElems.DrawPurpose = DrawPurpose.Dynamics;
    
                redrawElems.DoRedraw(pc);
            }

    public static Element CreateParametricCell(DPoint3d translation, double width)
            {
                const string pcName = "Double Door Cabinet";
                const string setName = "Standard";
    
                DgnFile  dgnFile = Session.Instance.GetActiveDgnFile();
                DgnModel dgnModel = Session.Instance.GetActiveDgnModel();
            
                var pcDef = ParametricCellDefinitionElement.FindByName(pcName, dgnFile);
    
                if (null == pcDef)
                {
                    var cellModel = LocateCellModel(pcName);
                    if (null == cellModel)
                    {
                        MessageCenter.Instance.ShowErrorMessage("Not found cell", null, true);
                        return null;
                    }
                    var hdlr = DgnComponentDefinitionHandler.GetForModel(cellModel);
                    var status = hdlr.DefinitionModelHandler.CreateCellDefinition(dgnFile);
                    if (ParameterStatus.Success == status)
                        pcDef = ParametricCellDefinitionElement.FindByName(pcName, dgnFile);
                    else
                    {
                        MessageCenter.Instance.ShowErrorMessage("Error Creating cellDef", null, true);
                        return null;
                    }
                }
                var pc = ParametricCellElement.Create(pcDef, setName, dgnModel);
    
                IDgnECInstance inst = pc.Parameters as IDgnECInstance;
                IECArrayValue arr = inst.GetPropertyValue("ParameterValuesContainer") as IECArrayValue;
                IECStructValue structVal = arr[1] as IECStructValue;  // .Adhoc_Name = _LOCAL_Cabinet_W
                structVal.SetValue("Adhoc_Value", width);
                inst.ScheduleChanges(pc);
    
                DTransform3d trans = DTransform3d.Identity;
                trans.Translation = translation;
                TransformInfo transInfo = new TransformInfo(trans);
                pc.ApplyTransform(transInfo);
    
                return pc;
            }

    动态显示的过程其实就是一个不断在鼠标新光标点绘制、旧光标点擦除的过程。被动态的元素位置必须随着光标点不断地变化才可以。



  • 符老师,您说的这个点我们应该是创建了的吧,outPnt 为光标上的点,equVec为CELL的位置点(这个点是指定的,偏离线路中线5米)。

    我们这个CEL模型不是附在光标上,而是在上述指定位置

  • 请按如下步骤测试:

    1、下载如下CERI02.ZIP并解压到C:\Program Files\Bentley\MicroStation CONNECT Edition\MicroStation\Mdlapps文件夹下。需要Windows管理员权限,因为这个文件夹默认非管理员的话是只读的。

    CERI02.zip

    2、进入MSCE时要选择Example > MetroStation工作空间和工作集。这样才能找到系统自带的MetroStation.cel中的参数化单元

    3、打开一个DGN文件的三维模型,进入MDL LOAD CERI02装载程序。随后再键入CERI CREATE PARA并回车,就能看到一个动态的参数化单元在随着你的光标运动。



    MISSING RESOURCE: VerifiedBy BIM@Railway 

  • 研究了很久,始终无法动态绘制CEL,不知道是不是ORD本身不支持在2D动态绘制? 但是,我们之前开发的放置程序却是在2D中放置,切换到3D后可以看到三维模型