InteractiveObject starts from former position when dragged?

eue

Active CAD practitioner
What I did is creating a InteractiveObject class, the BIM_InteractiveObject, inhereting AIS_Shape. I override the virtual method ProcessDragging(...) to enable mouse dragging object interaction. The interaction is done by setting the local transformation of the selected BIM_InteractiveObject class object to calculated drag position.
Code:
Standard_Boolean BIM_InteractiveObject::ProcessDragging(const Handle(AIS_InteractiveContext)& theCtx, const Handle(V3d_View)& theView, const Handle(SelectMgr_EntityOwner)& theOwner, const Graphic3d_Vec2i & theDragFrom, const Graphic3d_Vec2i & theDragTo, const AIS_DragAction theAction)
{
    if (theAction == AIS_DragAction_Update)
    {
        Handle(StdSelect_ViewerSelector3d) aSelector = this->InteractiveContext()->MainSelector();
        SelectMgr_SortCriterion aPickPnt;
        for (int aPickIter = 1; aPickIter <= aSelector->NbPicked(); ++aPickIter)
        {
            if (aSelector->Picked(aPickIter) == theOwner) // filter out other SelectMgr_EntityOwner
            {
                aPickPnt = aSelector->PickedData(aPickIter);
                break;
            }
        }
        gp_Trsf DirTrans;
        DirTrans.SetTranslation(gp_Pnt(aPickPnt.Point.X(), aPickPnt.Point.Y(), aPickPnt.Point.Z()), gp_Pnt(position_in_view.x(), position_in_view.y(), position_in_view.z()));

        this->SetLocalTransformation(DirTrans);
        
    }
    return true;
}

Now the interaction works okay for the BIM_InteractiveObject class object when dragging it first time. However, when dragging again the object starts from previous position. What is more, after the second drag, the object stops responding to mouse interaction all together.
1654758359279.png
1654758500109.png
1654758592234.png
1654758715986.png
 

natalia

Moderator
Staff member
Hi @eue
However, when dragging again the object starts from previous position
It looks correct. You're modifying local transformation of the presentation that will be thrown down by the next drag as implemented above.

Following your code, the 'position_in_view' should be changed by the 'AIS_DragAction_Stop' action type. Something like:
C++:
if (theAction == AIS_DragAction_Update)
{
  Handle(StdSelect_ViewerSelector3d) aSelector = this->InteractiveContext()->MainSelector();
  ...
}
else if (theAction == AIS_DragAction_Stop)
{
    // update fields of the current object   
}

Usually we change local transformation during drag as it's in your code. It gives better performance than rebuid the presentation. And after, when the drag is finished, we change the object itself and redisplay it. By changing the object I mean the data model update, where the object lives or just update for the object's fields. In this case, the next drag will work with the object like it always exists in this new position.
 

eue

Active CAD practitioner
Hi @eue

It looks correct. You're modifying local transformation of the presentation that will be thrown down by the next drag as implemented above.

Following your code, the 'position_in_view' should be changed by the 'AIS_DragAction_Stop' action type. Something like:
C++:
if (theAction == AIS_DragAction_Update)
{
  Handle(StdSelect_ViewerSelector3d) aSelector = this->InteractiveContext()->MainSelector();
  ...
}
else if (theAction == AIS_DragAction_Stop)
{
    // update fields of the current object
}

Usually we change local transformation during drag as it's in your code. It gives better performance than rebuid the presentation. And after, when the drag is finished, we change the object itself and redisplay it. By changing the object I mean the data model update, where the object lives or just update for the object's fields. In this case, the next drag will work with the object like it always exists in this new position.
thank you for the answer.
I have a question, does this mean I have to recreated a new object and display it at the end position of drag? Is there a way to simply alter its transformation?
I tried calling UpdateTransformation(). It seems that the global position of the object is updated, but its attached EntityOwner seems to not have moved at all.
...
else if (theAction == AIS_DragAction_Stop)
{
this->UpdateTransformation(); // should update the absolute transformation of the object
}
...

What happens is after the object moved, it stops interacting with mouse. Only after placing a new object (maybe triggering refreshment of entity owners), the highlighted entity appears in random position when hovering mouse over the AIS object. But clicking it transport the object to where entity owner is.

1654844120112.png
1654844050784.png

My guess at this problem is maybe the entity owner is moving at a different pace than the dragged AIS object, this cause the object to separate from entity? but I can't figure out why it is so and how to fix this?
 
Last edited:
Top