关于在PS中如何通过程序提取墙梁板柱的面的问题

各位老师好:我现在有个问题想请教大家

问题场景:我想实现在PS里创建的墙梁板柱等基础构件可以通过选择实体、然后选择面的操作

起初我在ABD CE里使用的是LocateSubEntityTool方法,可以拾取CE里的墙 柱等,但是程序放到PS里就不可以了,但是在PS里创建的拉伸体可以实现操作,

请问这块有什么办法可以解决吗,或者有什么例子可供参考吗?提前先谢谢各位老师了,新手,还望不吝赐教~

Parents
  • 请提供一个测试DGN供分析。Bentley各专业软件生成的虽然都是DGN,但都做了一些自己的定制,需要分析后才能答复您的问题。



  • psTest.dgn符老师,你好!附件是我上传的dgn,请查收,里面的墙和柱子都不能拾取,使用Ribbon自带的提取工具也不可以,提示是Element not valid for tool 与使用LocateSubEntityTool时提示的一样,谢谢符老师!

  • 张老师 我试了使用_DoLocateSubEntity后 不管return true 还是false都不在触发_OnElementModify了,怎么办呢

  • 您是打算做什么操作,_DoLocateSubEntity就是获取子元素的函数,您在里面可以获取您点击子元素的点。LocateSubEntityTool是从ElementGraphicsTool派生下来的,如果是用到ElementGraphicsTool封装的功能,从而重写了其虚函数的话,最好是在这个虚函数里边执行完自己的操作之后通过_super调用一下父类被重写的虚函数,关于LocateSubEntityTool很多您可以搜搜,也可以看看SDK的例子自己调试一下。

  • 张老师 再次打扰 我按照你说的 使用_DoLocateSubEntity时得到了点击子元素的点,然后我根据这个点去求出子元素面上最近的点,但是这块失败了,请问能是什么原因,是我的测试点有问题吗??我把代码贴一下,麻烦帮我看一下,谢谢

    struct PlaceAnchorPlateTool : LocateSubEntityTool
    {

    public:
    CEmbedPartsDesignDataDlg* m_dlgP;
    DPoint3d m_pos;

    protected:
    virtual BentleyStatus _OnProcessSolidPrimitive(ISolidPrimitivePtr& geomPtr, DisplayPathCR path) override { return ERROR; } // Promote capped surface to solid body...
    virtual BentleyStatus _OnProcessPolyface(PolyfaceHeaderPtr& geomPtr, DisplayPathCR path) override { return SUCCESS; } // Don't convert a closed mesh to a BRep (and don't collect), can be expensive for large meshes... +---------------+---------------+---------------+---------------+---------------+------*/
    virtual ISubEntity::SubEntityType _GetSubEntityTypeMask() override { return ISubEntity::SubEntityType_Face; }
    virtual bool _RequireSubEntitySupport() override { return true; } // Require solid w/at least 1 face...
    virtual bool _AcceptIdentifiesSubEntity() { return true; } // Solid accept point may also accept first face (except hollow which can apply to entire body)...
    virtual bool _IsElementValidForOperation(ElementHandleCR eh, HitPathCP path, WStringR cantAcceptReason) override
    {
    return (__super::_IsElementValidForOperation(eh, path, cantAcceptReason) && 1 == GetElementGraphicsCacheCount(eh) && !IsGeometryMissing(eh));
    }
    virtual bool _IsModifyOriginal() { return false; }
    virtual bool _IsSingleShot() override { return true; }
    //virtual bool _OnDataButton(DgnButtonEventCR ev) override
    //{
    // m_pos = *ev.GetPoint();
    // return true;
    //}

    virtual void _OnPostInstall() override
    {
    __super::_OnPostInstall();

    mdlLocate_init();
    mdlAccuSnap_enableSnap(true);
    mdlLocate_setCursor();
    mdlAccuSnap_enableLocate(true);
    mdlAccuSnap_enableSnap(false);
    mdlAccuSnap_suspend(false);
    mdlAccuDraw_setEnabledState(false);
    mdlSelect_freeAll();
    }

    virtual bool _OnPostLocate(HitPathCP path, WStringR cantAcceptReason) override
    {
    if (!DgnElementSetTool::_OnPostLocate(path, cantAcceptReason))
    return false;

    //ElementHandle eh(path->GetHeadElem(), path->GetRoot());

    return true;
    }

    virtual bool _OnResetButton(DgnButtonEventCR ev) override
    {
    bool bRet = __super::_OnResetButton(ev);

    ElemAgendaEntry* eeh = GetElementAgenda().GetEntryP(0);
    if (nullptr == eeh)
    {
    _ExitTool();
    }
    return bRet;
    }

    virtual StatusInt _OnElementModify(EditElementHandleR eeh) override
    {
    DPoint3d vec;
    if (_GetAnchorPoint(&vec))
    {
    bvector<ISubEntityPtr>& faces = GetAcceptedSubEntities();
    int nCount = faces.size();
    if (!faces.empty())
    {
    ISubEntityPtr& face = faces.front();
    if (ISubEntity::SubEntityType_Face == face->GetSubEntityType())
    {
    DRange1d uRange, vRange;
    if (SUCCESS == SolidUtil::GetFaceParameterRange(*face, uRange, vRange))
    {
    DPoint3d center, pickpoint;
    DVec3d normal, uDir, vDir;
    DPoint2d uvParam;
    uvParam.x = (uRange.low + uRange.high) * 0.5;
    uvParam.y = (vRange.low + vRange.high) * 0.5;

    if (SUCCESS == SolidUtil::ClosestPointToFace(*face, m_pos, pickpoint, normal, uvParam))
    //if (SUCCESS == SolidUtil::EvaluateFace(*face, pickpoint, normal, uDir, vDir, uvParam))
    {
    //水平布置
    if (m_dlgP->m_rad_Hor.GetCheck() == BST_CHECKED)
    {
    if (m_dlgP->m_rad_CT.GetCheck() == BST_CHECKED)
    {
    //CT布置,求出CT的距离
    pickpoint.z -= GlobalTools::MillimetreToUor(m_dlgP->m_dHorDist);
    }
    else
    {
    //CB布置,求出CB的距离
    pickpoint.z -= GlobalTools::MillimetreToUor(m_dlgP->m_dHorDist);
    }
    }
    else
    {
    //垂直布置,求出CS的距离
    pickpoint.z += GlobalTools::MillimetreToUor(m_dlgP->m_dVerticalDist);
    }

    mdlTMatrix_getIdentity(&BentleyElemUtil::TransMat);
    RotMatrix matrix;
    mdlRMatrix_fromVectorToVector(&matrix, &DPoint3d::From(0, 0, -1), &normal);
    BentleyElemUtil::TransMat.InitFrom(matrix);
    mdlTMatrix_setTranslation(&BentleyElemUtil::TransMat, &pickpoint);

    m_dlgP->CreateAnchorPlate(BentleyElemUtil::TransMat);
    }
    }
    return ERROR;//SUCCESS会再创建一个eeh对象
    }
    }
    }
    return ERROR;
    }

    virtual void _OnRestartTool() override
    {
    _ExitTool();
    }

    virtual bool _DoLocateSubEntity(DgnButtonEventCR ev, bool newSearch)
    {
    m_pos = *ev.GetPoint();
    return __super::_DoLocateSubEntity(ev, newSearch);
    }

    virtual void _ExitTool()
    {
    __super::_ExitTool();
    m_dlgP->ShowWindow(SW_SHOW);
    }

  • 我这边可以呀:

    /*--------------------------------------------------------------------------------------+
    |
    |     $Source: MstnExamples/Elements/exampleSolids/exampleSubEntityTool.cpp $
    |
    |  $Copyright: (c) 2015 Bentley Systems, Incorporated. All rights reserved. $
    |
    +--------------------------------------------------------------------------------------*/
    #include "exampleSolids.h"
    
    USING_NAMESPACE_BENTLEY_DGNPLATFORM;
    USING_NAMESPACE_BENTLEY_MSTNPLATFORM;
    USING_NAMESPACE_BENTLEY_MSTNPLATFORM_ELEMENT;
    
    /*=================================================================================**//**
    * Example showing how to use LocateSubEntityTool to write a tool to identify
    * faces, edges, or vertices of a solid or surface. This tool doesn't modify the
    * element and allows both locked elements and reference elements to be selected. 
    * Accepting locked/reference elements would be appropriate for a query tool like
    * measure distance, area, volume.
    *
    * @bsiclass                                                               Bentley Systems
    +===============+===============+===============+===============+===============+======*/
    struct          TestSubEntityTool : LocateSubEntityTool
    {
    protected:
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    TestSubEntityTool (int cmdName) {SetCmdName (cmdName, 0);}
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual StatusInt _OnPreElementModify (EditElementHandleR eeh) override {return ERROR;} // Example doesn't modify elements, don't copy styles, etc. from reference to active...
    virtual bool _IsModifyOriginal () override {return false;} // Allow sub-entity selection of elements in reference attachments...
    virtual void _OnPostInstall() override
    {
        __super::_OnPostInstall();
    
        mdlLocate_init();
        mdlAccuSnap_enableSnap(true);
        mdlLocate_setCursor();
        mdlAccuSnap_enableLocate(true);
        mdlAccuSnap_enableSnap(false);
        mdlAccuSnap_suspend(false);
        mdlAccuDraw_setEnabledState(false);
        mdlSelect_freeAll();
    }
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual ISubEntity::SubEntityType _GetSubEntityTypeMask () override {return (ISubEntity::SubEntityType) (ISubEntity::SubEntityType_Face | ISubEntity::SubEntityType_Edge | ISubEntity::SubEntityType_Vertex);}
    virtual bool _RequireSubEntitySupport () override {return true;} // Only allow elements having the requested sub-entity to be selected...
    
    /*---------------------------------------------------------------------------------**//**
    * Install a new instance of the tool. Will be called in response to external events
    * such as undo or by the base class from _OnReinitialize when the tool needs to be
    * reset to it's initial state.
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual void _OnRestartTool () override
        {
        InstallNewInstance (GetToolId ());
        }
    
    virtual bool _OnResetButton(DgnButtonEventCR ev) override
    {
        bool bRet = __super::_OnResetButton(ev);
    
        ElemAgendaEntry* eeh = GetElementAgenda().GetEntryP(0);
        if (nullptr == eeh)
        {
            _ExitTool();
        }
        return bRet;
    }
    
    
    virtual bool _OnDataButton(DgnButtonEventCR ev) override
    {
        StatusInt mstatus = ERROR;
        bool    status = __super::_OnDataButton(ev);
        bvector<ISubEntityPtr>& faces = GetAcceptedSubEntities();
    
    
        int nCount = faces.size();
        if (!faces.empty())
        {
            ISubEntityCR face = *faces.front();
            if (ISubEntity::SubEntityType_Face == face.GetSubEntityType())
            {
                DPoint2d        param;
                DVec3d          normal;
                DPoint3d        facePoint;
    
                if (true == SolidUtil::ClosestPointToFace(*GetAcceptedSubEntities().front(), m_pos, facePoint, normal, param))
                {
                    return SUCCESS;
                }
    
            }
    
        }
    
        return SUCCESS;
    }
    
    virtual StatusInt _OnElementModify(EditElementHandleR eeh) override
    {
    
        return ERROR;
    }
    
    virtual bool _DoLocateSubEntity(DgnButtonEventCR ev, bool newSearch)
    {
        m_pos = *ev.GetPoint();
    
        return __super::_DoLocateSubEntity(ev, newSearch);
    }
    
    public:
        DPoint3d m_pos;
    /*---------------------------------------------------------------------------------**//**
    * Method to create and install a new instance of the tool. If InstallTool returns ERROR,
    * the new tool instance will be freed/invalid. Never call delete on RefCounted classes.
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    static void InstallNewInstance (int toolId)
        {
        TestSubEntityTool* tool = new TestSubEntityTool (toolId);
    
        tool->InstallTool ();
        }
    
    }; // TestSubEntityTool
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    Public void startExampleLocateSubEntityTool (WCharCP unparsed)
        {
        // NOTE: Call the method to create/install the tool, RefCounted classes don't have public constructors...
        TestSubEntityTool::InstallNewInstance (CMDNAME_ExampleSubEntityTool);
        }
    

    Answer Verified By: 新畅 艾 

Reply
  • 我这边可以呀:

    /*--------------------------------------------------------------------------------------+
    |
    |     $Source: MstnExamples/Elements/exampleSolids/exampleSubEntityTool.cpp $
    |
    |  $Copyright: (c) 2015 Bentley Systems, Incorporated. All rights reserved. $
    |
    +--------------------------------------------------------------------------------------*/
    #include "exampleSolids.h"
    
    USING_NAMESPACE_BENTLEY_DGNPLATFORM;
    USING_NAMESPACE_BENTLEY_MSTNPLATFORM;
    USING_NAMESPACE_BENTLEY_MSTNPLATFORM_ELEMENT;
    
    /*=================================================================================**//**
    * Example showing how to use LocateSubEntityTool to write a tool to identify
    * faces, edges, or vertices of a solid or surface. This tool doesn't modify the
    * element and allows both locked elements and reference elements to be selected. 
    * Accepting locked/reference elements would be appropriate for a query tool like
    * measure distance, area, volume.
    *
    * @bsiclass                                                               Bentley Systems
    +===============+===============+===============+===============+===============+======*/
    struct          TestSubEntityTool : LocateSubEntityTool
    {
    protected:
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    TestSubEntityTool (int cmdName) {SetCmdName (cmdName, 0);}
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual StatusInt _OnPreElementModify (EditElementHandleR eeh) override {return ERROR;} // Example doesn't modify elements, don't copy styles, etc. from reference to active...
    virtual bool _IsModifyOriginal () override {return false;} // Allow sub-entity selection of elements in reference attachments...
    virtual void _OnPostInstall() override
    {
        __super::_OnPostInstall();
    
        mdlLocate_init();
        mdlAccuSnap_enableSnap(true);
        mdlLocate_setCursor();
        mdlAccuSnap_enableLocate(true);
        mdlAccuSnap_enableSnap(false);
        mdlAccuSnap_suspend(false);
        mdlAccuDraw_setEnabledState(false);
        mdlSelect_freeAll();
    }
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual ISubEntity::SubEntityType _GetSubEntityTypeMask () override {return (ISubEntity::SubEntityType) (ISubEntity::SubEntityType_Face | ISubEntity::SubEntityType_Edge | ISubEntity::SubEntityType_Vertex);}
    virtual bool _RequireSubEntitySupport () override {return true;} // Only allow elements having the requested sub-entity to be selected...
    
    /*---------------------------------------------------------------------------------**//**
    * Install a new instance of the tool. Will be called in response to external events
    * such as undo or by the base class from _OnReinitialize when the tool needs to be
    * reset to it's initial state.
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    virtual void _OnRestartTool () override
        {
        InstallNewInstance (GetToolId ());
        }
    
    virtual bool _OnResetButton(DgnButtonEventCR ev) override
    {
        bool bRet = __super::_OnResetButton(ev);
    
        ElemAgendaEntry* eeh = GetElementAgenda().GetEntryP(0);
        if (nullptr == eeh)
        {
            _ExitTool();
        }
        return bRet;
    }
    
    
    virtual bool _OnDataButton(DgnButtonEventCR ev) override
    {
        StatusInt mstatus = ERROR;
        bool    status = __super::_OnDataButton(ev);
        bvector<ISubEntityPtr>& faces = GetAcceptedSubEntities();
    
    
        int nCount = faces.size();
        if (!faces.empty())
        {
            ISubEntityCR face = *faces.front();
            if (ISubEntity::SubEntityType_Face == face.GetSubEntityType())
            {
                DPoint2d        param;
                DVec3d          normal;
                DPoint3d        facePoint;
    
                if (true == SolidUtil::ClosestPointToFace(*GetAcceptedSubEntities().front(), m_pos, facePoint, normal, param))
                {
                    return SUCCESS;
                }
    
            }
    
        }
    
        return SUCCESS;
    }
    
    virtual StatusInt _OnElementModify(EditElementHandleR eeh) override
    {
    
        return ERROR;
    }
    
    virtual bool _DoLocateSubEntity(DgnButtonEventCR ev, bool newSearch)
    {
        m_pos = *ev.GetPoint();
    
        return __super::_DoLocateSubEntity(ev, newSearch);
    }
    
    public:
        DPoint3d m_pos;
    /*---------------------------------------------------------------------------------**//**
    * Method to create and install a new instance of the tool. If InstallTool returns ERROR,
    * the new tool instance will be freed/invalid. Never call delete on RefCounted classes.
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    static void InstallNewInstance (int toolId)
        {
        TestSubEntityTool* tool = new TestSubEntityTool (toolId);
    
        tool->InstallTool ();
        }
    
    }; // TestSubEntityTool
    
    /*---------------------------------------------------------------------------------**//**
    * @bsimethod                                                              Bentley Systems
    +---------------+---------------+---------------+---------------+---------------+------*/
    Public void startExampleLocateSubEntityTool (WCharCP unparsed)
        {
        // NOTE: Call the method to create/install the tool, RefCounted classes don't have public constructors...
        TestSubEntityTool::InstallNewInstance (CMDNAME_ExampleSubEntityTool);
        }
    

    Answer Verified By: 新畅 艾 

Children
No Data