class CConduitTestBackFaceCulling : public CRhinoDisplayConduit { public: CConduitTestBackFaceCulling(const ON_Brep* brep, const CRhinoObject* obj); ~CConduitTestBackFaceCulling() = default; bool ExecConduit( CRhinoDisplayPipeline& dp, // pipeline executing this conduit UINT nChannel, // current channel within the pipeline bool& bTerminate // channel termination flag ); private: const ON_Brep * m_Brep; const CRhinoObject* mObject; }; CConduitTestBackFaceCulling::CConduitTestBackFaceCulling(const ON_Brep* brep, const CRhinoObject* obj) : CRhinoDisplayConduit(CSupportChannels::SC_CALCBOUNDINGBOX | CSupportChannels::SC_PREDRAWOBJECTS | CSupportChannels::SC_DRAWOBJECT), m_Brep(brep), mObject(obj) { } bool CConduitTestBackFaceCulling::ExecConduit(CRhinoDisplayPipeline& dp, UINT nChannel, bool& bTerminate) { UNREFERENCED_PARAMETER(bTerminate); // Determine which channel we're currently executing in... switch (nChannel) { case CSupportChannels::SC_CALCBOUNDINGBOX: { ON_BoundingBox bbox; m_Brep->GetTightBoundingBox(bbox, false); // Now adjust the channel attribute's bounding box with the accumulated one... m_pChannelAttrs->m_BoundingBox.Union(bbox); } break; case CSupportChannels::SC_DRAWOBJECT: { if (m_pChannelAttrs->m_pObject == mObject) { m_pChannelAttrs->m_bDrawObject = false; } } break; case CSupportChannels::SC_PREDRAWOBJECTS: { dp.PushDepthTesting(false); m_pDisplayAttrs->m_bShowIsocurves = false; m_pDisplayAttrs->m_bCullBackfaces = true; ON_Brep* brep = const_cast(m_Brep); CDisplayPipelineMaterial material; material.m_FrontMaterial.m_diffuse = ON_Color(0, 0, 255); material.m_BackMaterial.m_diffuse = ON_Color(0, 0, 255); dp.DrawShadedBrep(brep, &material, 0); //dp.DrawShadedBrep(*brep, &material); //in Rhino5 m_pDisplayAttrs->m_bShowIsocurves = true; m_pDisplayAttrs->m_bCullBackfaces = false; dp.PopDepthTesting(); } break; } return true; } #pragma region TestBackFaceCullingCmd command class CCommandTestBackFaceCullingCmd : public CRhinoCommand { public: CCommandTestBackFaceCullingCmd() {} ~CCommandTestBackFaceCullingCmd() {} UUID CommandUUID() { // {D7C7E039-5232-41B4-A573-725667752FEB} static const GUID TestBackFaceCullingCmdCommand_UUID = { 0xD7C7E039, 0x5232, 0x41B4, { 0xA5, 0x73, 0x72, 0x56, 0x67, 0x75, 0x2F, 0xEB } }; return TestBackFaceCullingCmdCommand_UUID; } const wchar_t* EnglishCommandName() { return L"TestBackFaceCullingCmd"; } const wchar_t* LocalCommandName() const { return L"TestBackFaceCullingCmd"; } CRhinoCommand::result RunCommand(const CRhinoCommandContext&); }; // The one and only CCommandTestBackFaceCullingCmd object static class CCommandTestBackFaceCullingCmd theTestBackFaceCullingCmdCommand; CRhinoCommand::result CCommandTestBackFaceCullingCmd::RunCommand(const CRhinoCommandContext& context) { CRhinoGetObject go; go.SetCommandPrompt(L"Select brep"); go.SetGeometryFilter(ON::brep_object); go.GetObjects(1, 1); if (go.CommandResult() != success) return go.CommandResult(); CRhinoObjRef ref = go.Object(0); const ON_Brep * brep = ref.Brep(); const CRhinoObject * obj = ref.Object(); CConduitTestBackFaceCulling conduit(brep, obj); conduit.Enable(); RhinoApp().ActiveDoc()->Regen(); CRhinoGetPoint gp; gp.SetCommandPrompt(L"Select point to stop conduit"); gp.GetPoint(); conduit.Disable(); context.m_doc.Regen(); return CRhinoCommand::success; } #pragma endregion