gp_Trsf within AIS_InteractiveObject is an unfortunate consequence of desire to reuse existing TopLoc_Datum3D, with overseen use case of non-uniform scaling (rarely needed).
If we will take a look at gp_Trsf, we will find that all its methods process the 3x3 matrix to fit definition of uniform-only scale factor (stored as a dedicated class field, hence 3x3 matrix is only for rotation), and all its fields are private by design.
All, but one - gp_Trsf::InitFromJson() lacks validation layer (by mistake of course, not by design), so it can be used to initialize a 'broken' transformation. If we do that to create a matrix with non-uniform scale, we can see objects displayed with this scale. However, the selection of the object will work incorrectly.
One of the reasons is that PrsMgr_PresentableObject::UpdateTransformation() computes inversed transformation out of gp_Trsf::Inversed(). We may further hack PrsMgr_PresentableObject::InversedTransformation() to assign a properly initialized inversed matrix to it.
#include <AIS_Shape.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
...
const Handle(AIS_InteractiveContext)& theCtx = ...;
TopoDS_Shape aBox = BRepPrimAPI_MakeBox(gp_Pnt(50.0, 0.0, 0.0), 100.0, 100.0, 100.0);
TopoDS_Shape aCone = BRepPrimAPI_MakeCone(100.0, 20.0, 100.0);
gp_Trsf aTrsf;
{
// This code abuses the fact that gp_Trsf::InitFromJson() lacks validation layer.
// gp_Other = 8
std::stringstream aStream;
aStream << "\"Location\": [-50, 0, 0], \"Matrix\": [3, 0, 0, 0, 3, 0, 0, 0, 1], \"shape\": 8";
int aPos = 1;
aTrsf.InitFromJson(aStream, aPos);
}
Handle(AIS_Shape) aPrsBox = new AIS_Shape(aBox);
aPrsBox->SetLocalTransformation(aTrsf); // for visualization
const_cast<gp_GTrsf&>(aPrsBox->InversedTransformation()) =
gp_GTrsf(aTrsf).Inverted(); // for selection
Handle(AIS_Shape) aPrsCone = new AIS_Shape(aCone);
aPrsCone->SetLocalTransformation(aTrsf); // for visualization
const_cast<gp_GTrsf&>(aPrsBox->InversedTransformation()) =
gp_GTrsf(aTrsf).Inverted();
theCtx->Display(aPrsBox, false);
theCtx->Display(aPrsCone, true);
Alternatively one may declare gp_Trsf copy with access to private fields and apply modifications via memory aliasing instead of serializing string for gp_Trsf::InitFromJson(). Of course, this is just a fragile hack and proof of concept, I don't suggest using it in a real code, but it might be tolerable as a temporary workaround, if you have very limited scenario to apply it.
Archived image: nonuniformscale.png