各位老师好:我现在有个问题想请教大家
问题场景:我想实现在PS里创建的墙梁板柱等基础构件可以通过选择实体、然后选择面的操作
起初我在ABD CE里使用的是LocateSubEntityTool方法,可以拾取CE里的墙 柱等,但是程序放到PS里就不可以了,但是在PS里创建的拉伸体可以实现操作,
请问这块有什么办法可以解决吗,或者有什么例子可供参考吗?提前先谢谢各位老师了,新手,还望不吝赐教~
请提供一个测试DGN供分析。Bentley各专业软件生成的虽然都是DGN,但都做了一些自己的定制,需要分析后才能答复您的问题。
psTest.dgn符老师,你好!附件是我上传的dgn,请查收,里面的墙和柱子都不能拾取,使用Ribbon自带的提取工具也不可以,提示是Element not valid for tool 与使用LocateSubEntityTool时提示的一样,谢谢符老师!
能否在_DoLocateSubEntity里面获得?
张老师 我试了使用_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: 新畅 艾