// sensitive entities activated. For more information, see
// SelectMgr_ViewerSelector.hxx
//=======================================================================
-void AIS_InteractiveContext::SetPixelTolerance (const Standard_Real thePrecision)
+void AIS_InteractiveContext::SetPixelTolerance (const Standard_Integer thePrecision)
{
if (HasOpenedContext())
{
//function : PixelTolerance
//purpose :
//=======================================================================
-Standard_Real AIS_InteractiveContext::PixelTolerance() const
+Standard_Integer AIS_InteractiveContext::PixelTolerance() const
{
return HasOpenedContext()
? myLocalContexts (myCurLocalIndex)->PixelTolerance()
aLineAspect->SetTypeOfLine (Aspect_TOL_DASH);
// tolerance to 2 pixels...
- SetPixelTolerance (2.0);
+ SetPixelTolerance (2);
// Customizing the drawer for trihedrons and planes...
Handle(Prs3d_DatumAspect) aTrihAspect = myDefaultDrawer->DatumAspect();
//! SelectMgr_ViewerSelector documentation
//! Warning: When a local context is open the sensitivity is apply on it
//! instead on the main context.
- Standard_EXPORT void SetPixelTolerance (const Standard_Real aPrecision = 2.0);
+ Standard_EXPORT void SetPixelTolerance (const Standard_Integer aPrecision = 2);
//! Returns the pixel tolerance.
- Standard_EXPORT Standard_Real PixelTolerance() const;
+ Standard_EXPORT Standard_Integer PixelTolerance() const;
//! Puts the location aLocation on the initial graphic
//! representation and the selection for the entity aniobj.
return myMainPM->IsImmediateModeOn();
}
-void AIS_LocalContext::SetPixelTolerance(const Standard_Real aPrecision) {
+void AIS_LocalContext::SetPixelTolerance(const Standard_Integer aPrecision) {
myMainVS->SetPixelTolerance(aPrecision);
}
-Standard_Real AIS_LocalContext::PixelTolerance() const {
+Standard_Integer AIS_LocalContext::PixelTolerance() const {
return myMainVS->PixelTolerance();
}
//! Define the current selection sensitivity for
//! this local context according to the view size.
- Standard_EXPORT void SetPixelTolerance (const Standard_Real aPrecision = 2);
+ Standard_EXPORT void SetPixelTolerance (const Standard_Integer aPrecision = 2);
//! Returns the pixel tolerance.
- Standard_EXPORT Standard_Real PixelTolerance() const;
+ Standard_EXPORT Standard_Integer PixelTolerance() const;
//! Resets the transient list of presentations previously displayed in immediate mode
//! and begins accumulation of new list by following AddToImmediateList()/Color()/Highlight() calls.
//================================================================
void MeshVS_DummySensitiveEntity::Clear()
{}
+
+//=======================================================================
+//function : HasInitLocation
+//purpose :
+//=======================================================================
+Standard_Boolean MeshVS_DummySensitiveEntity::HasInitLocation() const
+{
+ return Standard_False;
+}
+
+//=======================================================================
+//function : InvInitLocation
+//purpose :
+//=======================================================================
+inline gp_Trsf MeshVS_DummySensitiveEntity::InvInitLocation() const
+{
+ return gp_Trsf();
+}
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+ Standard_EXPORT virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE;
+
+ Standard_EXPORT virtual gp_Trsf InvInitLocation() const Standard_OVERRIDE;
+
DEFINE_STANDARD_RTTI(MeshVS_DummySensitiveEntity, SelectBasics_SensitiveEntity)
};
return 0;
}
+//=======================================================================
+//function : OCC26195
+//purpose :
+//=======================================================================
+#include <SelectMgr_SelectingVolumeManager.hxx>
+#include <BRepBuilderAPI_MakePolygon.hxx>
+#include <Geom_CartesianPoint.hxx>
+#include <AIS_Line.hxx>
+#include <Aspect_Window.hxx>
+static Standard_Integer OCC26195 (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
+{
+ if (theArgNb < 3)
+ {
+ std::cerr << "Error: wrong number of arguments! See usage:\n";
+ theDI.PrintHelp (theArgVec[0]);
+ return 1;
+ }
+
+ if (ViewerTest::GetAISContext().IsNull())
+ {
+ std::cerr << "Error: No opened context!\n";
+ return 1;
+ }
+
+ gp_Pnt2d aPxPnt1, aPxPnt2;
+ aPxPnt1.SetX (Draw::Atof (theArgVec[1]));
+ aPxPnt1.SetY (Draw::Atof (theArgVec[2]));
+ if (theArgNb > 4)
+ {
+ aPxPnt2.SetX (Draw::Atof (theArgVec[3]));
+ aPxPnt2.SetY (Draw::Atof (theArgVec[4]));
+ }
+ Standard_Boolean toPrint = Standard_False;
+ if (theArgNb % 2 == 0)
+ {
+ toPrint = Draw::Atoi (theArgVec[theArgNb - 1]);
+ }
+
+ SelectMgr_SelectingVolumeManager* aMgr = new SelectMgr_SelectingVolumeManager();
+ aMgr->SetActiveSelectionType (theArgNb > 4 ?
+ SelectMgr_SelectingVolumeManager::Box : SelectMgr_SelectingVolumeManager::Point);
+ aMgr->SetCamera (ViewerTest::CurrentView()->Camera());
+ aMgr->SetPixelTolerance (ViewerTest::GetAISContext()->PixelTolerance());
+ Standard_Integer aWidth, aHeight;
+ ViewerTest::CurrentView()->View()->Window()->Size (aWidth, aHeight);
+ aMgr->SetWindowSize (aWidth, aHeight);
+ if (theArgNb > 4)
+ {
+ aMgr->BuildSelectingVolume (aPxPnt1, aPxPnt2);
+ }
+ else
+ {
+ aMgr->BuildSelectingVolume (aPxPnt1);
+ }
+ const gp_Pnt* aVerts = aMgr->GetVertices();
+ gp_Pnt aNearPnt = aMgr->GetNearPnt();
+ gp_Pnt aFarPnt = aMgr->GetFarPnt();
+ BRepBuilderAPI_MakePolygon aWireBldrs[4];
+
+ aWireBldrs[0].Add (gp_Pnt (aVerts[0].X(), aVerts[0].Y(), aVerts[0].Z()));
+ aWireBldrs[0].Add (gp_Pnt (aVerts[4].X(), aVerts[4].Y(), aVerts[4].Z()));
+ aWireBldrs[0].Add (gp_Pnt (aVerts[6].X(), aVerts[6].Y(), aVerts[6].Z()));
+ aWireBldrs[0].Add (gp_Pnt (aVerts[2].X(), aVerts[2].Y(), aVerts[2].Z()));
+ aWireBldrs[0].Add (gp_Pnt (aVerts[0].X(), aVerts[0].Y(), aVerts[0].Z()));
+
+ aWireBldrs[1].Add (gp_Pnt (aVerts[4].X(), aVerts[4].Y(), aVerts[4].Z()));
+ aWireBldrs[1].Add (gp_Pnt (aVerts[5].X(), aVerts[5].Y(), aVerts[5].Z()));
+ aWireBldrs[1].Add (gp_Pnt (aVerts[7].X(), aVerts[7].Y(), aVerts[7].Z()));
+ aWireBldrs[1].Add (gp_Pnt (aVerts[6].X(), aVerts[6].Y(), aVerts[6].Z()));
+ aWireBldrs[1].Add (gp_Pnt (aVerts[4].X(), aVerts[4].Y(), aVerts[4].Z()));
+
+ aWireBldrs[2].Add (gp_Pnt (aVerts[1].X(), aVerts[1].Y(), aVerts[1].Z()));
+ aWireBldrs[2].Add (gp_Pnt (aVerts[5].X(), aVerts[5].Y(), aVerts[5].Z()));
+ aWireBldrs[2].Add (gp_Pnt (aVerts[7].X(), aVerts[7].Y(), aVerts[7].Z()));
+ aWireBldrs[2].Add (gp_Pnt (aVerts[3].X(), aVerts[3].Y(), aVerts[3].Z()));
+ aWireBldrs[2].Add (gp_Pnt (aVerts[1].X(), aVerts[1].Y(), aVerts[1].Z()));
+
+ aWireBldrs[3].Add (gp_Pnt (aVerts[0].X(), aVerts[0].Y(), aVerts[0].Z()));
+ aWireBldrs[3].Add (gp_Pnt (aVerts[1].X(), aVerts[1].Y(), aVerts[1].Z()));
+ aWireBldrs[3].Add (gp_Pnt (aVerts[3].X(), aVerts[3].Y(), aVerts[3].Z()));
+ aWireBldrs[3].Add (gp_Pnt (aVerts[2].X(), aVerts[2].Y(), aVerts[2].Z()));
+ aWireBldrs[3].Add (gp_Pnt (aVerts[0].X(), aVerts[0].Y(), aVerts[0].Z()));
+
+ TopoDS_Compound aComp;
+ BRep_Builder aCompBuilder;
+ aCompBuilder.MakeCompound (aComp);
+ for (Standard_Integer aWireIdx = 0; aWireIdx < 4; ++aWireIdx)
+ {
+ aCompBuilder.Add (aComp, aWireBldrs[aWireIdx].Shape());
+ }
+ DBRep::Set ("c", aComp);
+
+ Handle(AIS_InteractiveObject) aCmp = new AIS_Shape (aComp);
+ aCmp->SetColor (Quantity_NOC_GREEN);
+ ViewerTest::Display ("c", aCmp, Standard_True, Standard_True);
+
+ Handle(Geom_CartesianPoint) aPnt1 = new Geom_CartesianPoint (aNearPnt);
+ Handle(Geom_CartesianPoint) aPnt2 = new Geom_CartesianPoint (aFarPnt);
+
+ Handle(AIS_Line) aLine = new AIS_Line (aPnt1, aPnt2);
+ ViewerTest::Display ("l", aLine, Standard_True, Standard_True);
+
+ if (toPrint)
+ {
+ theDI << "Near: " << aNearPnt.X() << " " << aNearPnt.Y() << " " << aNearPnt.Z() << "\n";
+ theDI << "Far: " << aFarPnt.X() << " " << aFarPnt.Y() << " " << aFarPnt.Z() << "\n";
+ }
+
+ return 0;
+}
+
void QABugs::Commands_19(Draw_Interpretor& theCommands) {
const char *group = "QABugs";
theCommands.Add ("OCC26407", "OCC26407 result_name", __FILE__, OCC26407, group);
theCommands.Add ("OCC26485", "OCC26485 shape", __FILE__, OCC26485, group);
theCommands.Add ("OCC26553", "OCC26553 file_path", __FILE__, OCC26553, group);
+ theCommands.Add ("OCC26195",
+ "OCC26195: x1_pix y1_pix [x2_pix y2_pix] [toPrintPixelCoord 0|1]"
+ "\n\t\t: Draws rectangular selecting frustum defined by point selection in pixel coordinates"
+ "\n\t\t: [x1_pix, y1_pix] or rectangular selection in pixel coordinates [x1_pix, y1_pix,"
+ "\n\t\t: x2_pix, y2_pix]."
+ "\n\t\t: [toPrintPixelCoord 0|1] - prints 3d projection of pixel coordinate or center of"
+ "\n\t\t: selecting rectangle onto near and far view frustum planes",
+ __FILE__, OCC26195, group);
return;
}
}
Standard_Real aDepth;
- if (!theMgr.Overlaps (myBox, aDepth)) // check for overlap
+ if (!theMgr.Overlaps (myBox.CornerMin(), myBox.CornerMax(), aDepth)) // check for overlap
{
return Standard_False;
}
if (mySensType == Select3D_TOS_BOUNDARY)
{
- SetSensitivityFactor (6.0);
+ SetSensitivityFactor (6);
}
}
if (mySensType == Select3D_TOS_BOUNDARY)
{
- SetSensitivityFactor (6.0);
+ SetSensitivityFactor (6);
}
}
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
const Standard_Boolean theIsFilled)
-: Select3D_SensitivePoly (theOwnerId, thePnts3d, (Standard_Boolean )!theIsFilled),
+: Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)),
myStart (0),
myEnd (0)
{
if (mySensType == Select3D_TOS_BOUNDARY)
{
- SetSensitivityFactor (6.0);
+ SetSensitivityFactor (6);
}
}
if (mySensType == Select3D_TOS_BOUNDARY)
{
- SetSensitivityFactor (6.0);
+ SetSensitivityFactor (6);
}
}
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
{
- Standard_Real aDummy;
- if (!theMgr.Overlaps (anArrayOfPnt->Value (aPntIdx), aDummy))
+ if (!theMgr.Overlaps (anArrayOfPnt->Value (aPntIdx)))
return Standard_False;
}
return Standard_True;
myCurve (theCurve)
{
loadPoints (theCurve, theNbPnts);
- SetSensitivityFactor (3.0);
+ SetSensitivityFactor (3);
}
//==================================================
: Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True)
{
- SetSensitivityFactor (3.0);
+ SetSensitivityFactor (3);
}
//==================================================
const TColgp_Array1OfPnt& thePoints)
: Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True)
{
- SetSensitivityFactor (3.0);
+ SetSensitivityFactor (3);
}
//==================================================
//=======================================================================
//function : Select3D_SensitiveEntity
-//purpose :
+//purpose :
//=======================================================================
-
-Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& theOwnerId)
+Select3D_SensitiveEntity::Select3D_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId)
: SelectBasics_SensitiveEntity (theOwnerId) {}
//=======================================================================
{
Set (NULL);
}
+
+//=======================================================================
+// function : HasInitLocation
+// purpose : Returns true if the shape corresponding to the entity has init location
+//=======================================================================
+Standard_Boolean Select3D_SensitiveEntity::HasInitLocation() const
+{
+ return Standard_False;
+}
+
+//=======================================================================
+// function : InvInitLocation
+// purpose : Returns inversed location transformation matrix if the shape corresponding
+// to this entity has init location set. Otherwise, returns identity matrix.
+//=======================================================================
+gp_Trsf Select3D_SensitiveEntity::InvInitLocation() const
+{
+ return gp_Trsf();
+}
//! Clears up all resources and memory
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+ //! Returns true if the shape corresponding to the entity has init location
+ Standard_EXPORT virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE;
+
+ //! Returns inversed location transformation matrix if the shape corresponding
+ //! to this entity has init location set. Otherwise, returns identity matrix.
+ Standard_EXPORT virtual gp_Trsf InvInitLocation() const;
+
DEFINE_STANDARD_RTTI(Select3D_SensitiveEntity, SelectBasics_SensitiveEntity)
protected:
const gp_Pnt& thePoint)
: Select3D_SensitiveEntity (theOwner)
{
- SetSensitivityFactor (12.0);
+ SetSensitivityFactor (12);
myPoint = thePoint;
}
{
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
- Standard_Real aDummy;
- return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0), aDummy)
- && theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1), aDummy);
+ return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0))
+ && theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1));
}
//==================================================
Standard_Real aDistToCOG = RealLast();
if (!theMgr.IsOverlapAllowed())
{
- Standard_Real aDummy;
- return theMgr.Overlaps (myPoints[0], aDummy)
- && theMgr.Overlaps (myPoints[1], aDummy)
- && theMgr.Overlaps (myPoints[2], aDummy);
+ return theMgr.Overlaps (myPoints[0])
+ && theMgr.Overlaps (myPoints[1])
+ && theMgr.Overlaps (myPoints[2]);
}
if (!theMgr.Overlaps (myPoints[0], myPoints[1], myPoints[2], mySensType, aDepth))
myInitLocation (theInitLoc),
myDetectedTr (-1)
{
+ myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& aNodes = myTriangul->Nodes();
myFreeEdges (theFreeEdges),
myDetectedTr (-1)
{
+ myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
myPrimitivesNb = theIsInterior ? theTrg->Triangles().Length() : theFreeEdges->Length() / 2;
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
Standard_Integer aPrimIdx = myBVHPrimIndexes->Value (theIdx);
SelectMgr_Vec3 aMinPnt (RealLast());
SelectMgr_Vec3 aMaxPnt (RealFirst());
- Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_INTERIOR)
{
Standard_Integer aNode1, aNode2, aNode3;
myTriangul->Triangles() (aPrimIdx + 1).Get (aNode1, aNode2, aNode3);
- gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNode1);
- gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNode2);
- gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNode3);
+ gp_Pnt aPnt1 = myTriangul->Nodes().Value (aNode1);
+ gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
+ gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())),
Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())),
{
Standard_Integer aNodeIdx1 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx);
Standard_Integer aNodeIdx2 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx + 1);
- gp_Pnt aNode1 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx1).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNodeIdx1);
- gp_Pnt aNode2 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx2).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNodeIdx2);
+ gp_Pnt aNode1 = myTriangul->Nodes().Value (aNodeIdx1);
+ gp_Pnt aNode2 = myTriangul->Nodes().Value (aNodeIdx2);
aMinPnt = SelectMgr_Vec3 (Min (aNode1.X(), aNode2.X()),
Min (aNode1.Y(), aNode2.Y()),
Standard_Real& theMatchDepth)
{
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
- Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_BOUNDARY)
{
Standard_Integer aSegmStartIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 1);
Standard_Integer aSegmEndIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 2);
Handle(TColgp_HArray1OfPnt) anEdgePnts = new TColgp_HArray1OfPnt (1, 2);
- gp_Pnt aSegmStart = hasInitLoc ? myTriangul->Nodes().Value (aSegmStartIdx).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aSegmStartIdx);
- gp_Pnt aSegmEnd = hasInitLoc ? myTriangul->Nodes().Value (aSegmEndIdx).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aSegmEndIdx);
+ gp_Pnt aSegmStart = myTriangul->Nodes().Value (aSegmStartIdx);
+ gp_Pnt aSegmEnd = myTriangul->Nodes().Value (aSegmEndIdx);
anEdgePnts->SetValue (1, aSegmStart);
anEdgePnts->SetValue (2, aSegmEnd);
Standard_Boolean isMatched = theMgr.Overlaps (anEdgePnts, Select3D_TOS_BOUNDARY, theMatchDepth);
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
Standard_Integer aNode1, aNode2, aNode3;
aTriangles (aPrimitiveIdx + 1).Get (aNode1, aNode2, aNode3);
- gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNode1);
- gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNode2);
- gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
- : myTriangul->Nodes().Value (aNode3);
+ gp_Pnt aPnt1 = myTriangul->Nodes().Value (aNode1);
+ gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
+ gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, Select3D_TOS_INTERIOR, theMatchDepth);
}
}
Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
const Standard_Integer theElemIdx)
{
- Standard_Real aDummy;
-
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
if (mySensType == Select3D_TOS_BOUNDARY)
gp_Pnt aSegmPnt1 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 1));
gp_Pnt aSegmPnt2 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 2));
- if (HasInitLocation()) // Note: Should be removed (by transforming frustum)
- {
- aSegmPnt1.Transform (myInitLocation.Transformation());
- aSegmPnt2.Transform (myInitLocation.Transformation());
- }
-
- return theMgr.Overlaps (aSegmPnt1, aDummy) && theMgr.Overlaps (aSegmPnt2, aDummy);
+ return theMgr.Overlaps (aSegmPnt1) && theMgr.Overlaps (aSegmPnt2);
}
else
{
gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
- if (HasInitLocation()) // Note: Should be removed (by transforming frustum)
- {
- aPnt1.Transform (myInitLocation.Transformation());
- aPnt2.Transform (myInitLocation.Transformation());
- aPnt3.Transform (myInitLocation.Transformation());
- }
-
- return theMgr.Overlaps (aPnt1, aDummy)
- && theMgr.Overlaps (aPnt2, aDummy)
- && theMgr.Overlaps (aPnt3, aDummy);
+ return theMgr.Overlaps (aPnt1)
+ && theMgr.Overlaps (aPnt2)
+ && theMgr.Overlaps (aPnt3);
}
}
gp_Pnt aVertex = gp_Pnt (aX == 0 ? myBndBox.CornerMin().x() : myBndBox.CornerMax().x(),
aY == 0 ? myBndBox.CornerMin().y() : myBndBox.CornerMax().y(),
aZ == 0 ? myBndBox.CornerMin().z() : myBndBox.CornerMax().z());
- aVertex.Transform (myInitLocation);
+ aVertex.Transform (myInitLocation.Transformation());
aBndBox.Add (Select3D_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
}
}
//=======================================================================
gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const
{
- return HasInitLocation() ? myCDG3D.Transformed (myInitLocation) : myCDG3D;
+ return myCDG3D;
}
//=======================================================================
Standard_Integer Select3D_SensitiveTriangulation::NbSubElements()
{
return myTriangul->Nodes().Length();
-}
\ No newline at end of file
+}
+
+//=======================================================================
+//function : HasInitLocation
+//purpose :
+//=======================================================================
+Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
+{
+ return !myInitLocation.IsIdentity();
+}
+
+//=======================================================================
+//function : InvInitLocation
+//purpose :
+//=======================================================================
+gp_Trsf Select3D_SensitiveTriangulation::InvInitLocation() const
+{
+ return myInvInitLocation;
+}
const Handle(Poly_Triangulation)& Triangulation() const;
- Standard_Boolean HasInitLocation() const;
-
- const TopLoc_Location& GetInitLocation() const;
-
//! Returns the length of array of triangles or edges
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
+ //! Returns true if the shape corresponding to the entity has init location
+ Standard_EXPORT virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE;
+
+ //! Returns inversed location transformation matrix if the shape corresponding
+ //! to this entity has init location set. Otherwise, returns identity matrix.
+ Standard_EXPORT virtual gp_Trsf InvInitLocation() const Standard_OVERRIDE;
+
+ inline const TopLoc_Location& GetInitLocation() const;
+
public:
DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
const Standard_Integer theElemIdx) Standard_OVERRIDE;
-public:
- Standard_Real myBVHBuildTime;
-
private:
Handle(Poly_Triangulation) myTriangul;
- TopLoc_Location myInitLocation;
- gp_Pnt myCDG3D; //!< Center of the whole triangulation
+ TopLoc_Location myInitLocation;
+ gp_Pnt myCDG3D; //!< Center of the whole triangulation
Handle(TColStd_HArray1OfInteger) myFreeEdges;
- Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior
- Standard_Integer myDetectedTr;
- Standard_Integer myPrimitivesNb; //!< Amount of free edges or triangles depending on sensitivity type
+ Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior
+ Standard_Integer myDetectedTr;
+ Standard_Integer myPrimitivesNb; //!< Amount of free edges or triangles depending on sensitivity type
Handle(TColStd_HArray1OfInteger) myBVHPrimIndexes; //!< Indexes of edges or triangles for BVH build
- mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
+ mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
+ gp_Trsf myInvInitLocation;
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
return myTriangul;
}
-//=======================================================================
-//function : HasInitLocation
-//purpose :
-//=======================================================================
-inline Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
-{
- return !myInitLocation.IsIdentity();
-}
-
//=======================================================================
//function : GetInitLocation
//purpose :
#define _SelectBasics_SelectingVolumeManager_HeaderFile
#include <BVH_Box.hxx>
+#include <gp_Pnt.hxx>
#include <TColgp_HArray1OfPnt.hxx>
-#include <NCollection_Vec3.hxx>
class Bnd_Box;
class gp_Pnt;
virtual Standard_Integer GetActiveSelectionType() const = 0;
//! Returns true if selecting volume is overlapped by box theBox
- virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
+ virtual Standard_Boolean Overlaps (const NCollection_Vec3<Standard_Real>& theBoxMin,
+ const NCollection_Vec3<Standard_Real>& theBoxMax,
Standard_Real& theDepth) = 0;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box with minimum
const NCollection_Vec3<Standard_Real>& theBoxMax,
Standard_Boolean* theInside = NULL) = 0;
- //! Returns true if selecting volume is overlapped by point thePt
- virtual Standard_Boolean Overlaps (const gp_Pnt& thePt,
+ //! Returns true if selecting volume is overlapped by point thePnt
+ virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth) = 0;
+ //! Returns true if selecting volume is overlapped by point thePnt.
+ //! Does not perform depth calculation, so this method is defined as
+ //! helper function for inclusion test.
+ virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt) = 0;
+
//! Returns true if selecting volume is overlapped by planar convex polygon, which points
//! are stored in theArrayOfPts, taking into account sensitivity type theSensType
virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
//! to the given point theCOG
virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) = 0;
- virtual NCollection_Vec3<Standard_Real> DetectedPoint (const Standard_Real theDepth) const = 0;
+ virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const = 0;
virtual Standard_Boolean IsOverlapAllowed() const = 0;
// function : SelectBasics_SensitiveEntity
// purpose : Creates new empty sensitive entity instance
//=======================================================================
-SelectBasics_SensitiveEntity::SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId,
- const Standard_Real theSensFactor)
+SelectBasics_SensitiveEntity::SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId)
: myOwnerId (theOwnerId),
- mySFactor (theSensFactor) {}
+ mySFactor (2) {}
//=======================================================================
// function : Set
#ifndef _SelectBasics_SensitiveEntity_HeaderFile
#define _SelectBasics_SensitiveEntity_HeaderFile
+#include <gp_Trsf.hxx>
+
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <SelectBasics_PickResult.hxx>
#include <Standard_Integer.hxx>
#include <Select3D_BndBox3d.hxx>
+
class SelectBasics_EntityOwner;
//! Checks whether the sensitive entity is overlapped by
//! current selecting volume
- Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, SelectBasics_PickResult& thePickResult) = 0;
+ virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr, SelectBasics_PickResult& thePickResult) = 0;
//! allows a better sensitivity for
//! a specific entity in selection algorithms
//! useful for small sized entities.
- Standard_EXPORT Standard_Real SensitivityFactor() const;
+ Standard_EXPORT Standard_Integer SensitivityFactor() const;
//! Returns the number of sub-entities or elements in
//! sensitive entity. Is used to determine if entity is
//! complex and needs to pre-build BVH at the creation of
//! sensitive entity step or is light-weighted so the tree
//! can be build on demand with unnoticeable delay
- Standard_EXPORT virtual Standard_Integer NbSubElements() = 0;
+ virtual Standard_Integer NbSubElements() = 0;
//! Returns bounding box of sensitive entity
- Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() = 0;
+ virtual Select3D_BndBox3d BoundingBox() = 0;
//! Builds BVH tree for sensitive if it is needed
- Standard_EXPORT virtual void BVH() = 0;
+ virtual void BVH() = 0;
//! Clears up all the resources and memory allocated
- Standard_EXPORT virtual void Clear() = 0;
-
+ virtual void Clear() = 0;
+ //! Returns true if the shape corresponding to the entity has init location
+ virtual Standard_Boolean HasInitLocation() const = 0;
+ //! Returns inversed location transformation matrix if the shape corresponding
+ //! to this entity has init location set. Otherwise, returns identity matrix.
+ virtual gp_Trsf InvInitLocation() const = 0;
DEFINE_STANDARD_RTTI(SelectBasics_SensitiveEntity,MMgt_TShared)
protected:
-
- Standard_EXPORT SelectBasics_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& theOwnerId, const Standard_Real theSensFactor = 2.0);
-
+ Standard_EXPORT SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId);
+
//! Allows to manage the sensitivity of the entity
- void SetSensitivityFactor (const Standard_Real theSensFactor);
+ void SetSensitivityFactor (const Standard_Integer theSensFactor);
Handle(SelectBasics_EntityOwner) myOwnerId;
private:
-
- Standard_Real mySFactor;
-
-
+ Standard_Integer mySFactor;
};
// function : SetSensitivityFactor
// purpose : Allows to manage the sensitivity of the entity
//=======================================================================
-inline void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Real theSensFactor)
+inline void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Integer theSensFactor)
{
mySFactor = theSensFactor;
}
// function : SensitivityFactor
// purpose : Gets sensitivity factor for the entity
//=======================================================================
-inline Standard_Real SelectBasics_SensitiveEntity::SensitivityFactor() const
+inline Standard_Integer SelectBasics_SensitiveEntity::SensitivityFactor() const
{
return mySFactor;
}
// function : SetPixelTolerance
// purpose :
//=======================================================================
-void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Real theTol)
+void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Integer theTol)
{
myPixelTolerance = theTol;
}
// purpose : SAT intersection test between defined volume and
// given axis-aligned box
//=======================================================================
-Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const BVH_Box<Standard_Real, 3>& /*theBndBox*/,
+Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const SelectMgr_Vec3& /*theBoxMin*/,
+ const SelectMgr_Vec3& /*theBoxMax*/,
Standard_Real& /*theDepth*/)
{
return Standard_False;
// function : Overlaps
// purpose : Intersection test between defined volume and given point
//=======================================================================
-Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt*/,
+Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt*/,
Standard_Real& /*theDepth*/)
{
return Standard_False;
}
+//=======================================================================
+// function : Overlaps
+// purpose : Intersection test between defined volume and given point
+//=======================================================================
+Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt*/)
+{
+ return Standard_False;
+}
+
//=======================================================================
// function : Overlaps
// purpose : SAT intersection test between defined volume and given
// may be considered of interior part or boundary line defined
// by segments depending on given sensitivity type
//=======================================================================
-Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& /*theArrayOfPts*/,
+Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const Handle(TColgp_HArray1OfPnt)& /*theArrayOfPnts*/,
Select3D_TypeOfSensitivity /*theSensType*/,
Standard_Real& /*theDepth*/)
{
// function : Overlaps
// purpose : Checks if line segment overlaps selecting volume
//=======================================================================
-Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt1*/,
- const gp_Pnt& /*thePt2*/,
+Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt1*/,
+ const gp_Pnt& /*thePnt2*/,
Standard_Real& /*theDepth*/)
{
return Standard_False;
return DBL_MAX;
}
-SelectMgr_Vec3 SelectMgr_BaseFrustum::DetectedPoint (const Standard_Real /*theDepth*/) const
+gp_Pnt SelectMgr_BaseFrustum::DetectedPoint (const Standard_Real /*theDepth*/) const
{
- return SelectMgr_Vec3 (RealLast());
+ return gp_Pnt (RealLast(), RealLast(), RealLast());
}
//=======================================================================
#ifndef _SelectMgr_BaseFrustum_HeaderFile
#define _SelectMgr_BaseFrustum_HeaderFile
-#include <Bnd_Box.hxx>
-
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
//! @return current camera world view projection transformation state
Standard_EXPORT const Graphic3d_WorldViewProjState& WorldViewProjState() const;
- Standard_EXPORT void SetPixelTolerance (const Standard_Real theTol);
+ Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTol);
Standard_EXPORT void SetWindowSize (const Standard_Integer theWidth,
const Standard_Integer theHeight);
//! Builds selecting volumes set according to polyline points
virtual void Build (const TColgp_Array1OfPnt2d& /*thePoints*/) {}
- virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& /*theTrsf*/) { return NULL; }
-
- //! IMPORTANT: Makes sense only for frustum built on a single point!
+ //! IMPORTANT: Scaling makes sense only for frustum built on a single point!
+ //! Note that this method does not perform any checks on type of the frustum.
//! Returns a copy of the frustum resized according to the scale factor given
- virtual NCollection_Handle<SelectMgr_BaseFrustum> Scale (const Standard_Real /*theScaleFactor*/) { return NULL; }
+ //! and transforms it using the matrix given.
+ //! There are no default parameters, but in case if:
+ //! - transformation only is needed: @theScaleFactor must be initialized as any negative value;
+ //! - scale only is needed: @theTrsf must be set to gp_Identity.
+ Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer /*theScaleFactor*/,
+ const gp_Trsf& /*theTrsf*/) { return NULL; }
//! SAT intersection test between defined volume and given axis-aligned box
- Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
+ const SelectMgr_Vec3& theBoxMax,
Standard_Real& theDepth);
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
Standard_Boolean* theInside = NULL);
//! Intersection test between defined volume and given point
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth);
+ //! Intersection test between defined volume and given point
+ //! Does not perform depth calculation, so this method is defined as
+ //! helper function for inclusion test. Therefore, its implementation
+ //! makes sense only for rectangular frustum with box selection mode activated.
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt);
+
//! SAT intersection test between defined volume and given ordered set of points,
//! representing line segments. The test may be considered of interior part or
//! boundary line defined by segments depending on given sensitivity type
- Standard_EXPORT virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
Select3D_TypeOfSensitivity theSensType,
Standard_Real& theDepth);
//! Checks if line segment overlaps selecting frustum
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
- const gp_Pnt& thePt2,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
+ const gp_Pnt& thePnt2,
Standard_Real& theDepth);
//! SAT intersection test between defined volume and given triangle. The test may
//! screen point and given point theCOG
Standard_EXPORT virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG);
- Standard_EXPORT virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const;
+ Standard_EXPORT virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const;
//! Checks if the point of sensitive in which selection was detected belongs
//! to the region defined by clipping planes
DEFINE_STANDARD_RTTI(SelectMgr_BaseFrustum, Standard_Transient)
protected:
- Standard_Real myPixelTolerance; //!< Pixel tolerance
- Standard_Boolean myIsOrthographic; //!< Defines if current camera is orthographic
+ Standard_Integer myPixelTolerance; //!< Pixel tolerance
+ Standard_Boolean myIsOrthographic; //!< Defines if current camera is orthographic
Handle(SelectMgr_FrustumBuilder) myBuilder; //!< A tool implementing methods for volume build
};
#include <BVH_Box.hxx>
#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XYZ.hxx>
#include <SelectMgr_BaseFrustum.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
//! SAT intersection test between frustum given and planar convex polygon represented as ordered point set
Standard_EXPORT Standard_Boolean hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
- SelectMgr_Vec3& theNormal);
+ gp_Vec& theNormal);
//! SAT intersection test between defined volume and given triangle
Standard_EXPORT Standard_Boolean hasOverlap (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3,
- SelectMgr_Vec3& theNormal);
+ gp_Vec& theNormal);
private:
//! Checks if AABB and frustum are separated along the given axis
Standard_Boolean isSeparated (const SelectMgr_Vec3& theBoxMin,
const SelectMgr_Vec3& theBoxMax,
- const SelectMgr_Vec3& theDirect,
+ const gp_XYZ& theDirect,
Standard_Boolean* theInside) const;
//! Checks if triangle and frustum are separated along the given axis
Standard_Boolean isSeparated (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3,
- const SelectMgr_Vec3& theAxis) const;
+ const gp_XYZ& theAxis) const;
protected:
- SelectMgr_Vec3 myPlanes[N + 2]; //!< Plane equations
- SelectMgr_Vec3 myVertices[N * 2]; //!< Vertices coordinates
+ gp_Vec myPlanes[N + 2]; //!< Plane equations
+ gp_Pnt myVertices[N * 2]; //!< Vertices coordinates
Standard_Real myMaxVertsProjections[N + 2]; //!< Cached projections of vertices onto frustum plane directions
Standard_Real myMinVertsProjections[N + 2]; //!< Cached projections of vertices onto frustum plane directions
Standard_Real myMaxOrthoVertsProjections[3]; //!< Cached projections of vertices onto directions of ortho unit vectors
Standard_Real myMinOrthoVertsProjections[3]; //!< Cached projections of vertices onto directions of ortho unit vectors
- SelectMgr_Vec3 myEdgeDirs[6]; //!< Cached edge directions
+ gp_Vec myEdgeDirs[6]; //!< Cached edge directions
};
#include <SelectMgr_Frustum.lxx>
#include <Poly_Array1OfTriangle.hxx>
#include <Standard_Assert.hxx>
-#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z())
-#define DOTp(A, B) (A.x() * B.X() + A.y() * B.Y() + A.z() * B.Z())
-
// =======================================================================
// function : isSeparated
// purpose : Checks if AABB and frustum are separated along the given axis.
template <int N>
Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const SelectMgr_Vec3& theBoxMin,
const SelectMgr_Vec3& theBoxMax,
- const SelectMgr_Vec3& theDirect,
+ const gp_XYZ& theDirect,
Standard_Boolean* theInside) const
{
const Standard_Real aMinB =
- theDirect.x() * (theDirect.x() < 0.0 ? theBoxMax.x() : theBoxMin.x()) +
- theDirect.y() * (theDirect.y() < 0.0 ? theBoxMax.y() : theBoxMin.y()) +
- theDirect.z() * (theDirect.z() < 0.0 ? theBoxMax.z() : theBoxMin.z());
+ theDirect.X() * (theDirect.X() < 0.0 ? theBoxMax.x() : theBoxMin.x()) +
+ theDirect.Y() * (theDirect.Y() < 0.0 ? theBoxMax.y() : theBoxMin.y()) +
+ theDirect.Z() * (theDirect.Z() < 0.0 ? theBoxMax.z() : theBoxMin.z());
const Standard_Real aMaxB =
- theDirect.x() * (theDirect.x() < 0.0 ? theBoxMin.x() : theBoxMax.x()) +
- theDirect.y() * (theDirect.y() < 0.0 ? theBoxMin.y() : theBoxMax.y()) +
- theDirect.z() * (theDirect.z() < 0.0 ? theBoxMin.z() : theBoxMax.z());
+ theDirect.X() * (theDirect.X() < 0.0 ? theBoxMin.x() : theBoxMax.x()) +
+ theDirect.Y() * (theDirect.Y() < 0.0 ? theBoxMin.y() : theBoxMax.y()) +
+ theDirect.Z() * (theDirect.Z() < 0.0 ? theBoxMin.z() : theBoxMax.z());
Standard_ASSERT_RAISE (aMaxB >= aMinB, "Error! Failed to project box");
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
{
- const Standard_Real aProj = DOT (myVertices[aVertIdx], theDirect);
+ const Standard_Real aProj = myVertices[aVertIdx].XYZ().Dot (theDirect);
aMinF = Min (aMinF, aProj);
aMaxF = Max (aMaxF, aProj);
Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3,
- const SelectMgr_Vec3& theAxis) const
+ const gp_XYZ& theAxis) const
{
// frustum projection
Standard_Real aMinF = RealLast();
Standard_Real aTriangleProj;
- aTriangleProj = DOTp (theAxis, thePnt1);
+ aTriangleProj = theAxis.Dot (thePnt1.XYZ());
aMinTr = Min (aMinTr, aTriangleProj);
aMaxTr = Max (aMaxTr, aTriangleProj);
- aTriangleProj = DOTp (theAxis, thePnt2);
+ aTriangleProj = theAxis.Dot (thePnt2.XYZ());
aMinTr = Min (aMinTr, aTriangleProj);
aMaxTr = Max (aMaxTr, aTriangleProj);
- aTriangleProj = DOTp (theAxis, thePnt3);
+ aTriangleProj = theAxis.Dot (thePnt3.XYZ());
aMinTr = Min (aMinTr, aTriangleProj);
aMaxTr = Max (aMaxTr, aTriangleProj);
for (Standard_Integer aVertIter = 0; aVertIter < N * 2; ++aVertIter)
{
- const Standard_Real aProj = DOT (myVertices[aVertIter], theAxis);
+ const Standard_Real aProj = myVertices[aVertIter].XYZ().Dot (theAxis);
aMinF = Min (aMinF, aProj);
aMaxF = Max (aMaxF, aProj);
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
{
- SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
+ const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
const Standard_Real aBoxProjMin =
- aPlane.x() * (aPlane.x() < 0.f ? theMaxPnt.x() : theMinPnt.x()) +
- aPlane.y() * (aPlane.y() < 0.f ? theMaxPnt.y() : theMinPnt.y()) +
- aPlane.z() * (aPlane.z() < 0.f ? theMaxPnt.z() : theMinPnt.z());
+ aPlane.X() * (aPlane.X() < 0.f ? theMaxPnt.x() : theMinPnt.x()) +
+ aPlane.Y() * (aPlane.Y() < 0.f ? theMaxPnt.y() : theMinPnt.y()) +
+ aPlane.Z() * (aPlane.Z() < 0.f ? theMaxPnt.z() : theMinPnt.z());
const Standard_Real aBoxProjMax =
- aPlane.x() * (aPlane.x() < 0.f ? theMinPnt.x() : theMaxPnt.x()) +
- aPlane.y() * (aPlane.y() < 0.f ? theMinPnt.y() : theMaxPnt.y()) +
- aPlane.z() * (aPlane.z() < 0.f ? theMinPnt.z() : theMaxPnt.z());
+ aPlane.X() * (aPlane.X() < 0.f ? theMinPnt.x() : theMaxPnt.x()) +
+ aPlane.Y() * (aPlane.Y() < 0.f ? theMinPnt.y() : theMaxPnt.y()) +
+ aPlane.Z() * (aPlane.Z() < 0.f ? theMinPnt.z() : theMaxPnt.z());
Standard_ASSERT_RAISE (aBoxProjMax >= aBoxProjMin, "Error! Failed to project box");
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
{
- SelectMgr_Vec3 anEdge1 (aDim == 0, aDim == 1, aDim == 2);
-
+ // the following code performs a speedup of cross-product
+ // of vector with 1.0 at the position aDim and myEdgeDirs[aVolDir]
+ const Standard_Integer aNext = (aDim + 1) % 3;
+ const Standard_Integer aNextNext = (aDim + 2) % 3;
for (Standard_Integer aVolDir = 0, aDirectionsNb = myIsOrthographic ? 4 : 6; aVolDir < aDirectionsNb; ++aVolDir)
{
- SelectMgr_Vec3 aDirection (anEdge1.y() * myEdgeDirs[aVolDir].z() - anEdge1.z() * myEdgeDirs[aVolDir].y(),
- anEdge1.z() * myEdgeDirs[aVolDir].x() - anEdge1.x() * myEdgeDirs[aVolDir].z(),
- anEdge1.x() * myEdgeDirs[aVolDir].y() - anEdge1.y() * myEdgeDirs[aVolDir].x());
+ gp_XYZ aDirection (DBL_MAX, DBL_MAX, DBL_MAX);
+ aDirection.ChangeData()[aDim] = 0;
+ aDirection.ChangeData()[aNext] = -myEdgeDirs[aVolDir].XYZ().GetData()[aNextNext];
+ aDirection.ChangeData()[aNextNext] = myEdgeDirs[aVolDir].XYZ().GetData()[aNext];
if (isSeparated (theMinPnt, theMaxPnt, aDirection, theInside))
{
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
{
- const Select3D_Vec3& aPlane = myPlanes[aPlaneIdx];
-
- const Standard_Real aPointProj = aPlane.x() * thePnt.X() +
- aPlane.y() * thePnt.Y() +
- aPlane.z() * thePnt.Z();
+ const Standard_Real aPointProj = myPlanes[aPlaneIdx].XYZ().Dot (thePnt.XYZ());
if (aPointProj > myMaxVertsProjections[aPlaneIdx]
|| aPointProj < myMinVertsProjections[aPlaneIdx])
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
const gp_Pnt& theEndPnt)
{
- const SelectMgr_Vec3& aDir = SelectMgr_Vec3 (theEndPnt.X() - theStartPnt.X(),
- theEndPnt.Y() - theStartPnt.Y(),
- theEndPnt.Z() - theStartPnt.Z());
- if (std::sqrt (aDir.x() * aDir.x() + aDir.y() * aDir.y() + aDir.z () * aDir.z()) < Precision::Confusion())
+ const gp_XYZ& aDir = theEndPnt.XYZ() - theStartPnt.XYZ();
+ if (aDir.Modulus() < Precision::Confusion())
return Standard_True;
const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
{
Standard_Real aMinSegm = RealLast(), aMaxSegm = RealFirst();
Standard_Real aMinF = RealLast(), aMaxF = RealFirst();
- SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
- Standard_Real aProj1 = DOTp (aPlane, theStartPnt);
- Standard_Real aProj2 = DOTp (aPlane, theEndPnt);
+ Standard_Real aProj1 = myPlanes[aPlaneIdx].XYZ().Dot (theStartPnt.XYZ());
+ Standard_Real aProj2 = myPlanes[aPlaneIdx].XYZ().Dot (theEndPnt.XYZ());
aMinSegm = Min (aProj1, aProj2);
aMaxSegm = Max (aProj1, aProj2);
Standard_Real aMin2 = DBL_MAX, aMax2 = -DBL_MAX;
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
{
- Standard_Real aProjection = DOT (aDir, myVertices[aVertIdx]);
+ Standard_Real aProjection = aDir.Dot (myVertices[aVertIdx].XYZ());
aMax2 = Max (aMax2, aProjection);
aMin2 = Min (aMin2, aProjection);
}
- Standard_Real aProj1 = DOTp (aDir, theStartPnt);
- Standard_Real aProj2 = DOTp (aDir, theEndPnt);
+ Standard_Real aProj1 = aDir.Dot (theStartPnt.XYZ());
+ Standard_Real aProj2 = aDir.Dot (theEndPnt.XYZ());
aMin1 = Min (aProj1, aProj2);
aMax1 = Max (aProj1, aProj2);
if (aMin1 > aMax2
Standard_Real aMinSegm = DBL_MAX, aMaxSegm = -DBL_MAX;
Standard_Real aMinF = DBL_MAX, aMaxF = -DBL_MAX;
- SelectMgr_Vec3 aTestDir = SelectMgr_Vec3 (aDir.y() * myEdgeDirs[aEdgeDirIdx].z() - aDir.z() * myEdgeDirs[aEdgeDirIdx].y(),
- aDir.z() * myEdgeDirs[aEdgeDirIdx].x() - aDir.x() * myEdgeDirs[aEdgeDirIdx].z(),
- aDir.x() * myEdgeDirs[aEdgeDirIdx].y() - aDir.y() * myEdgeDirs[aEdgeDirIdx].x());
+ const gp_XYZ aTestDir = aDir.Crossed (myEdgeDirs[aEdgeDirIdx].XYZ());
- Standard_Real Proj1 = DOTp (aTestDir, theStartPnt);
- Standard_Real Proj2 = DOTp (aTestDir, theEndPnt);
+ Standard_Real Proj1 = aTestDir.Dot (theStartPnt.XYZ());
+ Standard_Real Proj2 = aTestDir.Dot (theEndPnt.XYZ());
aMinSegm = Min (Proj1, Proj2);
aMaxSegm = Max (Proj1, Proj2);
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
{
- Standard_Real aProjection = DOT (aTestDir, myVertices[aVertIdx]);
+ Standard_Real aProjection = aTestDir.Dot (myVertices[aVertIdx].XYZ());
aMaxF = Max (aMaxF, aProjection);
aMinF = Min (aMinF, aProjection);
}
// =======================================================================
template <int N>
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
- SelectMgr_Vec3& theNormal)
+ gp_Vec& theNormal)
{
Standard_Integer aStartIdx = theArrayOfPnts->Lower();
Standard_Integer anEndIdx = theArrayOfPnts->Upper();
- const gp_Pnt& aPnt1 = theArrayOfPnts->Value (aStartIdx);
- const gp_Pnt& aPnt2 = theArrayOfPnts->Value (aStartIdx + 1);
- const gp_Pnt& aPnt3 = theArrayOfPnts->Value (aStartIdx + 2);
- const gp_XYZ aVec1 = aPnt1.XYZ() - aPnt2.XYZ();
- const gp_XYZ aVec2 = aPnt3.XYZ() - aPnt2.XYZ();
- theNormal = SelectMgr_Vec3 (aVec2.Y() * aVec1.Z() - aVec2.Z() * aVec1.Y(),
- aVec2.Z() * aVec1.X() - aVec2.X() * aVec1.Z(),
- aVec2.X() * aVec1.Y() - aVec2.Y() * aVec1.X());
- Standard_Real aPolygProjection = DOTp (theNormal, aPnt1);
+ const gp_XYZ& aPnt1 = theArrayOfPnts->Value (aStartIdx).XYZ();
+ const gp_XYZ& aPnt2 = theArrayOfPnts->Value (aStartIdx + 1).XYZ();
+ const gp_XYZ& aPnt3 = theArrayOfPnts->Value (aStartIdx + 2).XYZ();
+ const gp_XYZ aVec1 = aPnt1 - aPnt2;
+ const gp_XYZ aVec2 = aPnt3 - aPnt2;
+ theNormal = aVec2.Crossed (aVec1);
+ const gp_XYZ& aNormal = theNormal.XYZ();
+ Standard_Real aPolygProjection = aNormal.Dot (aPnt1);
Standard_Real aMax = RealFirst();
Standard_Real aMin = RealLast();
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
{
- Standard_Real aProjection = DOT (theNormal, myVertices[aVertIdx]);
+ Standard_Real aProjection = aNormal.Dot (myVertices[aVertIdx].XYZ());
aMax = Max (aMax, aProjection);
aMin = Min (aMin, aProjection);
}
return Standard_False;
}
- Standard_Integer aPlanesNb = N == 4 ? N + 2 : N + 1;
- for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < aPlanesNb; ++aPlaneIdx)
+ const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
+ for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
{
Standard_Real aMaxF = RealFirst();
Standard_Real aMinF = RealLast();
Standard_Real aMaxPolyg = RealFirst();
Standard_Real aMinPolyg = RealLast();
- SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
+ const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter)
{
- Standard_Real aProjection = DOTp (aPlane, theArrayOfPnts->Value (aPntIter));
+ Standard_Real aProjection = aPlane.Dot (theArrayOfPnts->Value (aPntIter).XYZ());
aMaxPolyg = Max (aMaxPolyg, aProjection);
aMinPolyg = Min (aMinPolyg, aProjection);
}
}
Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6;
- for (Standard_Integer aPntsIter = aStartIdx; aPntsIter <= anEndIdx; ++aPntsIter)
+ for (Standard_Integer aPntsIter = 0, aLastIdx = anEndIdx - aStartIdx, aLen = theArrayOfPnts->Length(); aPntsIter <= aLastIdx; ++aPntsIter)
{
- const gp_XYZ aSegmDir = aPntsIter == anEndIdx ? theArrayOfPnts->Value (aStartIdx).XYZ() - theArrayOfPnts->Value (anEndIdx).XYZ()
- : theArrayOfPnts->Value (aPntsIter + 1).XYZ() - theArrayOfPnts->Value (aPntsIter).XYZ();
+ const gp_XYZ aSegmDir = theArrayOfPnts->Value ((aPntsIter + 1) % aLen + aStartIdx).XYZ()
+ - theArrayOfPnts->Value (aPntsIter + aStartIdx).XYZ();
for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir)
{
Standard_Real aMaxPolyg = RealFirst();
Standard_Real aMinPolyg = RealLast();
Standard_Real aMaxF = RealFirst();
Standard_Real aMinF = RealLast();
- SelectMgr_Vec3 aTestDir = SelectMgr_Vec3 (aSegmDir.Y() * myEdgeDirs[aVolDir].z() - aSegmDir.Z() * myEdgeDirs[aVolDir].y(),
- aSegmDir.Z() * myEdgeDirs[aVolDir].x() - aSegmDir.X() * myEdgeDirs[aVolDir].z(),
- aSegmDir.X() * myEdgeDirs[aVolDir].y() - aSegmDir.Y() * myEdgeDirs[aVolDir].x());
+ const gp_XYZ aTestDir = aSegmDir.Crossed (myEdgeDirs[aVolDir].XYZ());
for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter)
{
- Standard_Real aProjection = DOTp (aTestDir, theArrayOfPnts->Value (aPntIter));
+ Standard_Real aProjection = aTestDir.Dot (theArrayOfPnts->Value (aPntIter).XYZ());
aMaxPolyg = Max (aMaxPolyg, aProjection);
aMinPolyg = Min (aMinPolyg, aProjection);
}
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx)
{
- Standard_Real aProjection = DOT (aTestDir, myVertices[aVertIdx]);
+ Standard_Real aProjection = aTestDir.Dot (myVertices[aVertIdx].XYZ());
aMaxF = Max (aMaxF, aProjection);
aMinF = Min (aMinF, aProjection);
}
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3,
- SelectMgr_Vec3& theNormal)
+ gp_Vec& theNormal)
{
-
- SelectMgr_Vec3 aPnt1 (thePnt1.X(), thePnt1.Y(), thePnt1.Z());
- SelectMgr_Vec3 aPnt2 (thePnt2.X(), thePnt2.Y(), thePnt2.Z());
- SelectMgr_Vec3 aPnt3 (thePnt3.X(), thePnt3.Y(), thePnt3.Z());
- SelectMgr_Vec3 aTrEdges[3] = { aPnt2 - aPnt1,
- aPnt3 - aPnt2,
- aPnt1 - aPnt3 };
+ const gp_XYZ aTrEdges[3] = { thePnt2.XYZ() - thePnt1.XYZ(),
+ thePnt3.XYZ() - thePnt2.XYZ(),
+ thePnt1.XYZ() - thePnt3.XYZ() };
const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
{
- SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
+ const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
Standard_Real aTriangleProj;
- aTriangleProj = DOT (aPlane, aPnt1);
+ aTriangleProj = aPlane.Dot (thePnt1.XYZ());
Standard_Real aTriangleProjMin = aTriangleProj;
Standard_Real aTriangleProjMax = aTriangleProj;
- aTriangleProj = DOT (aPlane, aPnt2);
+ aTriangleProj = aPlane.Dot (thePnt2.XYZ());
aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj);
aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj);
- aTriangleProj = DOT (aPlane, aPnt3);
+ aTriangleProj = aPlane.Dot (thePnt3.XYZ());
aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj);
aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj);
}
}
- theNormal = SelectMgr_Vec3 (aTrEdges[2].y() * aTrEdges[0].z() - aTrEdges[2].z() * aTrEdges[0].y(),
- aTrEdges[2].z() * aTrEdges[0].x() - aTrEdges[2].x() * aTrEdges[0].z(),
- aTrEdges[2].x() * aTrEdges[0].y() - aTrEdges[2].y() * aTrEdges[0].x());
- if (isSeparated (thePnt1, thePnt2, thePnt3, theNormal))
+ theNormal = aTrEdges[2].Crossed (aTrEdges[0]);
+ if (isSeparated (thePnt1, thePnt2, thePnt3, theNormal.XYZ()))
{
return Standard_False;
}
{
for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir)
{
- SelectMgr_Vec3 anEdge1 = myEdgeDirs[aVolDir];
- SelectMgr_Vec3 anEdge2 = aTrEdges[aTriangleEdgeIdx];
- SelectMgr_Vec3 aTestDirection = SelectMgr_Vec3 (
- anEdge1.y() * anEdge2.z() - anEdge1.z() * anEdge2.y(),
- anEdge1.z() * anEdge2.x() - anEdge1.x() * anEdge2.z(),
- anEdge1.x() * anEdge2.y() - anEdge1.y() * anEdge2.x());
+ const gp_XYZ& aTestDirection = myEdgeDirs[aVolDir].XYZ().Crossed (aTrEdges[aTriangleEdgeIdx]);
if (isSeparated (thePnt1, thePnt2, thePnt3, aTestDirection))
{
return Standard_True;
}
-
-#undef DOT
-#undef DOTp
// function : unProject
// purpose : Unprojects point from NDC coords to 3d world space
//=======================================================================
-SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
+gp_Pnt SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
{
Graphic3d_Mat4d aInvView;
Graphic3d_Mat4d aInvProj;
// this case should never happen
if (!myWorldView.Inverted (aInvView) || !myProjection.Inverted (aInvProj))
{
- return SelectMgr_Vec3 (0.0, 0.0, 0.0);
+ return gp_Pnt (0.0, 0.0, 0.0);
}
// use compatible type of point
const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w());
- return SelectMgr_Vec3 (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
+ return gp_Pnt (aPnt.x() * aInvW, aPnt.y() * aInvW, aPnt.z() * aInvW);
}
// =======================================================================
// theZ = 0 - near plane,
// theZ = 1 - far plane
// =======================================================================
-SelectMgr_Vec3 SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& theX,
- const Standard_Real& theY,
- const Standard_Real& theZ) const
+gp_Pnt SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& theX,
+ const Standard_Real& theY,
+ const Standard_Real& theZ) const
{
Standard_Real aX, anY, aZ;
//! Projects 2d screen point onto view frustum plane:
//! theZ = 0 - near plane,
//! theZ = 1 - far plane
- Standard_EXPORT SelectMgr_Vec3 ProjectPntOnViewPlane (const Standard_Real& theX,
- const Standard_Real& theY,
- const Standard_Real& theZ) const;
+ Standard_EXPORT gp_Pnt ProjectPntOnViewPlane (const Standard_Real& theX,
+ const Standard_Real& theY,
+ const Standard_Real& theZ) const;
DEFINE_STANDARD_RTTI(SelectMgr_FrustumBuilder, Standard_Transient)
private:
//! Unprojects point from NDC coords to 3d world space
- SelectMgr_Vec3 unProject (const gp_Pnt& thePnt) const;
+ gp_Pnt unProject (const gp_Pnt& thePnt) const;
private:
#include <SelectMgr_RectangularFrustum.hxx>
-#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z())
-#define DOTp(A, B) (A.x() * B.X() + A.y() * B.Y() + A.z() * B.Z())
-#define DISTANCE(A, B) (std::sqrt ((A.x() - B.x()) * (A.x() - B.x()) + (A.y() - B.y()) * (A.y() - B.y()) + (A.z() - B.z()) * (A.z() - B.z())))
-#define DISTANCEp(A, B) (std::sqrt ((A.x() - B.X()) * (A.x() - B.X()) + (A.y() - B.Y()) * (A.y() - B.Y()) + (A.z() - B.Z()) * (A.z() - B.Z())))
-
// =======================================================================
// function : segmentSegmentDistance
// purpose :
const gp_Pnt& theSegPnt2,
Standard_Real& theDepth)
{
- SelectMgr_Vec3 anU = SelectMgr_Vec3 (theSegPnt2.X() - theSegPnt1.X(),
- theSegPnt2.Y() - theSegPnt1.Y(),
- theSegPnt2.Z() - theSegPnt1.Z());
- SelectMgr_Vec3 aV = myViewRayDir;
- SelectMgr_Vec3 aW = SelectMgr_Vec3 (theSegPnt1.X() - myNearPickedPnt.x(),
- theSegPnt1.Y() - myNearPickedPnt.y(),
- theSegPnt1.Z() - myNearPickedPnt.z());
- Standard_Real anA = DOT (anU, anU);
- Standard_Real aB = DOT (anU, aV);
- Standard_Real aC = DOT (aV, aV);
- Standard_Real aD = DOT (anU, aW);
- Standard_Real anE = DOT (aV, aW);
+ gp_XYZ anU = theSegPnt2.XYZ() - theSegPnt1.XYZ();
+ gp_XYZ aV = myViewRayDir.XYZ();
+ gp_XYZ aW = theSegPnt1.XYZ() - myNearPickedPnt.XYZ();
+
+ Standard_Real anA = anU.Dot (anU);
+ Standard_Real aB = anU.Dot (aV);
+ Standard_Real aC = aV.Dot (aV);
+ Standard_Real aD = anU.Dot (aW);
+ Standard_Real anE = aV.Dot (aW);
Standard_Real aCoef = anA * aC - aB * aB;
Standard_Real aSn = aCoef;
Standard_Real aTc, aTn, aTd = aCoef;
}
aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd);
- SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + myViewRayDir * aTc;
- theDepth = DISTANCE (myNearPickedPnt, aClosestPnt);
+ gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTc;
+ theDepth = myNearPickedPnt.Distance (aClosestPnt);
}
// =======================================================================
// function : segmentPlaneIntersection
// purpose :
// =======================================================================
-void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const SelectMgr_Vec3& thePlane,
+void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const gp_Vec& thePlane,
const gp_Pnt& thePntOnPlane,
Standard_Real& theDepth)
{
- SelectMgr_Vec3 anU = myViewRayDir;
- SelectMgr_Vec3 aW = SelectMgr_Vec3 (myNearPickedPnt.x() - thePntOnPlane.X(),
- myNearPickedPnt.y() - thePntOnPlane.Y(),
- myNearPickedPnt.z() - thePntOnPlane.Z());
- Standard_Real aD = DOT (thePlane, anU);
- Standard_Real aN = -DOT (thePlane, aW);
+ gp_XYZ anU = myViewRayDir.XYZ();
+ gp_XYZ aW = myNearPickedPnt.XYZ() - thePntOnPlane.XYZ();
+ Standard_Real aD = thePlane.Dot (anU);
+ Standard_Real aN = -thePlane.Dot (aW);
if (Abs (aD) < Precision::Confusion())
{
return;
}
- SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + anU * aParam;
- theDepth = DISTANCE (myNearPickedPnt, aClosestPnt);
+ gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + anU * aParam;
+ theDepth = myNearPickedPnt.Distance (aClosestPnt);
}
namespace
{
+ // =======================================================================
+ // function : computeFrustum
+ // purpose : Computes base frustum data: its vertices and edge directions
+ // =======================================================================
+ void computeFrustum (const gp_Pnt2d theMinPnt, const gp_Pnt2d& theMaxPnt,
+ const Handle(SelectMgr_FrustumBuilder)& theBuilder,
+ gp_Pnt* theVertices, gp_Vec* theEdges)
+ {
+ // LeftTopNear
+ theVertices[0] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
+ theMaxPnt.Y(),
+ 0.0);
+ // LeftTopFar
+ theVertices[1] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
+ theMaxPnt.Y(),
+ 1.0);
+ // LeftBottomNear
+ theVertices[2] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
+ theMinPnt.Y(),
+ 0.0);
+ // LeftBottomFar
+ theVertices[3] = theBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
+ theMinPnt.Y(),
+ 1.0);
+ // RightTopNear
+ theVertices[4] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
+ theMaxPnt.Y(),
+ 0.0);
+ // RightTopFar
+ theVertices[5] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
+ theMaxPnt.Y(),
+ 1.0);
+ // RightBottomNear
+ theVertices[6] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
+ theMinPnt.Y(),
+ 0.0);
+ // RightBottomFar
+ theVertices[7] = theBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
+ theMinPnt.Y(),
+ 1.0);
+
+ // Horizontal
+ theEdges[0] = theVertices[4].XYZ() - theVertices[0].XYZ();
+ // Vertical
+ theEdges[1] = theVertices[2].XYZ() - theVertices[0].XYZ();
+ // LeftLower
+ theEdges[2] = theVertices[2].XYZ() - theVertices[3].XYZ();
+ // RightLower
+ theEdges[3] = theVertices[6].XYZ() - theVertices[7].XYZ();
+ // LeftUpper
+ theEdges[4] = theVertices[0].XYZ() - theVertices[1].XYZ();
+ // RightUpper
+ theEdges[5] = theVertices[4].XYZ() - theVertices[5].XYZ();
+ }
+
// =======================================================================
// function : computeNormals
// purpose : Computes normals to frustum faces
// =======================================================================
- void computeNormals (const SelectMgr_Vec3* theVertices, SelectMgr_Vec3* theNormals)
+ void computeNormals (const gp_Vec* theEdges, gp_Vec* theNormals)
{
// Top
- theNormals[0] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0],
- theVertices[4] - theVertices[0]);
+ theNormals[0] = theEdges[0].Crossed (theEdges[4]);
// Bottom
- theNormals[1] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[2],
- theVertices[6] - theVertices[2]);
+ theNormals[1] = theEdges[2].Crossed (theEdges[3]);
// Left
- theNormals[2] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0],
- theVertices[2] - theVertices[0]);
+ theNormals[2] = theEdges[4].Crossed (theEdges[1]);
// Right
- theNormals[3] = SelectMgr_Vec3::Cross (theVertices[5] - theVertices[4],
- theVertices[6] - theVertices[4]);
+ theNormals[3] = theEdges[5].Crossed (theEdges[3]);
// Near
- theNormals[4] = SelectMgr_Vec3::Cross (theVertices[6] - theVertices[4],
- theVertices[0] - theVertices[4]);
+ theNormals[4] = theEdges[0].Crossed (theEdges[1]);
// Far
- theNormals[5] = SelectMgr_Vec3::Cross (theVertices[7] - theVertices[5],
- theVertices[1] - theVertices[5]);
+ theNormals[5] = -theNormals[4];
}
}
// =======================================================================
-// function : Build
-// purpose : Build volume according to the point and given pixel
-// tolerance
+// function : cacheVertexProjections
+// purpose : Caches projection of frustum's vertices onto its plane directions
+// and {i, j, k}
// =======================================================================
-void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint)
+void SelectMgr_RectangularFrustum::cacheVertexProjections (SelectMgr_RectangularFrustum* theFrustum)
{
- myNearPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 0.0);
- myFarPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 1.0);
- myViewRayDir = myFarPickedPnt - myNearPickedPnt;
- myMousePos = thePoint;
-
- // LeftTopNear
- myVertices[0] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0,
- thePoint.Y() + myPixelTolerance / 2.0,
- 0.0);
- // LeftTopFar
- myVertices[1] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0,
- thePoint.Y() + myPixelTolerance / 2.0,
- 1.0);
- // LeftBottomNear
- myVertices[2] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0,
- thePoint.Y() - myPixelTolerance / 2.0,
- 0.0);
- // LeftBottomFar
- myVertices[3] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0,
- thePoint.Y() - myPixelTolerance / 2.0,
- 1.0);
- // RightTopNear
- myVertices[4] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0,
- thePoint.Y() + myPixelTolerance / 2.0,
- 0.0);
- // RightTopFar
- myVertices[5] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0,
- thePoint.Y() + myPixelTolerance / 2.0,
- 1.0);
- // RightBottomNear
- myVertices[6] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0,
- thePoint.Y() - myPixelTolerance / 2.0,
- 0.0);
- // RightBottomFar
- myVertices[7] = myBuilder->ProjectPntOnViewPlane (thePoint.X() + myPixelTolerance / 2.0,
- thePoint.Y() - myPixelTolerance / 2.0,
- 1.0);
-
- // compute frustum normals
- computeNormals (myVertices, myPlanes);
-
- for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx)
+ if (theFrustum->myIsOrthographic)
{
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- const SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
- for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
+ // project vertices onto frustum normals
+ // Since orthographic view volume's faces are always a pairwise translation of
+ // one another, only 2 vertices that belong to opposite faces can be projected
+ // to simplify calculations.
+ Standard_Integer aVertIdxs[6] = { LeftTopNear, LeftBottomNear, // opposite planes in height direction
+ LeftBottomNear, RightBottomNear, // opposite planes in width direcion
+ LeftBottomFar, RightBottomNear }; // opposite planes in depth direction
+ for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; aPlaneIdx += 2)
{
- Standard_Real aProjection = DOT (aPlane, myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
+ Standard_Real aProj1 = theFrustum->myPlanes[aPlaneIdx].XYZ().Dot (theFrustum->myVertices[aVertIdxs[aPlaneIdx]].XYZ());
+ Standard_Real aProj2 = theFrustum->myPlanes[aPlaneIdx].XYZ().Dot (theFrustum->myVertices[aVertIdxs[aPlaneIdx + 1]].XYZ());
+ theFrustum->myMinVertsProjections[aPlaneIdx] = Min (aProj1, aProj2);
+ theFrustum->myMaxVertsProjections[aPlaneIdx] = Max (aProj1, aProj2);
}
- myMaxVertsProjections[aPlaneIdx] = aMax;
- myMinVertsProjections[aPlaneIdx] = aMin;
}
-
- SelectMgr_Vec3 aDimensions[3] =
+ else
{
- SelectMgr_Vec3 (1.0, 0.0, 0.0),
- SelectMgr_Vec3 (0.0, 1.0, 0.0),
- SelectMgr_Vec3 (0.0, 0.0, 1.0)
- };
+ // project all vertices onto frustum normals
+ for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx)
+ {
+ Standard_Real aMax = -DBL_MAX;
+ Standard_Real aMin = DBL_MAX;
+ const gp_XYZ& aPlane = theFrustum->myPlanes[aPlaneIdx].XYZ();
+ for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
+ {
+ Standard_Real aProjection = aPlane.Dot (theFrustum->myVertices[aVertIdx].XYZ());
+ aMin = Min (aMin, aProjection);
+ aMax = Max (aMax, aProjection);
+ }
+ theFrustum->myMinVertsProjections[aPlaneIdx] = aMin;
+ theFrustum->myMaxVertsProjections[aPlaneIdx] = aMax;
+ }
+ }
+ // project vertices onto {i, j, k}
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
{
Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
+ Standard_Real aMin = DBL_MAX;
for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
{
- Standard_Real aProjection = DOT (aDimensions[aDim], myVertices[aVertIdx]);
- aMax = Max (aProjection, aMax);
- aMin = Min (aProjection, aMin);
+ const gp_XYZ& aVert = theFrustum->myVertices[aVertIdx].XYZ();
+ aMax = Max (aVert.GetData()[aDim], aMax);
+ aMin = Min (aVert.GetData()[aDim], aMin);
}
- myMaxOrthoVertsProjections[aDim] = aMax;
- myMinOrthoVertsProjections[aDim] = aMin;
+ theFrustum->myMaxOrthoVertsProjections[aDim] = aMax;
+ theFrustum->myMinOrthoVertsProjections[aDim] = aMin;
}
+}
+
+// =======================================================================
+// function : Build
+// purpose : Build volume according to the point and given pixel
+// tolerance
+// =======================================================================
+void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint)
+{
+ myNearPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 0.0);
+ myFarPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 1.0);
+ myViewRayDir = myFarPickedPnt.XYZ() - myNearPickedPnt.XYZ();
+ myMousePos = thePoint;
- // Horizontal
- myEdgeDirs[0] = myVertices[4] - myVertices[0];
- // Vertical
- myEdgeDirs[1] = myVertices[2] - myVertices[0];
- // LeftLower
- myEdgeDirs[2] = myVertices[2] - myVertices[3];
- // RightLower
- myEdgeDirs[3] = myVertices[6] - myVertices[7];
- // LeftUpper
- myEdgeDirs[4] = myVertices[0] - myVertices[1];
- // RightUpper
- myEdgeDirs[5] = myVertices[4] - myVertices[5];
+ gp_Pnt2d aMinPnt (thePoint.X() - myPixelTolerance * 0.5,
+ thePoint.Y() - myPixelTolerance * 0.5);
+ gp_Pnt2d aMaxPnt (thePoint.X() + myPixelTolerance * 0.5,
+ thePoint.Y() + myPixelTolerance * 0.5);
+
+ // calculate base frustum characteristics: vertices and edge directions
+ computeFrustum (aMinPnt, aMaxPnt, myBuilder, myVertices, myEdgeDirs);
+
+ // compute frustum normals
+ computeNormals (myEdgeDirs, myPlanes);
+
+ // compute vertices projections onto frustum normals and
+ // {i, j, k} vectors and store them to corresponding class fields
+ cacheVertexProjections (this);
}
// =======================================================================
myFarPickedPnt = myBuilder->ProjectPntOnViewPlane ((theMinPnt.X() + theMaxPnt.X()) * 0.5,
(theMinPnt.Y() + theMaxPnt.Y()) * 0.5,
1.0);
- myViewRayDir = myFarPickedPnt - myNearPickedPnt;
-
- // LeftTopNear
- myVertices[0] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
- theMaxPnt.Y(),
- 0.0);
- // LeftTopFar
- myVertices[1] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
- theMaxPnt.Y(),
- 1.0);
- // LeftBottomNear
- myVertices[2] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
- theMinPnt.Y(),
- 0.0);
- // LeftBottomFar
- myVertices[3] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(),
- theMinPnt.Y(),
- 1.0);
- // RightTopNear
- myVertices[4] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
- theMaxPnt.Y(),
- 0.0);
- // RightTopFar
- myVertices[5] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
- theMaxPnt.Y(),
- 1.0);
- // RightBottomNear
- myVertices[6] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
- theMinPnt.Y(),
- 0.0);
- // RightBottomFar
- myVertices[7] = myBuilder->ProjectPntOnViewPlane (theMaxPnt.X(),
- theMinPnt.Y(),
- 1.0);
+ myViewRayDir = myFarPickedPnt.XYZ() - myNearPickedPnt.XYZ();
- // compute frustum normals
- computeNormals (myVertices, myPlanes);
+ // calculate base frustum characteristics: vertices and edge directions
+ computeFrustum (theMinPnt, theMaxPnt, myBuilder, myVertices, myEdgeDirs);
- for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx)
- {
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- const SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
- for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aPlane, myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- myMaxVertsProjections[aPlaneIdx] = aMax;
- myMinVertsProjections[aPlaneIdx] = aMin;
- }
-
- SelectMgr_Vec3 aDimensions[3] =
- {
- SelectMgr_Vec3 (1.0, 0.0, 0.0),
- SelectMgr_Vec3 (0.0, 1.0, 0.0),
- SelectMgr_Vec3 (0.0, 0.0, 1.0)
- };
-
- for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
- {
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aDimensions[aDim], myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- myMaxOrthoVertsProjections[aDim] = aMax;
- myMinOrthoVertsProjections[aDim] = aMin;
- }
+ // compute frustum normals
+ computeNormals (myEdgeDirs, myPlanes);
- // Horizontal
- myEdgeDirs[0] = myVertices[4] - myVertices[0];
- // Vertical
- myEdgeDirs[1] = myVertices[2] - myVertices[0];
- // LeftLower
- myEdgeDirs[2] = myVertices[2] - myVertices[3];
- // RightLower
- myEdgeDirs[3] = myVertices[6] - myVertices[7];
- // LeftUpper
- myEdgeDirs[4] = myVertices[0] - myVertices[1];
- // RightUpper
- myEdgeDirs[5] = myVertices[4] - myVertices[5];
+ // compute vertices projections onto frustum normals and
+ // {i, j, k} vectors and store them to corresponding class fields
+ cacheVertexProjections (this);
}
// =======================================================================
-// function : Transform
-// purpose : Returns a copy of the frustum transformed according to the matrix given
+// function : ScaleAndTransform
+// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
+// Note that this method does not perform any checks on type of the frustum.
+// Returns a copy of the frustum resized according to the scale factor given
+// and transforms it using the matrix given.
+// There are no default parameters, but in case if:
+// - transformation only is needed: @theScaleFactor must be initialized
+// as any negative value;
+// - scale only is needed: @theTrsf must be set to gp_Identity.
// =======================================================================
-NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::Transform (const gp_Trsf& theTrsf)
+NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::ScaleAndTransform (const Standard_Integer theScaleFactor,
+ const gp_Trsf& theTrsf)
{
+ Standard_ASSERT_RAISE (theScaleFactor > 0,
+ "Error! Pixel tolerance for selection should be greater than zero");
+
SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
+ const Standard_Boolean isToScale = theScaleFactor != 1;
+ const Standard_Boolean isToTrsf = theTrsf.Form() != gp_Identity;
- aRes->myNearPickedPnt = SelectMgr_MatOp::Transform (theTrsf, myNearPickedPnt);
- aRes->myFarPickedPnt = SelectMgr_MatOp::Transform (theTrsf, myFarPickedPnt);
- aRes->myViewRayDir = aRes->myFarPickedPnt - aRes->myNearPickedPnt;
+ if (!isToScale && !isToTrsf)
+ return aRes;
aRes->myIsOrthographic = myIsOrthographic;
+ SelectMgr_RectangularFrustum* aRef = this;
- // LeftTopNear
- aRes->myVertices[0] = SelectMgr_MatOp::Transform (theTrsf, myVertices[0]);
- // LeftTopFar
- aRes->myVertices[1] = SelectMgr_MatOp::Transform (theTrsf, myVertices[1]);
- // LeftBottomNear
- aRes->myVertices[2] = SelectMgr_MatOp::Transform (theTrsf, myVertices[2]);
- // LeftBottomFar
- aRes->myVertices[3] = SelectMgr_MatOp::Transform (theTrsf, myVertices[3]);
- // RightTopNear
- aRes->myVertices[4] = SelectMgr_MatOp::Transform (theTrsf, myVertices[4]);
- // RightTopFar
- aRes->myVertices[5] = SelectMgr_MatOp::Transform (theTrsf, myVertices[5]);
- // RightBottomNear
- aRes->myVertices[6] = SelectMgr_MatOp::Transform (theTrsf, myVertices[6]);
- // RightBottomFar
- aRes->myVertices[7] = SelectMgr_MatOp::Transform (theTrsf, myVertices[7]);
-
- // compute frustum normals
- computeNormals (aRes->myVertices, aRes->myPlanes);
-
- for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx)
+ if (isToScale)
{
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- const SelectMgr_Vec3 aPlane = aRes->myPlanes[aPlaneIdx];
- for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aPlane, aRes->myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- aRes->myMaxVertsProjections[aPlaneIdx] = aMax;
- aRes->myMinVertsProjections[aPlaneIdx] = aMin;
- }
-
- SelectMgr_Vec3 aDimensions[3] =
- {
- SelectMgr_Vec3 (1.0, 0.0, 0.0),
- SelectMgr_Vec3 (0.0, 1.0, 0.0),
- SelectMgr_Vec3 (0.0, 0.0, 1.0)
- };
-
- for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
- {
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aDimensions[aDim], aRes->myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- aRes->myMaxOrthoVertsProjections[aDim] = aMax;
- aRes->myMinOrthoVertsProjections[aDim] = aMin;
- }
-
- // Horizontal
- aRes->myEdgeDirs[0] = aRes->myVertices[4] - aRes->myVertices[0];
- // Vertical
- aRes->myEdgeDirs[1] = aRes->myVertices[2] - aRes->myVertices[0];
- // LeftLower
- aRes->myEdgeDirs[2] = aRes->myVertices[2] - aRes->myVertices[3];
- // RightLower
- aRes->myEdgeDirs[3] = aRes->myVertices[6] - aRes->myVertices[7];
- // LeftUpper
- aRes->myEdgeDirs[4] = aRes->myVertices[0] - aRes->myVertices[1];
- // RightUpper
- aRes->myEdgeDirs[5] = aRes->myVertices[4] - aRes->myVertices[5];
-
- return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
-}
-
-// =======================================================================
-// function : Scale
-// purpose : IMPORTANT: Makes sense only for frustum built on a single point!
-// Returns a copy of the frustum resized according to the scale factor given
-// =======================================================================
-NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::Scale (const Standard_Real theScaleFactor)
-{
- SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
+ aRes->myNearPickedPnt = myNearPickedPnt;
+ aRes->myFarPickedPnt = myFarPickedPnt;
+ aRes->myViewRayDir = myViewRayDir;
- aRes->myNearPickedPnt = myNearPickedPnt;
- aRes->myFarPickedPnt = myFarPickedPnt;
- aRes->myViewRayDir = myViewRayDir;
-
- aRes->myIsOrthographic = myIsOrthographic;
+ const gp_Pnt2d aMinPnt (myMousePos.X() - theScaleFactor * 0.5,
+ myMousePos.Y() - theScaleFactor * 0.5);
+ const gp_Pnt2d aMaxPnt (myMousePos.X() + theScaleFactor * 0.5,
+ myMousePos.Y() + theScaleFactor * 0.5);
- // LeftTopNear
- aRes->myVertices[0] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
- myMousePos.Y() + theScaleFactor / 2.0,
- 0.0);
- // LeftTopFar
- aRes->myVertices[1] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
- myMousePos.Y() + theScaleFactor / 2.0,
- 1.0);
- // LeftBottomNear
- aRes->myVertices[2] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
- myMousePos.Y() - theScaleFactor / 2.0,
- 0.0);
- // LeftBottomFar
- aRes->myVertices[3] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() - theScaleFactor / 2.0,
- myMousePos.Y() - theScaleFactor / 2.0,
- 1.0);
- // RightTopNear
- aRes->myVertices[4] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
- myMousePos.Y() + theScaleFactor / 2.0,
- 0.0);
- // RightTopFar
- aRes->myVertices[5] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
- myMousePos.Y() + theScaleFactor / 2.0,
- 1.0);
- // RightBottomNear
- aRes->myVertices[6] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
- myMousePos.Y() - theScaleFactor / 2.0,
- 0.0);
- // RightBottomFar
- aRes->myVertices[7] = myBuilder->ProjectPntOnViewPlane (myMousePos.X() + theScaleFactor / 2.0,
- myMousePos.Y() - theScaleFactor / 2.0,
- 1.0);
- // compute frustum normals
- computeNormals (aRes->myVertices, aRes->myPlanes);
+ // recompute base frustum characteristics from scratch
+ computeFrustum (aMinPnt, aMaxPnt, myBuilder, aRes->myVertices, aRes->myEdgeDirs);
- for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx)
- {
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- const SelectMgr_Vec3 aPlane = aRes->myPlanes[aPlaneIdx];
- for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aPlane, aRes->myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- aRes->myMaxVertsProjections[aPlaneIdx] = aMax;
- aRes->myMinVertsProjections[aPlaneIdx] = aMin;
+ aRef = aRes;
}
- SelectMgr_Vec3 aDimensions[3] =
+ if (isToTrsf)
{
- SelectMgr_Vec3 (1.0, 0.0, 0.0),
- SelectMgr_Vec3 (0.0, 1.0, 0.0),
- SelectMgr_Vec3 (0.0, 0.0, 1.0)
- };
-
- for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
- {
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aDimensions[aDim], aRes->myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- aRes->myMaxOrthoVertsProjections[aDim] = aMax;
- aRes->myMinOrthoVertsProjections[aDim] = aMin;
+ aRes->myNearPickedPnt = aRef->myNearPickedPnt.Transformed (theTrsf);
+ aRes->myFarPickedPnt = aRef->myFarPickedPnt.Transformed (theTrsf);
+ aRes->myViewRayDir = aRes->myFarPickedPnt.XYZ() - aRes->myNearPickedPnt.XYZ();
+
+ // LeftTopNear
+ aRes->myVertices[0] = aRef->myVertices[0].Transformed (theTrsf);
+ // LeftTopFar
+ aRes->myVertices[1] = aRef->myVertices[1].Transformed (theTrsf);
+ // LeftBottomNear
+ aRes->myVertices[2] = aRef->myVertices[2].Transformed (theTrsf);
+ // LeftBottomFar
+ aRes->myVertices[3] = aRef->myVertices[3].Transformed (theTrsf);
+ // RightTopNear
+ aRes->myVertices[4] = aRef->myVertices[4].Transformed (theTrsf);
+ // RightTopFar
+ aRes->myVertices[5] = aRef->myVertices[5].Transformed (theTrsf);
+ // RightBottomNear
+ aRes->myVertices[6] = aRef->myVertices[6].Transformed (theTrsf);
+ // RightBottomFar
+ aRes->myVertices[7] = aRef->myVertices[7].Transformed (theTrsf);
+
+ // Horizontal
+ aRes->myEdgeDirs[0] = aRes->myVertices[4].XYZ() - aRes->myVertices[0].XYZ();
+ // Vertical
+ aRes->myEdgeDirs[1] = aRes->myVertices[2].XYZ() - aRes->myVertices[0].XYZ();
+ // LeftLower
+ aRes->myEdgeDirs[2] = aRes->myVertices[2].XYZ() - aRes->myVertices[3].XYZ();
+ // RightLower
+ aRes->myEdgeDirs[3] = aRes->myVertices[6].XYZ() - aRes->myVertices[7].XYZ();
+ // LeftUpper
+ aRes->myEdgeDirs[4] = aRes->myVertices[0].XYZ() - aRes->myVertices[1].XYZ();
+ // RightUpper
+ aRes->myEdgeDirs[5] = aRes->myVertices[4].XYZ() - aRes->myVertices[5].XYZ();
}
- // Horizontal
- aRes->myEdgeDirs[0] = aRes->myVertices[4] - aRes->myVertices[0];
- // Vertical
- aRes->myEdgeDirs[1] = aRes->myVertices[2] - aRes->myVertices[0];
- // LeftLower
- aRes->myEdgeDirs[2] = aRes->myVertices[2] - aRes->myVertices[3];
- // RightLower
- aRes->myEdgeDirs[3] = aRes->myVertices[6] - aRes->myVertices[7];
- // LeftUpper
- aRes->myEdgeDirs[4] = aRes->myVertices[0] - aRes->myVertices[1];
- // RightUpper
- aRes->myEdgeDirs[5] = aRes->myVertices[4] - aRes->myVertices[5];
+ // compute frustum normals
+ computeNormals (aRes->myEdgeDirs, aRes->myPlanes);
+
+ cacheVertexProjections (aRes);
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
}
// purpose : SAT intersection test between defined volume and
// given axis-aligned box
// =======================================================================
-Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
+Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const SelectMgr_Vec3& theBoxMin,
+ const SelectMgr_Vec3& theBoxMax,
Standard_Real& theDepth)
{
- const SelectMgr_Vec3& aMinPnt = theBox.CornerMin();
- const SelectMgr_Vec3& aMaxPnt = theBox.CornerMax();
- if (!hasOverlap (aMinPnt, aMaxPnt))
+ if (!hasOverlap (theBoxMin, theBoxMax))
return Standard_False;
- SelectMgr_Vec3 aNearestPnt = SelectMgr_Vec3 (RealLast(), RealLast(), RealLast());
- aNearestPnt.x() = Max (Min (myNearPickedPnt.x(), aMaxPnt.x()), aMinPnt.x());
- aNearestPnt.y() = Max (Min (myNearPickedPnt.y(), aMaxPnt.y()), aMinPnt.y());
- aNearestPnt.z() = Max (Min (myNearPickedPnt.z(), aMaxPnt.z()), aMinPnt.z());
+ gp_Pnt aNearestPnt (RealLast(), RealLast(), RealLast());
+ aNearestPnt.SetX (Max (Min (myNearPickedPnt.X(), theBoxMax.x()), theBoxMin.x()));
+ aNearestPnt.SetY (Max (Min (myNearPickedPnt.Y(), theBoxMax.y()), theBoxMin.y()));
+ aNearestPnt.SetZ (Max (Min (myNearPickedPnt.Z(), theBoxMax.z()), theBoxMin.z()));
- theDepth = DISTANCE (aNearestPnt, myNearPickedPnt);
+ theDepth = aNearestPnt.Distance (myNearPickedPnt);
return Standard_True;
}
if (!hasOverlap (thePnt))
return Standard_False;
- SelectMgr_Vec3 aPnt (thePnt.X(), thePnt.Y(), thePnt.Z());
- SelectMgr_Vec3 aV = aPnt - myNearPickedPnt;
- SelectMgr_Vec3 aDetectedPnt = myNearPickedPnt + myViewRayDir * (DOT (aV, myViewRayDir) / DOT (myViewRayDir, myViewRayDir));
+ gp_XYZ aV = thePnt.XYZ() - myNearPickedPnt.XYZ();
+ gp_Pnt aDetectedPnt =
+ myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * (aV.Dot (myViewRayDir.XYZ()) / myViewRayDir.Dot (myViewRayDir));
- theDepth = DISTANCE (aDetectedPnt, myNearPickedPnt);
+ theDepth = aDetectedPnt.Distance (myNearPickedPnt);
return Standard_True;
}
+// =======================================================================
+// function : Overlaps
+// purpose : Intersection test between defined volume and given point
+// =======================================================================
+Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt)
+{
+ return hasOverlap (thePnt);
+}
+
// =======================================================================
// function : Overlaps
// purpose : Checks if line segment overlaps selecting frustum
}
else if (theSensType == Select3D_TOS_INTERIOR)
{
- SelectMgr_Vec3 aPolyNorm (RealLast());
+ gp_Vec aPolyNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
if (!hasOverlap (theArrayOfPnts, aPolyNorm))
return Standard_False;
}
else if (theSensType == Select3D_TOS_INTERIOR)
{
- SelectMgr_Vec3 aTriangleNormal (RealLast());
+ gp_Vec aTriangleNormal (gp_XYZ (RealLast(), RealLast(), RealLast()));
if (!hasOverlap (thePnt1, thePnt2, thePnt3, aTriangleNormal))
return Standard_False;
// check if intersection point belongs to triangle's interior part
- SelectMgr_Vec3 aPnt1 (thePnt1.X(), thePnt1.Y(), thePnt1.Z());
- SelectMgr_Vec3 aTrEdges[3] = { SelectMgr_Vec3 (thePnt2.X() - thePnt1.X(), thePnt2.Y() - thePnt1.Y(), thePnt2.Z() - thePnt1.Z()),
- SelectMgr_Vec3 (thePnt3.X() - thePnt2.X(), thePnt3.Y() - thePnt2.Y(), thePnt3.Z() - thePnt2.Z()),
- SelectMgr_Vec3 (thePnt1.X() - thePnt3.X(), thePnt1.Y() - thePnt3.Y(), thePnt1.Z() - thePnt3.Z()) };
+ gp_XYZ aTrEdges[3] = { thePnt2.XYZ() - thePnt1.XYZ(),
+ thePnt3.XYZ() - thePnt2.XYZ(),
+ thePnt1.XYZ() - thePnt3.XYZ() };
- Standard_Real anAlpha = DOT (aTriangleNormal, myViewRayDir);
+ Standard_Real anAlpha = aTriangleNormal.Dot (myViewRayDir);
if (Abs (anAlpha) < gp::Resolution())
{
// handle degenerated triangles: in this case, there is no possible way to detect overlap correctly.
- if (aTriangleNormal.SquareModulus() < gp::Resolution())
+ if (aTriangleNormal.SquareMagnitude() < gp::Resolution())
{
theDepth = std::numeric_limits<Standard_Real>::max();
return Standard_False;
// handle the case when triangle normal and selecting frustum direction are orthogonal: for this case, overlap
// is detected correctly, and distance to triangle's plane can be measured as distance to its arbitrary vertex.
- const SelectMgr_Vec3 aDiff = myNearPickedPnt - aPnt1;
- theDepth = DOT (aTriangleNormal, aDiff);
+ const gp_XYZ aDiff = myNearPickedPnt.XYZ() - thePnt1.XYZ();
+ theDepth = aTriangleNormal.Dot (aDiff);
return Standard_True;
}
- SelectMgr_Vec3 anEdge = (aPnt1 - myNearPickedPnt) * (1.0 / anAlpha);
+ gp_XYZ anEdge = (thePnt1.XYZ() - myNearPickedPnt.XYZ()) * (1.0 / anAlpha);
- Standard_Real aTime = DOT (aTriangleNormal, anEdge);
+ Standard_Real aTime = aTriangleNormal.Dot (anEdge);
- SelectMgr_Vec3 aVec = SelectMgr_Vec3 (myViewRayDir.y() * anEdge.z() - myViewRayDir.z() * anEdge.y(),
- myViewRayDir.z() * anEdge.x() - myViewRayDir.x() * anEdge.z(),
- myViewRayDir.x() * anEdge.y() - myViewRayDir.y() * anEdge.x());
+ gp_XYZ aVec = myViewRayDir.XYZ().Crossed (anEdge);
- Standard_Real anU = DOT (aVec, aTrEdges[2]);
- Standard_Real aV = DOT (aVec, aTrEdges[0]);
+ Standard_Real anU = aVec.Dot (aTrEdges[2]);
+ Standard_Real aV = aVec.Dot (aTrEdges[0]);
Standard_Boolean isInterior = (aTime >= 0.0) && (anU >= 0.0) && (aV >= 0.0) && (anU + aV <= 1.0);
if (isInterior)
{
- SelectMgr_Vec3 aDetectedPnt = myNearPickedPnt + myViewRayDir * aTime;
- theDepth = DISTANCE (myNearPickedPnt, aDetectedPnt);
+ gp_Pnt aDetectedPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTime;
+ theDepth = myNearPickedPnt.Distance (aDetectedPnt);
return Standard_True;
}
gp_Pnt aPnts[3] = {thePnt1, thePnt2, thePnt3};
Standard_Real aMinDist = RealLast();
Standard_Integer aNearestEdgeIdx = -1;
- SelectMgr_Vec3 aPtOnPlane = myNearPickedPnt + myViewRayDir * aTime;
+ gp_Pnt aPtOnPlane = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTime;
for (Standard_Integer anEdgeIdx = 0; anEdgeIdx < 3; ++anEdgeIdx)
{
- SelectMgr_Vec3 aW = SelectMgr_Vec3 (aPtOnPlane.x() - aPnts[anEdgeIdx].X(),
- aPtOnPlane.y() - aPnts[anEdgeIdx].Y(),
- aPtOnPlane.z() - aPnts[anEdgeIdx].Z());
- Standard_Real aCoef = DOT (aTrEdges[anEdgeIdx], aW) / DOT (aTrEdges[anEdgeIdx], aTrEdges[anEdgeIdx]);
- Standard_Real aDist = DISTANCE (aPtOnPlane, SelectMgr_Vec3 (aPnts[anEdgeIdx].X() + aCoef * aTrEdges[anEdgeIdx].x(),
- aPnts[anEdgeIdx].Y() + aCoef * aTrEdges[anEdgeIdx].y(),
- aPnts[anEdgeIdx].Z() + aCoef * aTrEdges[anEdgeIdx].z()));
+ gp_XYZ aW = aPtOnPlane.XYZ() - aPnts[anEdgeIdx].XYZ();
+ Standard_Real aCoef = aTrEdges[anEdgeIdx].Dot (aW) / aTrEdges[anEdgeIdx].Dot (aTrEdges[anEdgeIdx]);
+ Standard_Real aDist = aPtOnPlane.Distance (aPnts[anEdgeIdx].XYZ() + aCoef * aTrEdges[anEdgeIdx]);
if (aMinDist > aDist)
{
aMinDist = aDist;
// =======================================================================
Standard_Real SelectMgr_RectangularFrustum::DistToGeometryCenter (const gp_Pnt& theCOG)
{
- const SelectMgr_Vec3& aCOG = SelectMgr_Vec3 (theCOG.X(), theCOG.Y(), theCOG.Z());
- return DISTANCE (aCOG, myNearPickedPnt);
+ return theCOG.Distance (myNearPickedPnt);
}
// =======================================================================
// purpose : Calculates the point on a view ray that was detected during
// the run of selection algo by given depth
// =======================================================================
-SelectMgr_Vec3 SelectMgr_RectangularFrustum::DetectedPoint (const Standard_Real theDepth) const
+gp_Pnt SelectMgr_RectangularFrustum::DetectedPoint (const Standard_Real theDepth) const
{
- return myNearPickedPnt + myViewRayDir.Normalized() * theDepth;
+ return myNearPickedPnt.XYZ() + myViewRayDir.Normalized().XYZ() * theDepth;
}
// =======================================================================
const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ();
- Standard_Real aDotProduct = DOTp (myViewRayDir, aPlaneDirXYZ);
- Standard_Real aDistance = - (DOTp (myNearPickedPnt, aPlaneDirXYZ) + aPlaneD);
+ Standard_Real aDotProduct = myViewRayDir.XYZ().Dot (aPlaneDirXYZ);
+ Standard_Real aDistance = - myNearPickedPnt.XYZ().Dot (aPlaneDirXYZ) +
+ aPlaneD;
// check whether the pick line is parallel to clip plane
if (Abs (aDotProduct) < Precision::Angular())
continue;
}
- const SelectMgr_Vec3 anIntersectionPt = myNearPickedPnt + myViewRayDir * aParam;
- const Standard_Real aDistToPln = DISTANCE (anIntersectionPt, myNearPickedPnt);
+ const gp_Pnt anIntersectionPt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aParam;
+ const Standard_Real aDistToPln = anIntersectionPt.Distance (myNearPickedPnt);
// change depth limits for case of opposite and directed planes
if (aDotProduct < 0.0)
Standard_EXPORT virtual void Build (const gp_Pnt2d& theMinPnt,
const gp_Pnt2d& theMaxPnt) Standard_OVERRIDE;
- //! Returns a copy of the frustum transformed according to the matrix given
- Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
-
- //! IMPORTANT: Makes sense only for frustum built on a single point!
+ //! IMPORTANT: Scaling makes sense only for frustum built on a single point!
+ //! Note that this method does not perform any checks on type of the frustum.
//! Returns a copy of the frustum resized according to the scale factor given
- Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Scale (const Standard_Real theScaleFactor) Standard_OVERRIDE;
+ //! and transforms it using the matrix given.
+ //! There are no default parameters, but in case if:
+ //! - transformation only is needed: @theScaleFactor must be initialized as any negative value;
+ //! - scale only is needed: @theTrsf must be set to gp_Identity.
+ Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScaleFactor,
+ const gp_Trsf& theTrsf) Standard_OVERRIDE;
// SAT Tests for different objects
//! SAT intersection test between defined volume and given axis-aligned box
- Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
+ const SelectMgr_Vec3& theBoxMax,
Standard_Real& theDepth) Standard_OVERRIDE;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth) Standard_OVERRIDE;
+ //! Intersection test between defined volume and given point
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt) Standard_OVERRIDE;
+
//! SAT intersection test between defined volume and given ordered set of points,
//! representing line segments. The test may be considered of interior part or
//! boundary line defined by segments depending on given sensitivity type
Standard_EXPORT virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) Standard_OVERRIDE;
//! Calculates the point on a view ray that was detected during the run of selection algo by given depth
- Standard_EXPORT virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
+ Standard_EXPORT virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
//! Checks if the point of sensitive in which selection was detected belongs
//! to the region defined by clipping planes
Standard_EXPORT virtual Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
const Standard_Real theDepth) Standard_OVERRIDE;
+ //! A set of helper functions that return rectangular selecting frustum data
+ inline const gp_Pnt* GetVertices() const { return myVertices; }
+
+ inline gp_Pnt GetNearPnt() const { return myNearPickedPnt; }
+
+ inline gp_Pnt GetFarPnt() const { return myFarPickedPnt; }
protected:
Standard_EXPORT void segmentSegmentDistance (const gp_Pnt& theSegPnt1,
const gp_Pnt& theSegPnt2,
Standard_Real& theDepth);
- Standard_EXPORT void segmentPlaneIntersection (const SelectMgr_Vec3& thePlane,
+ Standard_EXPORT void segmentPlaneIntersection (const gp_Vec& thePlane,
const gp_Pnt& thePntOnPlane,
Standard_Real& theDepth);
private:
- SelectMgr_Vec3 myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane
- SelectMgr_Vec3 myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
- SelectMgr_Vec3 myViewRayDir;
- gp_Pnt2d myMousePos; //!< Mouse coordinates
+ void cacheVertexProjections (SelectMgr_RectangularFrustum* theFrustum);
+
+private:
+ enum { LeftTopNear, LeftTopFar,
+ LeftBottomNear, LeftBottomFar,
+ RightTopNear, RightTopFar,
+ RightBottomNear, RightBottomFar };
+
+private:
+
+ gp_Pnt myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane
+ gp_Pnt myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
+ gp_Vec myViewRayDir;
+ gp_Pnt2d myMousePos; //!< Mouse coordinates
};
#endif // _SelectMgr_RectangularFrustum_HeaderFile
//=======================================================================
SelectMgr_SelectableObjectSet::SelectMgr_SelectableObjectSet()
{
- myBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 32> (1, 32, Standard_False);
+ myBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (1, 32, Standard_True);
}
//=======================================================================
void SelectMgr_SelectableObjectSet::Swap (const Standard_Integer theIndex1,
const Standard_Integer theIndex2)
{
- const Standard_Integer aIndex1 = theIndex1 + 1;
- const Standard_Integer aIndex2 = theIndex2 + 1;
-
- Handle(SelectMgr_SelectableObject) anObject1 = myObjects.FindKey (aIndex1);
- Handle(SelectMgr_SelectableObject) anObject2 = myObjects.FindKey (aIndex2);
-
- myObjects.Substitute (aIndex1, EMPTY_OBJ);
- myObjects.Substitute (aIndex2, anObject1);
- myObjects.Substitute (aIndex1, anObject2);
+ myObjects.Swap (theIndex1 + 1, theIndex2 + 1);
}
//=======================================================================
//! binned BVH builder is used with 32 bins and 1 element per leaf.
class SelectMgr_SelectableObjectSet : public BVH_PrimitiveSet<Standard_Real, 3>
{
- Handle(SelectMgr_SelectableObject) EMPTY_OBJ;
-
public:
//! Creates new empty objects set and initializes BVH tree
}
//=======================================================================
-// function : Transform
-// purpose : Returns a copy of active frustum transformed according to the matrix given
-//=======================================================================
-SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Transform (const gp_Trsf& theTrsf)
+// function : ScaleAndTransform
+// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
+// Note that this method does not perform any checks on type of the frustum.
+//
+// Returns a copy of the frustum resized according to the scale factor given
+// and transforms it using the matrix given.
+// There are no default parameters, but in case if:
+// - transformation only is needed: @theScaleFactor must be initialized
+// as any negative value;
+// - scale only is needed: @theTrsf must be set to gp_Identity.
+//=======================================================================
+SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTransform (const Standard_Integer theScaleFactor,
+ const gp_Trsf& theTrsf)
{
SelectMgr_SelectingVolumeManager aMgr (Standard_False);
aMgr.myActiveSelectionType = myActiveSelectionType;
- aMgr.mySelectingVolumes[myActiveSelectionType / 2] = mySelectingVolumes[myActiveSelectionType / 2]->Transform (theTrsf);
+ aMgr.mySelectingVolumes[myActiveSelectionType / 2]
+ = mySelectingVolumes[myActiveSelectionType / 2]->ScaleAndTransform (theScaleFactor, theTrsf);
aMgr.myToAllowOverlap = myToAllowOverlap;
return aMgr;
}
-//=======================================================================
-// function : Scale
-// purpose : IMPORTANT: Makes sense only for point selection!
-// Returns a copy of the frustum resized according to the scale factor given
-//=======================================================================
-SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Scale (const Standard_Real theScaleFactor)
-{
- if (myActiveSelectionType != Point)
- return SelectMgr_SelectingVolumeManager (Standard_False);
-
- SelectMgr_SelectingVolumeManager aMgr (Standard_False);
-
- aMgr.myActiveSelectionType = Point;
-
- aMgr.mySelectingVolumes[Point] = mySelectingVolumes[Point]->Scale (theScaleFactor);
-
- return aMgr;
-}
-
//=======================================================================
// function : GetActiveSelectionType
// purpose :
// function : SetPixelTolerance
// purpose : Updates pixel tolerance in all selecting volumes
//=======================================================================
-void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Real theTolerance)
+void SelectMgr_SelectingVolumeManager::SetPixelTolerance (const Standard_Integer theTolerance)
{
for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
{
// purpose : SAT intersection test between defined volume and
// given axis-aligned box
//=======================================================================
-Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox,
+Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec3& theBoxMin,
+ const SelectMgr_Vec3& theBoxMax,
Standard_Real& theDepth)
{
if (myActiveSelectionType == Unknown)
return Standard_False;
- return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBndBox, theDepth);
+ return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theDepth);
}
//=======================================================================
// function : Overlaps
// purpose : Intersection test between defined volume and given point
//=======================================================================
-Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt,
+Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth)
{
if (myActiveSelectionType == Unknown)
return Standard_False;
- return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt,
+ return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt,
theDepth);
}
+//=======================================================================
+// function : Overlaps
+// purpose : Intersection test between defined volume and given point
+//=======================================================================
+Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePnt)
+{
+ if (myActiveSelectionType == Unknown)
+ return Standard_False;
+
+ return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt);
+}
+
//=======================================================================
// function : Overlaps
// purpose : SAT intersection test between defined volume and given
// may be considered of interior part or boundary line defined
// by segments depending on given sensitivity type
//=======================================================================
-Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
+Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
Standard_Integer theSensType,
Standard_Real& theDepth)
{
if (myActiveSelectionType == Unknown)
return Standard_False;
- return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPts,
+ return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts,
(Select3D_TypeOfSensitivity)theSensType,
theDepth);
}
// the run of selection algo by given depth. Is valid for point
// selection only
// =======================================================================
-NCollection_Vec3<Standard_Real> SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
+gp_Pnt SelectMgr_SelectingVolumeManager::DetectedPoint (const Standard_Real theDepth) const
{
if (myActiveSelectionType != Point)
- return NCollection_Vec3<Standard_Real> (RealLast());
+ return gp_Pnt (RealLast(), RealLast(), RealLast());
return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
}
{
return myActiveSelectionType != Box || myToAllowOverlap;
}
+
+//=======================================================================
+// function : GetVertices
+// purpose :
+//=======================================================================
+const gp_Pnt* SelectMgr_SelectingVolumeManager::GetVertices() const
+{
+ if (myActiveSelectionType == Polyline)
+ return NULL;
+
+ const SelectMgr_RectangularFrustum* aFr =
+ reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
+ return aFr->GetVertices();
+}
+
+//=======================================================================
+// function : GetNearPnt
+// purpose :
+//=======================================================================
+gp_Pnt SelectMgr_SelectingVolumeManager::GetNearPnt() const
+{
+ if (myActiveSelectionType == Polyline)
+ return gp_Pnt();
+
+ const SelectMgr_RectangularFrustum* aFr =
+ reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
+ return aFr->GetNearPnt();
+}
+
+//=======================================================================
+// function : GetFarPnt
+// purpose :
+//=======================================================================
+gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPnt() const
+{
+ if (myActiveSelectionType == Polyline)
+ return gp_Pnt();
+
+ const SelectMgr_RectangularFrustum* aFr =
+ reinterpret_cast<const SelectMgr_RectangularFrustum*> (mySelectingVolumes[myActiveSelectionType / 2].get());
+ return aFr->GetFarPnt();
+}
Standard_EXPORT virtual ~SelectMgr_SelectingVolumeManager() {};
- //! Returns a copy of active frustum transformed according to the matrix given
- Standard_EXPORT virtual SelectMgr_SelectingVolumeManager Transform (const gp_Trsf& theTrsf);
-
- //! IMPORTANT: Makes sense only for point selection!
+ //! IMPORTANT: Scaling makes sense only for frustum built on a single point!
+ //! Note that this method does not perform any checks on type of the frustum.
+ //!
//! Returns a copy of the frustum resized according to the scale factor given
- Standard_EXPORT virtual SelectMgr_SelectingVolumeManager Scale (const Standard_Real theScaleFactor);
+ //! and transforms it using the matrix given.
+ //! There are no default parameters, but in case if:
+ //! - transformation only is needed: @theScaleFactor must be initialized as any negative value;
+ //! - scale only is needed: @theTrsf must be set to gp_Identity.
+ Standard_EXPORT virtual SelectMgr_SelectingVolumeManager ScaleAndTransform (const Standard_Integer theScaleFactor,
+ const gp_Trsf& theTrsf);
Standard_EXPORT virtual Standard_Integer GetActiveSelectionType() const Standard_OVERRIDE;
const Standard_Real theHeight);
//! Updates pixel tolerance in all selecting volumes
- Standard_EXPORT void SetPixelTolerance (const Standard_Real theTolerance);
+ Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTolerance);
//! Updates window size in all selecting volumes
Standard_EXPORT void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight);
//! SAT intersection test between defined volume and given axis-aligned box
- Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
+ const SelectMgr_Vec3& theBoxMax,
Standard_Real& theDepth) Standard_OVERRIDE;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
Standard_Boolean* theInside = NULL) Standard_OVERRIDE;
//! Intersection test between defined volume and given point
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth) Standard_OVERRIDE;
+ //! Intersection test between defined volume and given point
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt) Standard_OVERRIDE;
+
//! SAT intersection test between defined volume and given ordered set of points,
//! representing line segments. The test may be considered of interior part or
//! boundary line defined by segments depending on given sensitivity type
Standard_Real& theDepth) Standard_OVERRIDE;
//! Checks if line segment overlaps selecting frustum
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
- const gp_Pnt& thePt2,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
+ const gp_Pnt& thePnt2,
Standard_Real& theDepth) Standard_OVERRIDE;
//! SAT intersection test between defined volume and given triangle. The test may
//! be considered of interior part or boundary line defined by triangle vertices
//! depending on given sensitivity type
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
- const gp_Pnt& thePt2,
- const gp_Pnt& thePt3,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
+ const gp_Pnt& thePnt2,
+ const gp_Pnt& thePnt3,
Standard_Integer theSensType,
Standard_Real& theDepth) Standard_OVERRIDE;
//! Calculates the point on a view ray that was detected during the run of selection algo by given depth. Is valid for point
//! selection only
- Standard_EXPORT virtual NCollection_Vec3<Standard_Real> DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
+ Standard_EXPORT virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
//! Checks if the point of sensitive in which selection was detected belongs
//! to the region defined by clipping planes
Standard_EXPORT virtual Standard_Boolean IsOverlapAllowed() const Standard_OVERRIDE;
+ //! A set of helper functions that return rectangular selecting frustum data
+ Standard_EXPORT const gp_Pnt* GetVertices() const;
+
+ Standard_EXPORT gp_Pnt GetNearPnt() const;
+
+ Standard_EXPORT gp_Pnt GetFarPnt() const;
+
private:
enum { Frustum, FrustumSet, VolumeTypesNb }; //!< Defines the amount of available selecting volumes
: myMode (theModeIdx),
mySelectionState (SelectMgr_SOS_Unknown),
myBVHUpdateStatus (SelectMgr_TBU_None),
- mySensFactor (2.0)
+ mySensFactor (2)
{}
SelectMgr_Selection::~SelectMgr_Selection()
Handle(SelectMgr_SensitiveEntity)& anEntity = myEntities.ChangeValue (anEntityIdx);
anEntity->BaseSensitive()->Set (NULL);
}
- mySensFactor = 2.0;
+ mySensFactor = 2;
}
//==================================================
// function: Sensitivity
// purpose : Returns sensitivity of the selection
//==================================================
-Standard_Real SelectMgr_Selection::Sensitivity() const
+Standard_Integer SelectMgr_Selection::Sensitivity() const
{
return mySensFactor;
}
Standard_EXPORT void SetSelectionState (const SelectMgr_StateOfSelection theState) const;
//! Returns sensitivity of the selection
- Standard_EXPORT Standard_Real Sensitivity() const;
+ Standard_EXPORT Standard_Integer Sensitivity() const;
DEFINE_STANDARD_RTTI (SelectMgr_Selection, MMgt_TShared)
SelectMgr_TypeOfUpdate myUpdateStatus;
mutable SelectMgr_StateOfSelection mySelectionState;
mutable SelectMgr_TypeOfBVHUpdate myBVHUpdateStatus;
- Standard_Real mySensFactor;
+ Standard_Integer mySensFactor;
};
DEFINE_STANDARD_HANDLE(SelectMgr_Selection, MMgt_TShared)
void SelectMgr_SensitiveEntitySet::Swap (const Standard_Integer theIndex1,
const Standard_Integer theIndex2)
{
- const Handle(SelectMgr_SensitiveEntity) anEntity1 = GetSensitiveById (theIndex1);
- const Handle(SelectMgr_SensitiveEntity) anEntity2 = GetSensitiveById (theIndex2);
-
- mySensitives.Substitute (theIndex1 + 1, EMPTY_ENT);
- mySensitives.Substitute (theIndex2 + 1, anEntity1);
- mySensitives.Substitute (theIndex1 + 1, anEntity2);
+ mySensitives.Swap (theIndex1 + 1, theIndex2 + 1);
}
//=======================================================================
//! the performance of searching for overlap among sensitives of one selectable object
class SelectMgr_SensitiveEntitySet : public BVH_PrimitiveSet<Standard_Real, 3>
{
- Handle(SelectMgr_SensitiveEntity) EMPTY_ENT;
-
public:
Standard_EXPORT SelectMgr_SensitiveEntitySet();
#include <SelectMgr_TriangularFrustum.hxx>
-#define DOT(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z())
-#define DOTp(A, B) (A.x() * B.X() + A.y() * B.Y() + A.z() * B.Z())
-#define LENGTH(A) (std::sqrt (A.x() * A.x() + A.y() * A.y() + A.z() * A.z()))
-
SelectMgr_TriangularFrustum::~SelectMgr_TriangularFrustum()
{
Clear();
namespace
{
- void computeFrustumNormals (const SelectMgr_Vec3* theVertices, SelectMgr_Vec3* theNormals)
+ void computeFrustumNormals (const gp_Vec* theEdges, gp_Vec* theNormals)
{
// V0V1
- theNormals[0] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[0],
- theVertices[4] - theVertices[0]);
+ theNormals[0] = theEdges[0].Crossed (theEdges[1]);
// V1V2
- theNormals[1] = SelectMgr_Vec3::Cross (theVertices[4] - theVertices[1],
- theVertices[5] - theVertices[1]);
+ theNormals[1] = theEdges[1].Crossed (theEdges[2]);
// V0V2
- theNormals[2] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[0],
- theVertices[5] - theVertices[0]);
+ theNormals[2] = theEdges[0].Crossed (theEdges[2]);
// Near
- theNormals[3] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0],
- theVertices[2] - theVertices[0]);
+ theNormals[3] = theEdges[3].Crossed (theEdges[5]);
// Far
- theNormals[4] = SelectMgr_Vec3::Cross (theVertices[4] - theVertices[3],
- theVertices[5] - theVertices[3]);
+ theNormals[4] = -theNormals[3];
}
}
-//=======================================================================
-// function : SelectMgr_TriangularFrustum
-// purpose : Creates new triangular frustum with bases of triangles with
-// vertices theP1, theP2 and theP3 projections onto near and
-// far view frustum planes
-//=======================================================================
-void SelectMgr_TriangularFrustum::Build (const gp_Pnt2d& theP1,
- const gp_Pnt2d& theP2,
- const gp_Pnt2d& theP3)
+// =======================================================================
+// function : cacheVertexProjections
+// purpose : Caches projection of frustum's vertices onto its plane directions
+// and {i, j, k}
+// =======================================================================
+void SelectMgr_TriangularFrustum::cacheVertexProjections (SelectMgr_TriangularFrustum* theFrustum)
{
- // V0_Near
- myVertices[0] = myBuilder->ProjectPntOnViewPlane (theP1.X(), theP1.Y(), 0.0);
- // V1_Near
- myVertices[1] = myBuilder->ProjectPntOnViewPlane (theP2.X(), theP2.Y(), 0.0);
- // V2_Near
- myVertices[2] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 0.0);
- // V0_Far
- myVertices[3] = myBuilder->ProjectPntOnViewPlane (theP1.X(), theP1.Y(), 1.0);
- // V1_Far
- myVertices[4] = myBuilder->ProjectPntOnViewPlane (theP2.X(), theP2.Y(), 1.0);
- // V2_Far
- myVertices[5] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 1.0);
-
- computeFrustumNormals (myVertices, myPlanes);
-
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; ++aPlaneIdx)
{
Standard_Real aMax = -DBL_MAX;
Standard_Real aMin = DBL_MAX;
- const SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
+ const gp_XYZ& aPlane = theFrustum->myPlanes[aPlaneIdx].XYZ();
for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx)
{
- Standard_Real aProjection = DOT (aPlane, myVertices[aVertIdx]);
+ Standard_Real aProjection = aPlane.Dot (theFrustum->myVertices[aVertIdx].XYZ());
aMax = Max (aMax, aProjection);
aMin = Min (aMin, aProjection);
}
- myMaxVertsProjections[aPlaneIdx] = aMax;
- myMinVertsProjections[aPlaneIdx] = aMin;
+ theFrustum->myMaxVertsProjections[aPlaneIdx] = aMax;
+ theFrustum->myMinVertsProjections[aPlaneIdx] = aMin;
}
- SelectMgr_Vec3 aDimensions[3] =
- {
- SelectMgr_Vec3 (1.0, 0.0, 0.0),
- SelectMgr_Vec3 (0.0, 1.0, 0.0),
- SelectMgr_Vec3 (0.0, 0.0, 1.0)
- };
-
for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
{
Standard_Real aMax = -DBL_MAX;
Standard_Real aMin = DBL_MAX;
for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx)
{
- Standard_Real aProjection = DOT (aDimensions[aDim], myVertices[aVertIdx]);
+ Standard_Real aProjection = theFrustum->myVertices[aVertIdx].XYZ().GetData()[aDim];
aMax = Max (aMax, aProjection);
aMin = Min (aMin, aProjection);
}
- myMaxOrthoVertsProjections[aDim] = aMax;
- myMinOrthoVertsProjections[aDim] = aMin;
+ theFrustum->myMaxOrthoVertsProjections[aDim] = aMax;
+ theFrustum->myMinOrthoVertsProjections[aDim] = aMin;
}
+}
+
+//=======================================================================
+// function : SelectMgr_TriangularFrustum
+// purpose : Creates new triangular frustum with bases of triangles with
+// vertices theP1, theP2 and theP3 projections onto near and
+// far view frustum planes
+//=======================================================================
+void SelectMgr_TriangularFrustum::Build (const gp_Pnt2d& theP1,
+ const gp_Pnt2d& theP2,
+ const gp_Pnt2d& theP3)
+{
+ // V0_Near
+ myVertices[0] = myBuilder->ProjectPntOnViewPlane (theP1.X(), theP1.Y(), 0.0);
+ // V1_Near
+ myVertices[1] = myBuilder->ProjectPntOnViewPlane (theP2.X(), theP2.Y(), 0.0);
+ // V2_Near
+ myVertices[2] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 0.0);
+ // V0_Far
+ myVertices[3] = myBuilder->ProjectPntOnViewPlane (theP1.X(), theP1.Y(), 1.0);
+ // V1_Far
+ myVertices[4] = myBuilder->ProjectPntOnViewPlane (theP2.X(), theP2.Y(), 1.0);
+ // V2_Far
+ myVertices[5] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 1.0);
// V0_Near - V0_Far
- myEdgeDirs[0] = myVertices[0] - myVertices[3];
+ myEdgeDirs[0] = myVertices[0].XYZ() - myVertices[3].XYZ();
// V1_Near - V1_Far
- myEdgeDirs[1] = myVertices[1] - myVertices[4];
+ myEdgeDirs[1] = myVertices[1].XYZ() - myVertices[4].XYZ();
// V2_Near - V1_Far
- myEdgeDirs[2] = myVertices[2] - myVertices[5];
+ myEdgeDirs[2] = myVertices[2].XYZ() - myVertices[5].XYZ();
// V1_Near - V0_Near
- myEdgeDirs[3] = myVertices[1] - myVertices[0];
+ myEdgeDirs[3] = myVertices[1].XYZ() - myVertices[0].XYZ();
// V2_Near - V1_Near
- myEdgeDirs[4] = myVertices[2] - myVertices[1];
+ myEdgeDirs[4] = myVertices[2].XYZ() - myVertices[1].XYZ();
// V1_Near - V0_Near
- myEdgeDirs[5] = myVertices[2] - myVertices[0];
+ myEdgeDirs[5] = myVertices[2].XYZ() - myVertices[0].XYZ();
+
+ computeFrustumNormals (myEdgeDirs, myPlanes);
+
+ cacheVertexProjections (this);
}
//=======================================================================
-// function : Transform
-// purpose : Returns a copy of the frustum transformed according to the matrix given
+// function : ScaleAndTransform
+// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
+// Note that this method does not perform any checks on type of the frustum.
+// Returns a copy of the frustum resized according to the scale factor given
+// and transforms it using the matrix given.
+// There are no default parameters, but in case if:
+// - transformation only is needed: @theScaleFactor must be initialized
+// as any negative value;
+// - scale only is needed: @theTrsf must be set to gp_Identity.
//=======================================================================
-NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustum::Transform (const gp_Trsf& theTrsf)
+NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustum::ScaleAndTransform (const Standard_Integer /*theScale*/,
+ const gp_Trsf& theTrsf)
{
SelectMgr_TriangularFrustum* aRes = new SelectMgr_TriangularFrustum();
// V0_Near
- aRes->myVertices[0] = SelectMgr_MatOp::Transform (theTrsf, myVertices[0]);
+ aRes->myVertices[0] = myVertices[0].Transformed (theTrsf);
// V1_Near
- aRes->myVertices[1] = SelectMgr_MatOp::Transform (theTrsf, myVertices[1]);
+ aRes->myVertices[1] = myVertices[1].Transformed (theTrsf);
// V2_Near
- aRes->myVertices[2] = SelectMgr_MatOp::Transform (theTrsf, myVertices[2]);
+ aRes->myVertices[2] = myVertices[2].Transformed (theTrsf);
// V0_Far
- aRes->myVertices[3] = SelectMgr_MatOp::Transform (theTrsf, myVertices[3]);
+ aRes->myVertices[3] = myVertices[3].Transformed (theTrsf);
// V1_Far
- aRes->myVertices[4] = SelectMgr_MatOp::Transform (theTrsf, myVertices[4]);
+ aRes->myVertices[4] = myVertices[4].Transformed (theTrsf);
// V2_Far
- aRes->myVertices[5] = SelectMgr_MatOp::Transform (theTrsf, myVertices[5]);
+ aRes->myVertices[5] = myVertices[5].Transformed (theTrsf);
aRes->myIsOrthographic = myIsOrthographic;
- computeFrustumNormals (aRes->myVertices, aRes->myPlanes);
-
- for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; ++aPlaneIdx)
- {
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- const SelectMgr_Vec3 aPlane = aRes->myPlanes[aPlaneIdx];
- for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aPlane, aRes->myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- aRes->myMaxVertsProjections[aPlaneIdx] = aMax;
- aRes->myMinVertsProjections[aPlaneIdx] = aMin;
- }
-
- SelectMgr_Vec3 aDimensions[3] =
- {
- SelectMgr_Vec3 (1.0, 0.0, 0.0),
- SelectMgr_Vec3 (0.0, 1.0, 0.0),
- SelectMgr_Vec3 (0.0, 0.0, 1.0)
- };
-
- for (Standard_Integer aDim = 0; aDim < 3; ++aDim)
- {
- Standard_Real aMax = -DBL_MAX;
- Standard_Real aMin = DBL_MAX;
- for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++aVertIdx)
- {
- Standard_Real aProjection = DOT (aDimensions[aDim], aRes->myVertices[aVertIdx]);
- aMax = Max (aMax, aProjection);
- aMin = Min (aMin, aProjection);
- }
- aRes->myMaxOrthoVertsProjections[aDim] = aMax;
- aRes->myMinOrthoVertsProjections[aDim] = aMin;
- }
-
// V0_Near - V0_Far
- aRes->myEdgeDirs[0] = aRes->myVertices[0] - aRes->myVertices[3];
+ aRes->myEdgeDirs[0] = aRes->myVertices[0].XYZ() - aRes->myVertices[3].XYZ();
// V1_Near - V1_Far
- aRes->myEdgeDirs[1] = aRes->myVertices[1] - aRes->myVertices[4];
+ aRes->myEdgeDirs[1] = aRes->myVertices[1].XYZ() - aRes->myVertices[4].XYZ();
// V2_Near - V1_Far
- aRes->myEdgeDirs[2] = aRes->myVertices[2] - aRes->myVertices[5];
+ aRes->myEdgeDirs[2] = aRes->myVertices[2].XYZ() - aRes->myVertices[5].XYZ();
// V1_Near - V0_Near
- aRes->myEdgeDirs[3] = aRes->myVertices[1] - aRes->myVertices[0];
+ aRes->myEdgeDirs[3] = aRes->myVertices[1].XYZ() - aRes->myVertices[0].XYZ();
// V2_Near - V1_Near
- aRes->myEdgeDirs[4] = aRes->myVertices[2] - aRes->myVertices[1];
+ aRes->myEdgeDirs[4] = aRes->myVertices[2].XYZ() - aRes->myVertices[1].XYZ();
// V1_Near - V0_Near
- aRes->myEdgeDirs[5] = aRes->myVertices[2] - aRes->myVertices[0];
+ aRes->myEdgeDirs[5] = aRes->myVertices[2].XYZ() - aRes->myVertices[0].XYZ();
+
+ computeFrustumNormals (aRes->myEdgeDirs, aRes->myPlanes);
+
+ cacheVertexProjections (aRes);
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
}
// purpose : SAT intersection test between defined volume and
// given axis-aligned box
//=======================================================================
-Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
+Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const SelectMgr_Vec3& theMinPt,
+ const SelectMgr_Vec3& theMaxPt,
Standard_Real& /*theDepth*/)
{
- return hasOverlap (theBox.CornerMin(), theBox.CornerMax());
+ return hasOverlap (theMinPt, theMaxPt);
}
// =======================================================================
}
else if (theSensType == Select3D_TOS_INTERIOR)
{
- SelectMgr_Vec3 aNorm (RealLast());
+ gp_Vec aNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
return hasOverlap (theArrayOfPnts, aNorm);
}
}
else if (theSensType == Select3D_TOS_INTERIOR)
{
- SelectMgr_Vec3 aNorm (RealLast());
+ gp_Vec aNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
return hasOverlap (thePnt1, thePnt2, thePnt3, aNorm);
}
const gp_Pnt2d& theP3) Standard_OVERRIDE;
//! Returns a copy of the frustum transformed according to the matrix given
- Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
+ Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScale,
+ const gp_Trsf& theTrsf) Standard_OVERRIDE;
// SAT Tests for different objects
//! SAT intersection test between defined volume and given axis-aligned box
- Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
+ const SelectMgr_Vec3& theMaxPnt,
Standard_Real& theDepth) Standard_OVERRIDE;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box
//! Nullifies the handle to corresponding builder instance to prevent memory leaks
Standard_EXPORT void Clear();
+private:
+
+ void cacheVertexProjections (SelectMgr_TriangularFrustum* theFrustum);
+
DEFINE_STANDARD_RTTI(SelectMgr_TriangularFrustum,Standard_Transient)
};
}
// =======================================================================
-// function : Transform
-// purpose : Returns a copy of the frustum with all sub-volumes transformed
-// according to the matrix given
-// =======================================================================
-NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::Transform (const gp_Trsf& theTrsf)
+// function : ScaleAndTransform
+// purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
+// Note that this method does not perform any checks on type of the frustum.
+// Returns a copy of the frustum resized according to the scale factor given
+// and transforms it using the matrix given.
+// There are no default parameters, but in case if:
+// - transformation only is needed: @theScaleFactor must be initialized
+// as any negative value;
+// - scale only is needed: @theTrsf must be set to gp_Identity.
+// =======================================================================
+NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::ScaleAndTransform (const Standard_Integer theScale,
+ const gp_Trsf& theTrsf)
{
SelectMgr_TriangularFrustumSet* aRes = new SelectMgr_TriangularFrustumSet();
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
{
- aRes->myFrustums.Append (Handle(SelectMgr_TriangularFrustum)::DownCast (anIter.Value()->Transform (theTrsf)));
+ aRes->myFrustums.Append (Handle(SelectMgr_TriangularFrustum)::DownCast (anIter.Value()->ScaleAndTransform (theScale, theTrsf)));
}
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
// function : Overlaps
// purpose :
// =======================================================================
-Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
+Standard_Boolean SelectMgr_TriangularFrustumSet::Overlaps (const SelectMgr_Vec3& theMinPnt,
+ const SelectMgr_Vec3& theMaxPnt,
Standard_Real& theDepth)
{
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
{
- if (anIter.Value()->Overlaps (theBox, theDepth))
+ if (anIter.Value()->Overlaps (theMinPnt, theMaxPnt, theDepth))
return Standard_True;
}
Standard_EXPORT virtual void Build (const TColgp_Array1OfPnt2d& thePoints) Standard_OVERRIDE;
//! Returns a copy of the frustum with all sub-volumes transformed according to the matrix given
- Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE;
+ Standard_EXPORT virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScale,
+ const gp_Trsf& theTrsf) Standard_OVERRIDE;
- Standard_EXPORT virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
+ const SelectMgr_Vec3& theMaxPnt,
Standard_Real& theDepth) Standard_OVERRIDE;
Standard_EXPORT virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
const SelectMgr_Vec3& theMaxPnt,
Standard_Boolean* theInside) Standard_OVERRIDE;
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth) Standard_OVERRIDE;
- Standard_EXPORT virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
Select3D_TypeOfSensitivity theSensType,
Standard_Real& theDepth) Standard_OVERRIDE;
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
- const gp_Pnt& thePt2,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
+ const gp_Pnt& thePnt2,
Standard_Real& theDepth) Standard_OVERRIDE;
- Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1,
- const gp_Pnt& thePt2,
- const gp_Pnt& thePt3,
+ Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
+ const gp_Pnt& thePnt2,
+ const gp_Pnt& thePnt3,
Select3D_TypeOfSensitivity theSensType,
Standard_Real& theDepth) Standard_OVERRIDE;
//=======================================================================
SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
{
- myLargestKey = -1.0;
- myCustomTolerance = -1.0;
+ myLargestKey = -1;
+ myCustomTolerance = -1;
}
//=======================================================================
// purpose : Adds the value given to map, checks if the current tolerance value
// should be replaced by theTolerance
//=======================================================================
-void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
+void SelectMgr_ToleranceMap::Add (const Standard_Integer& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
{
// purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
// should be recalculated
//=======================================================================
-void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
+void SelectMgr_ToleranceMap::Decrement (const Standard_Integer& theTolerance)
{
if (myTolerances.IsBound (theTolerance))
{
if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
{
- myLargestKey = 0.0;
- for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
+ myLargestKey = 0;
+ for (NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
{
if (anIter.Value() != 0)
myLargestKey = Max (myLargestKey, anIter.Key());
&& sensitivity (theEntity) < myTolerances.Tolerance();
}
-//=======================================================================
-// function: scaleAndTransform
-// purpose : Applies given scale and transformation matrices to the default selecting volume manager
-//=======================================================================
-SelectMgr_SelectingVolumeManager SelectMgr_ViewerSelector::scaleAndTransform (const Standard_Real theScale,
- const gp_Trsf& theTrsf)
-{
- SelectMgr_SelectingVolumeManager aMgr;
-
- if (theScale > Precision::Angular())
- {
- aMgr = mySelectingVolumeMgr.Scale (theScale);
- }
-
- if (theTrsf.Form() != gp_Identity)
- {
- aMgr = aMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Unknown ?
- mySelectingVolumeMgr.Transform (theTrsf) : aMgr.Transform (theTrsf);
- }
-
- return aMgr;
-}
-
//=======================================================================
// function: sensitivity
// purpose : In case if custom tolerance is set, this method will return sum of entity
// sensitivity and custom tolerance.
//=======================================================================
-Standard_Real SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
+Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const
{
return myTolerances.IsCustomTolSet() ?
theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
Standard_Integer aPriority = anOwner->Priority();
- SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33, preferclosest);
+ SelectMgr_SortCriterion aCriterion (aPriority, aPickResult.Depth(), aPickResult.DistToGeomCenter(), theEntity->SensitivityFactor() / 33.0, preferclosest);
if (mystored.Contains (anOwner))
{
if (theMgr.GetActiveSelectionType() != 1)
}
}
+//=======================================================================
+// function: computeFrustum
+// purpose : Internal function that checks if a current selecting frustum
+// needs to be scaled and transformed for the entity and performs
+// necessary calculations
+//=======================================================================
+void SelectMgr_ViewerSelector::computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
+ const gp_Trsf& theInvTrsf,
+ SelectMgr_FrustumCache& theCachedMgrs,
+ SelectMgr_SelectingVolumeManager& theResMgr)
+{
+ Standard_Integer aScale = 1;
+ const Standard_Boolean toScale = isToScaleFrustum (theEnt);
+ if (toScale)
+ {
+ aScale = sensitivity (theEnt);
+ }
+ if (theEnt->HasInitLocation())
+ {
+ theResMgr =
+ mySelectingVolumeMgr.ScaleAndTransform (aScale, theEnt->InvInitLocation() * theInvTrsf);
+ }
+ else if (toScale)
+ {
+ if (!theCachedMgrs.IsBound (aScale))
+ {
+ theCachedMgrs.Bind (aScale,
+ mySelectingVolumeMgr.ScaleAndTransform(aScale, theInvTrsf));
+ }
+
+ theResMgr = theCachedMgrs.Find (aScale);
+ }
+}
+
//=======================================================================
// function: traverseObject
// purpose : Internal function that checks if there is possible overlap
}
SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
- ? mySelectingVolumeMgr.Transform (aInversedTrsf)
+ ? mySelectingVolumeMgr.ScaleAndTransform (1, aInversedTrsf)
: mySelectingVolumeMgr;
- NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums;
+ SelectMgr_FrustumCache aScaledTrnsfFrustums;
Standard_Integer aNode = 0; // a root node
if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
{
const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
- if (isToScaleFrustum (anEnt))
- {
- if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
- {
- aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
- scaleAndTransform (sensitivity (anEnt), aInversedTrsf));
- }
-
- aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
- }
+ computeFrustum (anEnt, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
checkOverlap (anEnt, anIdx, aTmpMgr);
}
}
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwnerDetectedEntities;
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer>::Iterator SelectMgr_MapOfOwnerDetectedEntitiesIterator;
+typedef NCollection_DataMap<Standard_Integer, SelectMgr_SelectingVolumeManager> SelectMgr_FrustumCache;
+
//! An internal class for calculation of current largest tolerance value which will be applied
//! for creation of selecting frustum by default. Each time the selection set is deactivated,
//! maximum tolerance value will be recalculated. If a user enables custom precision using
//! Adds the value given to map, checks if the current tolerance value
//! should be replaced by theTolerance
- Standard_EXPORT void Add (const Standard_Real& theTolerance);
+ Standard_EXPORT void Add (const Standard_Integer& theTolerance);
//! Decrements a counter of the tolerance given, checks if the current tolerance value
//! should be recalculated
- Standard_EXPORT void Decrement (const Standard_Real& theTolerance);
+ Standard_EXPORT void Decrement (const Standard_Integer& theTolerance);
//! Returns a current tolerance that must be applied
- inline Standard_Real Tolerance() const;
+ inline Standard_Integer Tolerance() const;
//! Sets tolerance to the given one and disables adaptive checks
- inline void SetCustomTolerance (const Standard_Real theTolerance);
+ inline void SetCustomTolerance (const Standard_Integer theTolerance);
//! Unsets a custom tolerance and enables adaptive checks
inline void ResetDefaults();
//! Returns the value of custom tolerance regardless of it validity
- inline Standard_Real CustomTolerance() const;
+ inline Standard_Integer CustomTolerance() const;
//! Returns true if custom tolerance value is greater than zero
inline Standard_Boolean IsCustomTolSet() const;
private:
- NCollection_DataMap<Standard_Real, Standard_Integer> myTolerances;
- Standard_Real myLargestKey;
- Standard_Real myCustomTolerance;
+ NCollection_DataMap<Standard_Integer, Standard_Integer> myTolerances;
+ Standard_Integer myLargestKey;
+ Standard_Integer myCustomTolerance;
};
//! A framework to define finding, sorting the sensitive
//! In case if custom tolerance is set, this method will return sum of entity sensitivity and
//! custom tolerance. Otherwise, pure entity sensitivity factor will be returned.
- Standard_Real sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const;
-
- //! Applies given scale and transformation matrices to the default selecting volume manager
- SelectMgr_SelectingVolumeManager scaleAndTransform (const Standard_Real theScale,
- const gp_Trsf& theTrsf);
+ Standard_Integer sensitivity (const Handle(SelectBasics_SensitiveEntity)& theEntity) const;
void Activate (const Handle(SelectMgr_Selection)& theSelection);
//! removes a Selection from the Selector
void Remove (const Handle(SelectMgr_Selection)& aSelection);
+ //! Internal function that checks if a current selecting frustum
+ //! needs to be scaled and transformed for the entity and performs
+ //! necessary calculations
+ void computeFrustum (const Handle(SelectBasics_SensitiveEntity)& theEnt,
+ const gp_Trsf& theInvTrsf,
+ SelectMgr_FrustumCache& theCachedMgrs,
+ SelectMgr_SelectingVolumeManager& theResMgr);
+
protected:
Standard_Boolean preferclosest;
// function: Tolerance
// purpose : Returns a current tolerance that must be applied
//=======================================================================
-inline Standard_Real SelectMgr_ToleranceMap::Tolerance() const
+inline Standard_Integer SelectMgr_ToleranceMap::Tolerance() const
{
if (myLargestKey < Precision::Confusion())
- return 2.0; // default tolerance value
+ return 2; // default tolerance value
- return myCustomTolerance < 0.0 ? myLargestKey : myLargestKey + myCustomTolerance;
+ return myCustomTolerance < 0 ? myLargestKey : myLargestKey + myCustomTolerance;
}
//=======================================================================
// function: SetCustomTolerance
// purpose : Sets tolerance to the given one and disables adaptive checks
//=======================================================================
-inline void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance)
+inline void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Integer theTolerance)
{
myCustomTolerance = theTolerance;
}
// function: CustomTolerance
// purpose : Returns current value of custom tolerance regardless of it is set or not
//=======================================================================
-inline Standard_Real SelectMgr_ToleranceMap::CustomTolerance() const
+inline Standard_Integer SelectMgr_ToleranceMap::CustomTolerance() const
{
return myCustomTolerance;
}
//=======================================================================
inline Standard_Boolean SelectMgr_ToleranceMap::IsCustomTolSet() const
{
- return myCustomTolerance > 0.0;
+ return myCustomTolerance > 0;
}
//=======================================================================
//=======================================================================
inline void SelectMgr_ToleranceMap::ResetDefaults()
{
- myCustomTolerance = -1.0;
+ myCustomTolerance = -1;
}
inline Standard_Real SelectMgr_ViewerSelector::Sensitivity() const
// Function: SetPixelTolerance
// Purpose :
//=======================================================================
-void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Real theTolerance)
+void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance)
{
if (myTolerances.Tolerance() != theTolerance)
{
- if (theTolerance < 0.0)
+ if (theTolerance < 0)
myTolerances.ResetDefaults();
else
myTolerances.SetCustomTolerance (theTolerance);
Standard_EXPORT StdSelect_ViewerSelector3d();
//! Sets the pixel tolerance <theTolerance>.
- Standard_EXPORT void SetPixelTolerance (const Standard_Real theTolerance);
+ Standard_EXPORT void SetPixelTolerance (const Standard_Integer theTolerance);
//! Returns the pixel tolerance.
- Standard_Real PixelTolerance() const;
+ inline Standard_Integer PixelTolerance() const;
//! Picks the sensitive entity at the pixel coordinates of
//! the mouse <theXPix> and <theYPix>. The selector looks for touched areas and owners.
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-inline Standard_Real StdSelect_ViewerSelector3d::PixelTolerance() const
+inline Standard_Integer StdSelect_ViewerSelector3d::PixelTolerance() const
{
return myTolerances.Tolerance();
}
anArg.LowerCase();
if (anArg == "-unset")
{
- aContext->SetPixelTolerance (-1.0);
+ aContext->SetPixelTolerance (-1);
}
else
{
- aContext->SetPixelTolerance (anArg.RealValue());
+ aContext->SetPixelTolerance (anArg.IntegerValue());
}
}
const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity();
Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
- SelectMgr_SelectingVolumeManager aMgr = anObj->HasTransformation() ? aSelector->GetManager().Transform (anObj->InversedTransformation())
- : aSelector->GetManager();
+ SelectMgr_SelectingVolumeManager aMgr =
+ anObj->HasTransformation() ? aSelector->GetManager().ScaleAndTransform (1, anObj->InversedTransformation())
+ : aSelector->GetManager();
SelectBasics_PickResult aResult;
anEntity->Matches (aMgr, aResult);
- NCollection_Vec3<Standard_Real> aDetectedPnt = aMgr.DetectedPoint (aResult.Depth());
+ gp_Pnt aDetectedPnt = aMgr.DetectedPoint (aResult.Depth());
TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
aName.LeftJustify (20, ' ');
" Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f",
aResult.Depth(),
aResult.DistToGeomCenter(),
- aDetectedPnt.x(), aDetectedPnt.y(), aDetectedPnt.z());
+ aDetectedPnt.X(), aDetectedPnt.Y(), aDetectedPnt.Z());
theDI << " " << aName
<< anInfoStr
<< " (" << anEntity->DynamicType()->Name() << ")"
Standard_Real& ChangeCoord (const Standard_Integer theIndex);
void Coord (Standard_Real& X, Standard_Real& Y, Standard_Real& Z) const;
+
+ //! Returns a const ptr to coordinates location.
+ //! Is useful for algorithms, but DOES NOT PERFORM
+ //! ANY CHECKS!
+ inline const Standard_Real* GetData() const { return (&x); }
+
+ //! Returns a ptr to coordinates location.
+ //! Is useful for algorithms, but DOES NOT PERFORM
+ //! ANY CHECKS!
+ inline Standard_Real* ChangeData() { return (&x); }
//! Returns the X coordinate
Standard_Real X() const;