Custom polyline with individual colors for edges: make the segments selectable

I need a polyline with colored segments/edges and every individual edge should be selectable.
Basically what you can do with BRepBuilderAPI_MakePolygon would serve my needs, except that I can't give colors to the edges (as far as I can see).
The code below is an example only showing a few points in the polyline, but in reality it can contain more than 10k points.

So I made my own AIS_InteractiveObject derivation:

class MyAisTrajectoryObject : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MyAisTrajectoryObject, AIS_InteractiveObject)
public:
	MyAisTrajectoryObject();
public:
	void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr,const Handle(Prs3d_Presentation)& thePrs,const Standard_Integer theMode) override;
	void ComputeSelection(const Handle(SelectMgr_Selection)& theSel,const Standard_Integer theMode) override;
	bool AcceptDisplayMode(const Standard_Integer theMode) const override;
protected:
	std::vector<gp_Pnt>					m_Points;
	std::vector<Quantity_Color >		m_Colors;
	Handle(Graphic3d_ArrayOfPolylines)	arLines;
	Handle(Graphic3d_AspectLine3d)		m_LineAspects;
}; 

MyAisTrajectoryObject::MyAisTrajectoryObject() 
{
	m_Points = { {100,0,300} ,{0,0,300} ,{0,100,300} , {0,0,200} };
	m_Colors = { Quantity_Color(1.0,0.0,0.0,Quantity_TOC_RGB)  , Quantity_Color(0.0,1.0,0.0,Quantity_TOC_RGB) , Quantity_Color(0.0,0.0,1.0,Quantity_TOC_RGB) , Quantity_Color(1.0,1.0,1.0,Quantity_TOC_RGB) };
	m_LineAspects = new Graphic3d_AspectLine3d(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB), Aspect_TOL_SOLID, 5.0);
}

void MyAisTrajectoryObject::Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr, const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode)
{
	arLines = new Graphic3d_ArrayOfPolylines(m_Points.size(),0,0, Graphic3d_ArrayFlags_VertexColor);

	size_t NPoints = std::min<size_t>(m_Points.size(), m_Colors.size());
	for (size_t Index = 0; Index < NPoints; Index++)
	{
		arLines->AddVertex(m_Points
, m_Colors
); } Handle(Graphic3d_Group) aGroupLines = thePrs->NewGroup(); aGroupLines->SetGroupPrimitivesAspect(m_LineAspects); aGroupLines->AddPrimitiveArray(arLines); } void MyAisTrajectoryObject::ComputeSelection(const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) { if (arLines.IsNull()) return; Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner(this); Handle(Select3D_SensitivePrimitiveArray) aSens = new Select3D_SensitivePrimitiveArray(anOwner); // detect individual points of trajectory aSens->SetDetectElements(true); aSens->SetSensitivityFactor(8); aSens->InitPoints(arLines->Attributes(), arLines->Indices(), TopLoc_Location(), true); aSens->BVH(); theSel->Add(aSens); } bool MyAisTrajectoryObject::AcceptDisplayMode(const Standard_Integer theMode) const { return true; }

It works fine for the presentation, but I cannot select individual edges.

Any suggestions?
Or maybe there are other better alternatives.

gkv311 n's picture

You have the following options within ComputeSelection():

  • Create multiple SelectMgr_EntityOwner for each selectable segment and define own geometry per segment.
  • Subclass SelectMgr_EntityOwner::HilightWithColor to highlight individual segments detected by Select3D_SensitivePrimitiveArray::LastDetectedElement() (see AIS_PointCloudOwner as example).
Luc Wens's picture

I have been testing with AIS_PointCloud and i think this comes closest to what I need: color per vertex and selection of individual vertices, I only need to adapt this to edges. During test I did have unexptected behaviour when doing a polygon selection (the box selection works correctly): it selects less points than expected (see attached movie).