1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

6 Commits

Author SHA1 Message Date
dbv
3b3c61fbf9 0026553: Out of range exception in BRepFill_Pipe::FindEdge
Test case for issue CR26553
Warning fix

Conflicts:
	src/QABugs/QABugs_19.cxx
2015-08-31 18:29:39 +03:00
vpa
09e3484fc0 0026462: Visualization - selection does not adapt to line width change
- added interface for changing sensitivity of a particular selection through both local and interactive context;
- added corresponding methods for changing sensitivity to SelectMgr_SelectionManager, SelectMgr_Selection and SelectBasics_SensitiveEntity;
- option -setSensitivity was implemented in vaspects Draw command;
- test case for issue #26462
2015-08-31 15:46:41 +03:00
vpa
1372b56bc2 0026195: Visualization - optimize selection algorithms
- initial transformation of triangulation is now applied to selecting frustum;
- switched from NCollection_Vec3 to gp collections to avoid conversions and usage of macros;
- calculation of frustum was refactored to reduce its build time;
- double pixel tolerances for selection were replaced by integer ones;
- switched to splitting along the main axis only in SelectMgr BVH selection primitive sets.
2015-08-31 06:43:42 +03:00
vpa
1521d40f5d 0026324: Visualization - fix iteration through corrupted memory in AIS_LocalContext::FindSelectedOwnerFromShape
The signature of SelectMgr_ViewerSelector::ActiveOwners is changed to return output parameter to avoid crash
2015-06-17 10:33:40 +03:00
apv
3a91994fed Test-cases for issues #26305 and #26315 2015-06-17 10:16:05 +03:00
ifv
0dec1a483d 0026305: BRepFeat_MakePrism returns inconsistent results && 026315: BRepFeat_MakeRevol fails to create revol from shape 2015-06-17 10:16:03 +03:00
63 changed files with 1830 additions and 1173 deletions

View File

@@ -428,8 +428,8 @@ is
-- Removes selection mode from Interactive Objects. -- Removes selection mode from Interactive Objects.
-- aMode provides the selection mode index of the entity aniobj. -- aMode provides the selection mode index of the entity aniobj.
SetPixelTolerance(me:mutable; SetPixelTolerance (me:mutable;
aPrecision: Real from Standard = 2.0); aPrecision: Integer from Standard = 2);
---Level: Public ---Level: Public
---Purpose: Disables the mechanism of adaptive tolerance calculation in SelectMgr_ViewerSelector and ---Purpose: Disables the mechanism of adaptive tolerance calculation in SelectMgr_ViewerSelector and
-- sets the given tolerance for ALL sensitive entities activated. For more information, see -- sets the given tolerance for ALL sensitive entities activated. For more information, see
@@ -437,12 +437,20 @@ is
-- Warning: When a local context is open the sensitivity is apply on it -- Warning: When a local context is open the sensitivity is apply on it
-- instead on the main context. -- instead on the main context.
PixelTolerance(me) returns Real from Standard; PixelTolerance(me) returns Integer from Standard;
---Level: Public ---Level: Public
---Purpose: Returns the pixel tolerance. ---Purpose: Returns the pixel tolerance.
---Category: put locations on objects.... ---Category: put locations on objects....
-- --
SetSelectionSensitivity (me : mutable;
theObject : InteractiveObject from AIS;
theMode : Integer from Standard;
theNewSensitivity : Integer from Standard);
---Purpose: Allows to manage sensitivity of a particular selection of interactive object theObject and
-- changes previous sensitivity value of all sensitive entities in selection with theMode to
-- the given theNewSensitivity.
SetLocation(me:mutable; SetLocation(me:mutable;
aniobj : InteractiveObject from AIS; aniobj : InteractiveObject from AIS;

View File

@@ -2596,7 +2596,7 @@ void AIS_InteractiveContext::UnsetSelectionMode (const Handle(AIS_InteractiveObj
// sensitive entities activated. For more information, see // sensitive entities activated. For more information, see
// SelectMgr_ViewerSelector.hxx // SelectMgr_ViewerSelector.hxx
//======================================================================= //=======================================================================
void AIS_InteractiveContext::SetPixelTolerance (const Standard_Real thePrecision) void AIS_InteractiveContext::SetPixelTolerance (const Standard_Integer thePrecision)
{ {
if (HasOpenedContext()) if (HasOpenedContext())
{ {
@@ -2612,13 +2612,30 @@ void AIS_InteractiveContext::SetPixelTolerance (const Standard_Real thePrecision
//function : PixelTolerance //function : PixelTolerance
//purpose : //purpose :
//======================================================================= //=======================================================================
Standard_Real AIS_InteractiveContext::PixelTolerance() const Standard_Integer AIS_InteractiveContext::PixelTolerance() const
{ {
return HasOpenedContext() return HasOpenedContext()
? myLocalContexts (myCurLocalIndex)->PixelTolerance() ? myLocalContexts (myCurLocalIndex)->PixelTolerance()
: myMainSel->PixelTolerance(); : myMainSel->PixelTolerance();
} }
//=======================================================================
//function : SetSelectionSensitivity
//purpose : Allows to manage sensitivity of a particular selection of interactive object theObject
//=======================================================================
void AIS_InteractiveContext::SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject,
const Standard_Integer theMode,
const Standard_Integer theNewSensitivity)
{
if (HasOpenedContext())
{
myLocalContexts (myCurLocalIndex)->SetSelectionSensitivity (theObject, theMode, theNewSensitivity);
return;
}
mgrSelector->SetSelectionSensitivity (theObject, theMode, theNewSensitivity);
}
//======================================================================= //=======================================================================
//function : IsInLocal //function : IsInLocal
//purpose : //purpose :
@@ -2677,7 +2694,7 @@ void AIS_InteractiveContext::InitAttributes()
aLineAspect->SetTypeOfLine (Aspect_TOL_DASH); aLineAspect->SetTypeOfLine (Aspect_TOL_DASH);
// tolerance to 2 pixels... // tolerance to 2 pixels...
SetPixelTolerance (2.0); SetPixelTolerance (2);
// Customizing the drawer for trihedrons and planes... // Customizing the drawer for trihedrons and planes...
Handle(Prs3d_DatumAspect) aTrihAspect = myDefaultDrawer->DatumAspect(); Handle(Prs3d_DatumAspect) aTrihAspect = myDefaultDrawer->DatumAspect();

View File

@@ -437,16 +437,24 @@ is
HiCol : out NameOfColor from Quantity) HiCol : out NameOfColor from Quantity)
returns Boolean from Standard; returns Boolean from Standard;
SetPixelTolerance(me:mutable; SetPixelTolerance (me:mutable;
aPrecision: Real from Standard = 2); aPrecision: Integer from Standard = 2);
---Level: Public ---Level: Public
---Purpose: Define the current selection sensitivity for ---Purpose: Define the current selection sensitivity for
-- this local context according to the view size. -- this local context according to the view size.
PixelTolerance(me) returns Real from Standard; PixelTolerance(me) returns Integer from Standard;
---Level: Public ---Level: Public
---Purpose: Returns the pixel tolerance. ---Purpose: Returns the pixel tolerance.
SetSelectionSensitivity (me : mutable;
theObject : InteractiveObject from AIS;
theMode : Integer from Standard;
theNewSensitivity : Integer from Standard);
---Purpose: Allows to manage sensitivity of a particular selection of interactive object theObject and
-- changes previous sensitivity value of all sensitive entities in selection with theMode to
-- the given theNewSensitivity.
---Category: IMMEDIATE MODE ---Category: IMMEDIATE MODE

View File

@@ -1139,12 +1139,23 @@ Standard_Boolean AIS_LocalContext::IsImmediateModeOn() const
return myMainPM->IsImmediateModeOn(); return myMainPM->IsImmediateModeOn();
} }
void AIS_LocalContext::SetPixelTolerance(const Standard_Real aPrecision) { void AIS_LocalContext::SetPixelTolerance(const Standard_Integer aPrecision) {
myMainVS->SetPixelTolerance(aPrecision); myMainVS->SetPixelTolerance(aPrecision);
} }
Standard_Real AIS_LocalContext::PixelTolerance() const { Standard_Integer AIS_LocalContext::PixelTolerance() const {
return myMainVS->PixelTolerance(); return myMainVS->PixelTolerance();
} }
//=======================================================================
//function : SetSelectionSensitivity
//purpose : Allows to manage sensitivity of a particular selection of interactive object theObject
//=======================================================================
void AIS_LocalContext::SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject,
const Standard_Integer theMode,
const Standard_Integer theNewSensitivity)
{
mySM->SetSelectionSensitivity (theObject, theMode, theNewSensitivity);
}

View File

@@ -1454,8 +1454,10 @@ Handle(SelectMgr_EntityOwner) AIS_LocalContext::FindSelectedOwnerFromShape(const
Standard_Boolean found(Standard_False); Standard_Boolean found(Standard_False);
if (!found) { if (!found) {
NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (myMainVS->ActiveOwners()); NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
for (; anOwnersIt.More(); anOwnersIt.Next()) { myMainVS->ActiveOwners (anActiveOwners);
for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners); anOwnersIt.More(); anOwnersIt.Next())
{
EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value()); EO = Handle(SelectMgr_EntityOwner)::DownCast (anOwnersIt.Value());
Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO); Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast(EO);
if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) { if (!BROwnr.IsNull() && BROwnr->HasShape() && BROwnr->Shape() == sh) {

View File

@@ -54,6 +54,7 @@
#include <LocOpe_CSIntersector.hxx> #include <LocOpe_CSIntersector.hxx>
#include <LocOpe_PntFace.hxx> #include <LocOpe_PntFace.hxx>
#include <LocOpe_BuildShape.hxx> #include <LocOpe_BuildShape.hxx>
#include <ElSLib.hxx>
#include <TColGeom_SequenceOfCurve.hxx> #include <TColGeom_SequenceOfCurve.hxx>
@@ -490,14 +491,9 @@ void BRepFeat::FaceUntil(const TopoDS_Shape& Sbase,
{ {
Bnd_Box B; Bnd_Box B;
BRepBndLib::Add(Sbase,B); BRepBndLib::Add(Sbase,B);
Standard_Real c[6], bnd; Standard_Real x[2], y[2], z[2];
B.Get(c[0],c[2],c[4],c[1],c[3],c[5]); B.Get(x[0],y[0],z[0],x[1],y[1],z[1]);
bnd = c[0]; Standard_Real diam = 10.*Sqrt(B.SquareExtent());
for(Standard_Integer i = 1 ; i < 6; i++) {
if(c[i] > bnd) bnd = c[i];
}
bnd = 10*bnd;
Handle(Geom_Surface) s = BRep_Tool::Surface(FUntil); Handle(Geom_Surface) s = BRep_Tool::Surface(FUntil);
Handle(Standard_Type) styp = s->DynamicType(); Handle(Standard_Type) styp = s->DynamicType();
@@ -507,16 +503,80 @@ void BRepFeat::FaceUntil(const TopoDS_Shape& Sbase,
} }
Handle(Geom_RectangularTrimmedSurface) str; Handle(Geom_RectangularTrimmedSurface) str;
if (styp == STANDARD_TYPE(Geom_Plane)) { if (styp == STANDARD_TYPE(Geom_Plane)) {
gp_Pln aPln = Handle(Geom_Plane)::DownCast(s)->Pln();
Standard_Real u, v, umin = RealLast(), umax = -umin,
vmin = RealLast(), vmax = -vmin;
for(Standard_Integer i = 0 ; i < 2; i++)
{
for(Standard_Integer j = 0; j < 2; j++)
{
for(Standard_Integer k = 0; k < 2; k++)
{
gp_Pnt aP(x[i], y[j], z[k]);
ElSLib::Parameters(aPln, aP, u, v);
if(u < umin)
umin = u;
if(u > umax)
umax = u;
if(v < vmin)
vmin = v;
if(v > vmax)
vmax = v;
}
}
}
umin -= diam;
umax += diam;
vmin -= diam;
vmax += diam;
str = new Geom_RectangularTrimmedSurface str = new Geom_RectangularTrimmedSurface
(s, bnd, -bnd, bnd, -bnd, Standard_True, Standard_True); (s, umin, umax, vmin, vmax, Standard_True, Standard_True);
} }
else if (styp == STANDARD_TYPE(Geom_CylindricalSurface)) { else if (styp == STANDARD_TYPE(Geom_CylindricalSurface)) {
gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(s)->Cylinder();
Standard_Real u, v, vmin = RealLast(), vmax = -vmin;
for(Standard_Integer i = 0 ; i < 2; i++)
{
for(Standard_Integer j = 0; j < 2; j++)
{
for(Standard_Integer k = 0; k < 2; k++)
{
gp_Pnt aP(x[i], y[j], z[k]);
ElSLib::Parameters(aCyl, aP, u, v);
if(v < vmin)
vmin = v;
if(v > vmax)
vmax = v;
}
}
}
vmin -= diam;
vmax += diam;
str = new Geom_RectangularTrimmedSurface str = new Geom_RectangularTrimmedSurface
(s, bnd, -bnd, Standard_False, Standard_True); (s, vmin, vmax, Standard_False, Standard_True);
} }
else if (styp == STANDARD_TYPE(Geom_ConicalSurface)) { else if (styp == STANDARD_TYPE(Geom_ConicalSurface)) {
gp_Cone aCon = Handle(Geom_ConicalSurface)::DownCast(s)->Cone();
Standard_Real u, v, vmin = RealLast(), vmax = -vmin;
for(Standard_Integer i = 0 ; i < 2; i++)
{
for(Standard_Integer j = 0; j < 2; j++)
{
for(Standard_Integer k = 0; k < 2; k++)
{
gp_Pnt aP(x[i], y[j], z[k]);
ElSLib::Parameters(aCon, aP, u, v);
if(v < vmin)
vmin = v;
if(v > vmax)
vmax = v;
}
}
}
vmin -= diam;
vmax += diam;
str = new Geom_RectangularTrimmedSurface str = new Geom_RectangularTrimmedSurface
(s, bnd, -bnd, Standard_False, Standard_True); (s, vmin, vmax, Standard_False, Standard_True);
} }
else { else {
FUntil.Nullify(); FUntil.Nullify();

View File

@@ -260,15 +260,15 @@ void BRepFeat_MakePrism::Perform(const Standard_Real Length)
if(myLShape.ShapeType() == TopAbs_WIRE) { if(myLShape.ShapeType() == TopAbs_WIRE) {
TopExp_Explorer ex1(VraiPrism, TopAbs_FACE); TopExp_Explorer ex1(VraiPrism, TopAbs_FACE);
for(; ex1.More(); ex1.Next()) { for(; ex1.More(); ex1.Next()) {
TopExp_Explorer ex2(ex1.Current(), TopAbs_WIRE); TopExp_Explorer ex2(ex1.Current(), TopAbs_WIRE);
for(; ex2.More(); ex2.Next()) { for(; ex2.More(); ex2.Next()) {
if(ex2.Current().IsSame(myLShape)) { if(ex2.Current().IsSame(myLShape)) {
FFace = TopoDS::Face(ex1.Current()); FFace = TopoDS::Face(ex1.Current());
found = Standard_True; found = Standard_True;
break; break;
} }
} }
if(found) break; if(found) break;
} }
} }
@@ -276,9 +276,9 @@ void BRepFeat_MakePrism::Perform(const Standard_Real Length)
for(; exp.More(); exp.Next()) { for(; exp.More(); exp.Next()) {
const TopoDS_Face& ff = TopoDS::Face(exp.Current()); const TopoDS_Face& ff = TopoDS::Face(exp.Current());
if(ToFuse(ff, FFace)) { if(ToFuse(ff, FFace)) {
TopTools_DataMapOfShapeListOfShape sl; TopTools_DataMapOfShapeListOfShape sl;
if(!FFace.IsSame(myPbase) && BRepFeat::IsInside(ff, FFace)) if(!FFace.IsSame(myPbase) && BRepFeat::IsInside(ff, FFace))
break; break;
} }
} }
} }
@@ -570,15 +570,17 @@ void BRepFeat_MakePrism::Perform(const TopoDS_Shape& From,
ASI2.Perform(scur); ASI2.Perform(scur);
TopAbs_Orientation OrU, OrF; TopAbs_Orientation OrU, OrF;
TopoDS_Face FFrom, FUntil; TopoDS_Face FFrom, FUntil;
Standard_Real ParF, ParU;
if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) { if (ASI1.IsDone() && ASI1.NbPoints(1) >=1) {
if (myFuse == 1) { if (myFuse == 1) {
OrU = ASI1.Point(1,1).Orientation(); OrU = ASI1.Point(1,1).Orientation();
} }
else { else {
OrU = ASI1.Point(1,ASI1.NbPoints(1)).Orientation(); OrU = ASI1.Point(1,ASI1.NbPoints(1)).Orientation();
} }
if(sens==-1) OrU = TopAbs::Reverse(OrU); if(sens==-1) OrU = TopAbs::Reverse(OrU);
FUntil = ASI1.Point(1,1).Face(); FUntil = ASI1.Point(1,1).Face();
ParU = ASI1.Point(1,1).Parameter();
} }
else { else {
NotDone(); NotDone();
@@ -589,12 +591,20 @@ void BRepFeat_MakePrism::Perform(const TopoDS_Shape& From,
OrF = ASI2.Point(1,1).Orientation(); OrF = ASI2.Point(1,1).Orientation();
if(sens==1) OrF = TopAbs::Reverse(OrF); if(sens==1) OrF = TopAbs::Reverse(OrF);
FFrom = ASI2.Point(1,1).Face(); FFrom = ASI2.Point(1,1).Face();
ParF = ASI2.Point(1,1).Parameter();
} }
else { else {
NotDone(); NotDone();
myStatusError = BRepFeat_NoIntersectF; myStatusError = BRepFeat_NoIntersectF;
return; return;
} }
if(tran > 0 && (Abs(ParU) < Abs(ParF)))
{
TopAbs_Orientation Or;
Or = OrU;
OrU = OrF;
OrF = Or;
}
TopoDS_Shape Comp; TopoDS_Shape Comp;
BRep_Builder B; BRep_Builder B;
B.MakeCompound(TopoDS::Compound(Comp)); B.MakeCompound(TopoDS::Compound(Comp));

View File

@@ -78,22 +78,22 @@ extern Standard_Boolean BRepFeat_GettraceFEAT();
#endif #endif
static void MajMap(const TopoDS_Shape&, // base static void MajMap(const TopoDS_Shape&, // base
const LocOpe_Revol&, const LocOpe_Revol&,
TopTools_DataMapOfShapeListOfShape&, // myMap TopTools_DataMapOfShapeListOfShape&, // myMap
TopoDS_Shape&, // myFShape TopoDS_Shape&, // myFShape
TopoDS_Shape&); // myLShape TopoDS_Shape&); // myLShape
static void VerifGluedFaces(const TopoDS_Face& theSkface, static void VerifGluedFaces(const TopoDS_Face& theSkface,
const TopoDS_Shape& thePbase, const TopoDS_Shape& thePbase,
Handle(Geom_Curve)& theBCurve, Handle(Geom_Curve)& theBCurve,
TColGeom_SequenceOfCurve& theCurves, TColGeom_SequenceOfCurve& theCurves,
LocOpe_Revol& theRevol, LocOpe_Revol& theRevol,
TopTools_DataMapOfShapeShape& theMap); TopTools_DataMapOfShapeShape& theMap);
static Standard_Boolean ToFuse(const TopoDS_Face& , static Standard_Boolean ToFuse(const TopoDS_Face& ,
const TopoDS_Face&); const TopoDS_Face&);
@@ -104,11 +104,11 @@ static Standard_Boolean ToFuse(const TopoDS_Face& ,
//======================================================================= //=======================================================================
void BRepFeat_MakeRevol::Init(const TopoDS_Shape& Sbase, void BRepFeat_MakeRevol::Init(const TopoDS_Shape& Sbase,
const TopoDS_Shape& Pbase, const TopoDS_Shape& Pbase,
const TopoDS_Face& Skface, const TopoDS_Face& Skface,
const gp_Ax1& Axis, const gp_Ax1& Axis,
const Standard_Integer Mode, const Standard_Integer Mode,
const Standard_Boolean Modify) const Standard_Boolean Modify)
{ {
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT(); Standard_Boolean trc = BRepFeat_GettraceFEAT();
@@ -140,7 +140,7 @@ void BRepFeat_MakeRevol::Init(const TopoDS_Shape& Sbase,
myJustGluer = Standard_False; myJustGluer = Standard_False;
//-------------- ifv //-------------- ifv
// mySkface.Nullify(); // mySkface.Nullify();
//-------------- ifv //-------------- ifv
@@ -171,7 +171,7 @@ void BRepFeat_MakeRevol::Init(const TopoDS_Shape& Sbase,
//======================================================================= //=======================================================================
void BRepFeat_MakeRevol::Add(const TopoDS_Edge& E, void BRepFeat_MakeRevol::Add(const TopoDS_Edge& E,
const TopoDS_Face& F) const TopoDS_Face& F)
{ {
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT(); Standard_Boolean trc = BRepFeat_GettraceFEAT();
@@ -237,13 +237,13 @@ void BRepFeat_MakeRevol::Perform(const Standard_Real Angle)
if(RevolComp) { if(RevolComp) {
/* /*
if (!mySkface.IsNull() || !mySlface.IsEmpty()) { if (!mySkface.IsNull() || !mySlface.IsEmpty()) {
for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) { for (exp.Init(mySbase,TopAbs_FACE); exp.More(); exp.Next()) {
if (exp.Current().IsSame(mySkface)) { if (exp.Current().IsSame(mySkface)) {
angledec = M_PI/5; // pourquoi pas angledec = M_PI/5; // pourquoi pas
if (myFuse) angledec = -angledec; if (myFuse) angledec = -angledec;
break; break;
} }
} }
} }
*/ */
mySkface.Nullify(); mySkface.Nullify();
@@ -252,7 +252,7 @@ void BRepFeat_MakeRevol::Perform(const Standard_Real Angle)
else theRevol.Perform(myPbase, myAxis, Angle, angledec); else theRevol.Perform(myPbase, myAxis, Angle, angledec);
TopoDS_Shape VraiRevol = theRevol.Shape(); TopoDS_Shape VraiRevol = theRevol.Shape();
MajMap(myPbase,theRevol,myMap,myFShape,myLShape); MajMap(myPbase,theRevol,myMap,myFShape,myLShape);
myGShape = VraiRevol; myGShape = VraiRevol;
@@ -268,32 +268,32 @@ void BRepFeat_MakeRevol::Perform(const Standard_Real Angle)
} }
TopoDS_Face FFace; TopoDS_Face FFace;
Standard_Boolean found = Standard_False; Standard_Boolean found = Standard_False;
if(!mySkface.IsNull() || !mySlface.IsEmpty()) { if(!mySkface.IsNull() || !mySlface.IsEmpty()) {
if(myLShape.ShapeType() == TopAbs_WIRE) { if(myLShape.ShapeType() == TopAbs_WIRE) {
TopExp_Explorer ex1(VraiRevol, TopAbs_FACE); TopExp_Explorer ex1(VraiRevol, TopAbs_FACE);
for(; ex1.More(); ex1.Next()) { for(; ex1.More(); ex1.Next()) {
TopExp_Explorer ex2(ex1.Current(), TopAbs_WIRE); TopExp_Explorer ex2(ex1.Current(), TopAbs_WIRE);
for(; ex2.More(); ex2.Next()) { for(; ex2.More(); ex2.Next()) {
if(ex2.Current().IsSame(myLShape)) { if(ex2.Current().IsSame(myLShape)) {
FFace = TopoDS::Face(ex1.Current()); FFace = TopoDS::Face(ex1.Current());
found = Standard_True; found = Standard_True;
break; break;
} }
} }
if(found) break; if(found) break;
} }
} }
TopExp_Explorer exp(mySbase, TopAbs_FACE); TopExp_Explorer exp(mySbase, TopAbs_FACE);
for(; exp.More(); exp.Next()) { for(; exp.More(); exp.Next()) {
const TopoDS_Face& ff = TopoDS::Face(exp.Current()); const TopoDS_Face& ff = TopoDS::Face(exp.Current());
if(ToFuse(ff, FFace)) { if(ToFuse(ff, FFace)) {
TopTools_DataMapOfShapeListOfShape sl; TopTools_DataMapOfShapeListOfShape sl;
if(!FFace.IsSame(myPbase) && BRepFeat::IsInside(ff, FFace)) if(!FFace.IsSame(myPbase) && BRepFeat::IsInside(ff, FFace))
break; break;
} }
} }
} }
@@ -372,8 +372,8 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& Until)
Standard_Boolean Trf = TransformShapeFU(1); Standard_Boolean Trf = TransformShapeFU(1);
ShapeUntilValid(); ShapeUntilValid();
// Do systematically almost complete revolution // Do systematically almost complete revolution
// BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular()); // BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular());
LocOpe_Revol theRevol; LocOpe_Revol theRevol;
if(!TourComplet) { if(!TourComplet) {
Angle = 2.*M_PI- 3*M_PI/180.; Angle = 2.*M_PI- 3*M_PI/180.;
@@ -387,10 +387,10 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& Until)
if(!Trf) { if(!Trf) {
myGShape = VraiRevol; myGShape = VraiRevol;
GeneratedShapeValid(); GeneratedShapeValid();
TopoDS_Shape Base = theRevol.FirstShape(); TopoDS_Shape Base = theRevol.FirstShape();
exp.Init(Base, TopAbs_FACE); exp.Init(Base, TopAbs_FACE);
TopoDS_Face theBase = TopoDS::Face(exp.Current()); TopoDS_Face theBase = TopoDS::Face(exp.Current());
@@ -430,79 +430,79 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& Until)
TopoDS_Shape Cutsh = trP.Shape(); TopoDS_Shape Cutsh = trP.Shape();
TopExp_Explorer ex(Cutsh, TopAbs_SOLID); TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
for(; ex.More(); ex.Next()) { for(; ex.More(); ex.Next()) {
TopExp_Explorer ex1(ex.Current(), TopAbs_FACE); TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
for(; ex1.More(); ex1.Next()) { for(; ex1.More(); ex1.Next()) {
const TopoDS_Face& fac = TopoDS::Face(ex1.Current()); const TopoDS_Face& fac = TopoDS::Face(ex1.Current());
if(fac.IsSame(myPbase)) { if(fac.IsSame(myPbase)) {
VraiRevol = ex.Current(); VraiRevol = ex.Current();
break; break;
} }
} }
} }
if(myFuse == 1) { if(myFuse == 1) {
//modified by NIZNHY-PKV Thu Mar 21 18:17:53 2002 f //modified by NIZNHY-PKV Thu Mar 21 18:17:53 2002 f
//BRepAlgo_Fuse f(mySbase, VraiRevol); //BRepAlgo_Fuse f(mySbase, VraiRevol);
//myShape = f.Shape(); //myShape = f.Shape();
//UpdateDescendants(f.Builder(), myShape, Standard_False); //UpdateDescendants(f.Builder(), myShape, Standard_False);
BRepAlgoAPI_Fuse f(mySbase, VraiRevol); BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
myShape = f.Shape(); myShape = f.Shape();
UpdateDescendants(f, myShape, Standard_False); UpdateDescendants(f, myShape, Standard_False);
//modified by NIZNHY-PKV Thu Mar 21 18:17:57 2002 t //modified by NIZNHY-PKV Thu Mar 21 18:17:57 2002 t
Done(); Done();
} }
else if(myFuse == 0) { else if(myFuse == 0) {
//modified by NIZNHY-PKV Thu Mar 21 18:18:23 2002 f //modified by NIZNHY-PKV Thu Mar 21 18:18:23 2002 f
//BRepAlgo_Cut c(mySbase, VraiRevol); //BRepAlgo_Cut c(mySbase, VraiRevol);
//myShape = c.Shape(); //myShape = c.Shape();
//UpdateDescendants(c.Builder(), myShape, Standard_False); //UpdateDescendants(c.Builder(), myShape, Standard_False);
BRepAlgoAPI_Cut c(mySbase, VraiRevol); BRepAlgoAPI_Cut c(mySbase, VraiRevol);
myShape = c.Shape(); myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False); UpdateDescendants(c, myShape, Standard_False);
//modified by NIZNHY-PKV Thu Mar 21 18:18:28 2002 t //modified by NIZNHY-PKV Thu Mar 21 18:18:28 2002 t
Done(); Done();
} }
else { else {
myShape = VraiRevol; myShape = VraiRevol;
Done(); Done();
} }
} }
} }
// Loop of control of descendance // Loop of control of descendance
/* /*
TopExp_Explorer expr(mySbase, TopAbs_FACE); TopExp_Explorer expr(mySbase, TopAbs_FACE);
char nom1[20], nom2[20]; char nom1[20], nom2[20];
Standard_Integer ii = 0; Standard_Integer ii = 0;
for(; expr.More(); expr.Next()) { for(; expr.More(); expr.Next()) {
ii++; ii++;
sprintf(nom1, "faceinitial_%d", ii); sprintf(nom1, "faceinitial_%d", ii);
DBRep::Set(nom1, expr.Current()); DBRep::Set(nom1, expr.Current());
Standard_Integer jj = 0; Standard_Integer jj = 0;
const TopTools_ListOfShape& list = Modified(expr.Current()); const TopTools_ListOfShape& list = Modified(expr.Current());
TopTools_ListIteratorOfListOfShape ite(list); TopTools_ListIteratorOfListOfShape ite(list);
for(; ite.More(); ite.Next()) { for(; ite.More(); ite.Next()) {
jj++; jj++;
sprintf(nom2, "facemodifie_%d_%d", ii, jj); sprintf(nom2, "facemodifie_%d_%d", ii, jj);
DBRep::Set(nom2, ite.Value()); DBRep::Set(nom2, ite.Value());
}
} }
}
expr.Init(myPbase, TopAbs_EDGE); expr.Init(myPbase, TopAbs_EDGE);
ii=0; ii=0;
for(; expr.More(); expr.Next()) { for(; expr.More(); expr.Next()) {
ii++; ii++;
sprintf(nom1, "edgeinitial_%d", ii); sprintf(nom1, "edgeinitial_%d", ii);
DBRep::Set(nom1, expr.Current()); DBRep::Set(nom1, expr.Current());
Standard_Integer jj = 0; Standard_Integer jj = 0;
const TopTools_ListOfShape& list = Generated(expr.Current()); const TopTools_ListOfShape& list = Generated(expr.Current());
TopTools_ListIteratorOfListOfShape ite(list); TopTools_ListIteratorOfListOfShape ite(list);
for(; ite.More(); ite.Next()) { for(; ite.More(); ite.Next()) {
jj++; jj++;
sprintf(nom2, "facegeneree_%d_%d", ii, jj); sprintf(nom2, "facegeneree_%d_%d", ii, jj);
DBRep::Set(nom2, ite.Value()); DBRep::Set(nom2, ite.Value());
}
} }
*/ }
} */
}
//======================================================================= //=======================================================================
@@ -511,7 +511,7 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& Until)
//======================================================================= //=======================================================================
void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From, void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
const TopoDS_Shape& Until) const TopoDS_Shape& Until)
{ {
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT(); Standard_Boolean trc = BRepFeat_GettraceFEAT();
@@ -553,7 +553,7 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
mySUntil = Until; mySUntil = Until;
Standard_Boolean Trfu = TransformShapeFU(1); Standard_Boolean Trfu = TransformShapeFU(1);
ShapeUntilValid(); ShapeUntilValid();
if(Trfu != Trff) { if(Trfu != Trff) {
NotDone(); NotDone();
myStatusError = BRepFeat_IncTypes; myStatusError = BRepFeat_IncTypes;
@@ -570,7 +570,7 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
myGShape = VraiRevol; myGShape = VraiRevol;
GeneratedShapeValid(); GeneratedShapeValid();
GluedFacesValid(); GluedFacesValid();
// VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF); // VerifGluedFaces(mySkface, theBase, myBCurve, myCurves, theRevol, myGluedF);
theRevol.Curves(myCurves); theRevol.Curves(myCurves);
myBCurve = theRevol.BarycCurve(); myBCurve = theRevol.BarycCurve();
@@ -604,7 +604,8 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
pr1 = ElCLib::InPeriod(pr1,PrU-2*M_PI,PrU); pr1 = ElCLib::InPeriod(pr1,PrU-2*M_PI,PrU);
Standard_Real pr2 = ASI2.Point(1,ASI2.NbPoints(1)).Parameter(); Standard_Real pr2 = ASI2.Point(1,ASI2.NbPoints(1)).Parameter();
pr2 = ElCLib::InPeriod(pr2,PrU-2*M_PI,PrU); pr2 = ElCLib::InPeriod(pr2,PrU-2*M_PI,PrU);
OrF = OrU; //OrF = OrU;
OrF = TopAbs::Reverse(OrU);
FFrom = ASI2.Point(1,1).Face(); FFrom = ASI2.Point(1,1).Face();
PrF = Max(pr1, pr2); PrF = Max(pr1, pr2);
} }
@@ -631,18 +632,18 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
//modified by NIZNHY-PKV Thu Mar 21 18:18:57 2002 t //modified by NIZNHY-PKV Thu Mar 21 18:18:57 2002 t
TopoDS_Shape Cutsh = trP.Shape(); TopoDS_Shape Cutsh = trP.Shape();
TopExp_Explorer ex(Cutsh, TopAbs_SOLID); TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
// Standard_Real PrF = BRepFeat::ParametricBarycenter(mySFrom, myBCurve); // Standard_Real PrF = BRepFeat::ParametricBarycenter(mySFrom, myBCurve);
// Standard_Real PrU = BRepFeat::ParametricBarycenter(mySUntil, myBCurve); // Standard_Real PrU = BRepFeat::ParametricBarycenter(mySUntil, myBCurve);
VraiRevol = ex.Current(); VraiRevol = ex.Current();
for(; ex.More(); ex.Next()) { for(; ex.More(); ex.Next()) {
Standard_Real PrCur = BRepFeat:: Standard_Real PrCur = BRepFeat::
ParametricBarycenter(ex.Current(), myBCurve); ParametricBarycenter(ex.Current(), myBCurve);
if(PrF <= PrCur && PrU >= PrCur) { if(PrF <= PrCur && PrU >= PrCur) {
VraiRevol = ex.Current(); VraiRevol = ex.Current();
break; break;
} }
} }
if(myFuse == 1) { if(myFuse == 1 && !myJustFeat) {
//modified by NIZNHY-PKV Thu Mar 21 18:19:14 2002 f //modified by NIZNHY-PKV Thu Mar 21 18:19:14 2002 f
//BRepAlgo_Fuse f(mySbase, VraiRevol); //BRepAlgo_Fuse f(mySbase, VraiRevol);
//myShape = f.Shape(); //myShape = f.Shape();
@@ -653,7 +654,7 @@ void BRepFeat_MakeRevol::Perform(const TopoDS_Shape& From,
//modified by NIZNHY-PKV Thu Mar 21 18:19:18 2002 t //modified by NIZNHY-PKV Thu Mar 21 18:19:18 2002 t
Done(); Done();
} }
else if(myFuse == 0) { else if(myFuse == 0 && !myJustFeat) {
//modified by NIZNHY-PKV Thu Mar 21 18:19:46 2002 f //modified by NIZNHY-PKV Thu Mar 21 18:19:46 2002 f
//BRepAlgo_Cut c(mySbase, VraiRevol); //BRepAlgo_Cut c(mySbase, VraiRevol);
//myShape = c.Shape(); //myShape = c.Shape();
@@ -692,7 +693,7 @@ void BRepFeat_MakeRevol::PerformThruAll()
//======================================================================= //=======================================================================
void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until, void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until,
const Standard_Real Angle) const Standard_Real Angle)
{ {
#ifdef OCCT_DEBUG #ifdef OCCT_DEBUG
Standard_Boolean trc = BRepFeat_GettraceFEAT(); Standard_Boolean trc = BRepFeat_GettraceFEAT();
@@ -721,8 +722,8 @@ void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until,
Standard_Boolean Trf = TransformShapeFU(1); Standard_Boolean Trf = TransformShapeFU(1);
ShapeUntilValid(); ShapeUntilValid();
// Produce systematicallt an almost complete revolution // Produce systematicallt an almost complete revolution
// BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular()); // BRepSweep_Revol theRevol(myPbase,myAxis,2.*M_PI-10.*Precision::Angular());
LocOpe_Revol theRevol; LocOpe_Revol theRevol;
theRevol.Perform(myPbase, myAxis, Angle); theRevol.Perform(myPbase, myAxis, Angle);
TopoDS_Shape VraiRevol = theRevol.Shape(); TopoDS_Shape VraiRevol = theRevol.Shape();
@@ -732,7 +733,7 @@ void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until,
if(Trf) { if(Trf) {
myGShape = VraiRevol; myGShape = VraiRevol;
GeneratedShapeValid(); GeneratedShapeValid();
TopoDS_Shape Base = theRevol.FirstShape(); TopoDS_Shape Base = theRevol.FirstShape();
exp.Init(Base, TopAbs_FACE); exp.Init(Base, TopAbs_FACE);
TopoDS_Face theBase = TopoDS::Face(exp.Current()); TopoDS_Face theBase = TopoDS::Face(exp.Current());
@@ -773,40 +774,40 @@ void BRepFeat_MakeRevol::PerformUntilAngle(const TopoDS_Shape& Until,
TopoDS_Shape Cutsh = trP.Shape(); TopoDS_Shape Cutsh = trP.Shape();
TopExp_Explorer ex(Cutsh, TopAbs_SOLID); TopExp_Explorer ex(Cutsh, TopAbs_SOLID);
for(; ex.More(); ex.Next()) { for(; ex.More(); ex.Next()) {
TopExp_Explorer ex1(ex.Current(), TopAbs_FACE); TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
for(; ex1.More(); ex1.Next()) { for(; ex1.More(); ex1.Next()) {
const TopoDS_Face& fac = TopoDS::Face(ex1.Current()); const TopoDS_Face& fac = TopoDS::Face(ex1.Current());
if(fac.IsSame(myPbase)) { if(fac.IsSame(myPbase)) {
VraiRevol = ex.Current(); VraiRevol = ex.Current();
break; break;
} }
} }
} }
if(myFuse == 1) { if(myFuse == 1) {
//modified by NIZNHY-PKV Thu Mar 21 18:20:36 2002 f //modified by NIZNHY-PKV Thu Mar 21 18:20:36 2002 f
//BRepAlgo_Fuse f(mySbase, VraiRevol); //BRepAlgo_Fuse f(mySbase, VraiRevol);
//myShape = f.Shape(); //myShape = f.Shape();
//UpdateDescendants(f.Builder(), myShape, Standard_False); //UpdateDescendants(f.Builder(), myShape, Standard_False);
BRepAlgoAPI_Fuse f(mySbase, VraiRevol); BRepAlgoAPI_Fuse f(mySbase, VraiRevol);
myShape = f.Shape(); myShape = f.Shape();
UpdateDescendants(f, myShape, Standard_False); UpdateDescendants(f, myShape, Standard_False);
//modified by NIZNHY-PKV Thu Mar 21 18:20:40 2002 t //modified by NIZNHY-PKV Thu Mar 21 18:20:40 2002 t
Done(); Done();
} }
else if(myFuse == 0) { else if(myFuse == 0) {
//modified by NIZNHY-PKV Thu Mar 21 18:21:07 2002 f //modified by NIZNHY-PKV Thu Mar 21 18:21:07 2002 f
//BRepAlgo_Cut c(mySbase, VraiRevol); //BRepAlgo_Cut c(mySbase, VraiRevol);
//myShape = c.Shape(); //myShape = c.Shape();
//UpdateDescendants(c.Builder(), myShape, Standard_False); //UpdateDescendants(c.Builder(), myShape, Standard_False);
BRepAlgoAPI_Cut c(mySbase, VraiRevol); BRepAlgoAPI_Cut c(mySbase, VraiRevol);
myShape = c.Shape(); myShape = c.Shape();
UpdateDescendants(c, myShape, Standard_False); UpdateDescendants(c, myShape, Standard_False);
//modified by NIZNHY-PKV Thu Mar 21 18:21:26 2002 t //modified by NIZNHY-PKV Thu Mar 21 18:21:26 2002 t
Done(); Done();
} }
else { else {
myShape = VraiRevol; myShape = VraiRevol;
Done(); Done();
} }
} }
} }
@@ -838,15 +839,15 @@ Handle(Geom_Curve) BRepFeat_MakeRevol::BarycCurve()
//======================================================================= //=======================================================================
static void VerifGluedFaces(const TopoDS_Face& theSkface, static void VerifGluedFaces(const TopoDS_Face& theSkface,
const TopoDS_Shape& thePbase, const TopoDS_Shape& thePbase,
Handle(Geom_Curve)& theBCurve, Handle(Geom_Curve)& theBCurve,
TColGeom_SequenceOfCurve& theCurves, TColGeom_SequenceOfCurve& theCurves,
LocOpe_Revol& theRevol, LocOpe_Revol& theRevol,
TopTools_DataMapOfShapeShape& theMap) TopTools_DataMapOfShapeShape& theMap)
{ {
Standard_Boolean GluedFaces = Standard_True; Standard_Boolean GluedFaces = Standard_True;
TopoDS_Shape VraiRevol = theRevol.Shape(); TopoDS_Shape VraiRevol = theRevol.Shape();
TColGeom_SequenceOfCurve scur; TColGeom_SequenceOfCurve scur;
theRevol.Curves(theCurves); theRevol.Curves(theCurves);
theBCurve = theRevol.BarycCurve(); theBCurve = theRevol.BarycCurve();
@@ -871,13 +872,13 @@ static void VerifGluedFaces(const TopoDS_Face& theSkface,
for(; ex.More(); ex.Next()) { for(; ex.More(); ex.Next()) {
TopExp_Explorer ex1(ex.Current(), TopAbs_FACE); TopExp_Explorer ex1(ex.Current(), TopAbs_FACE);
for(; ex1.More(); ex1.Next()) { for(; ex1.More(); ex1.Next()) {
const TopoDS_Face& fac1 = TopoDS::Face(ex1.Current()); const TopoDS_Face& fac1 = TopoDS::Face(ex1.Current());
TopExp_Explorer ex2(thePbase, TopAbs_FACE); TopExp_Explorer ex2(thePbase, TopAbs_FACE);
for(; ex2.More(); ex2.Next()) { for(; ex2.More(); ex2.Next()) {
const TopoDS_Face& fac2 = TopoDS::Face(ex2.Current()); const TopoDS_Face& fac2 = TopoDS::Face(ex2.Current());
if(fac1.IsSame(fac2)) break; if(fac1.IsSame(fac2)) break;
} }
if (ex2.More()) break; if (ex2.More()) break;
} }
if (ex1.More()) continue; if (ex1.More()) continue;
GluedFaces = Standard_False; GluedFaces = Standard_False;
@@ -899,10 +900,10 @@ static void VerifGluedFaces(const TopoDS_Face& theSkface,
//======================================================================= //=======================================================================
static void MajMap(const TopoDS_Shape& theB, static void MajMap(const TopoDS_Shape& theB,
const LocOpe_Revol& theP, const LocOpe_Revol& theP,
TopTools_DataMapOfShapeListOfShape& theMap, // myMap TopTools_DataMapOfShapeListOfShape& theMap, // myMap
TopoDS_Shape& theFShape, // myFShape TopoDS_Shape& theFShape, // myFShape
TopoDS_Shape& theLShape) // myLShape TopoDS_Shape& theLShape) // myLShape
{ {
TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE); TopExp_Explorer exp(theP.FirstShape(),TopAbs_WIRE);
if (exp.More()) { if (exp.More()) {
@@ -913,7 +914,7 @@ static void MajMap(const TopoDS_Shape& theB,
theMap(theFShape).Append(exp.Current()); theMap(theFShape).Append(exp.Current());
} }
} }
exp.Init(theP.LastShape(),TopAbs_WIRE); exp.Init(theP.LastShape(),TopAbs_WIRE);
if (exp.More()) { if (exp.More()) {
theLShape = exp.Current(); theLShape = exp.Current();
@@ -941,7 +942,7 @@ static void MajMap(const TopoDS_Shape& theB,
//======================================================================= //=======================================================================
Standard_Boolean ToFuse(const TopoDS_Face& F1, Standard_Boolean ToFuse(const TopoDS_Face& F1,
const TopoDS_Face& F2) const TopoDS_Face& F2)
{ {
if (F1.IsNull() || F2.IsNull()) { if (F1.IsNull() || F2.IsNull()) {
return Standard_False; return Standard_False;

View File

@@ -798,14 +798,14 @@ Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
case TopAbs_WIRE : case TopAbs_WIRE :
{ {
Standard_Integer ii = InitialLength+1;
Handle(BRepFill_ShapeLaw) Section = Handle(BRepFill_ShapeLaw) Section =
new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False); new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
InitialLength += Section->NbLaw(); Standard_Integer NbLaw = Section->NbLaw();
for (; (ii<=InitialLength) && (!result); ii++) { for (Standard_Integer ii = 1; (ii<=NbLaw) && (!result); ii++) {
if (E.IsSame(Section->Edge(ii)) ) result = ii; if (E.IsSame(Section->Edge(ii)) ) result = InitialLength + ii;
} }
InitialLength += NbLaw;
break; break;
} }

View File

@@ -187,7 +187,6 @@ void IVtkOCC_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSel
theSelection->SetSelectionState (SelectMgr_SOS_Activated); theSelection->SetSelectionState (SelectMgr_SOS_Activated);
myTolerances.Add (theSelection->Sensitivity()); myTolerances.Add (theSelection->Sensitivity());
mytolerance = myTolerances.Tolerance();
myToUpdateTolerance = Standard_True; myToUpdateTolerance = Standard_True;
} }
@@ -205,6 +204,5 @@ void IVtkOCC_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theS
theSelection->SetSelectionState (SelectMgr_SOS_Deactivated); theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
myTolerances.Decrement (theSelection->Sensitivity()); myTolerances.Decrement (theSelection->Sensitivity());
mytolerance = myTolerances.Tolerance();
myToUpdateTolerance = Standard_True; myToUpdateTolerance = Standard_True;
} }

View File

@@ -71,3 +71,21 @@ void MeshVS_DummySensitiveEntity::BVH()
//================================================================ //================================================================
void MeshVS_DummySensitiveEntity::Clear() 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();
}

View File

@@ -48,6 +48,10 @@ public:
Standard_EXPORT virtual void Clear() Standard_OVERRIDE; 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) DEFINE_STANDARD_RTTI(MeshVS_DummySensitiveEntity)
}; };

View File

@@ -3866,6 +3866,220 @@ static Standard_Integer OCC24923(
return 0; return 0;
} }
//=======================================================================
//function : OCC26195
//purpose :
//=======================================================================
#include <AIS_Line.hxx>
#include <Aspect_Window.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <Geom_CartesianPoint.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Visual3d_View.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;
}
//=======================================================================
//function : OCC26462
//purpose :
//=======================================================================
static Standard_Integer OCC26462 (Draw_Interpretor& theDI, Standard_Integer /*theArgNb*/, const char** /*theArgVec*/)
{
if (ViewerTest::GetAISContext().IsNull())
{
std::cerr << "Error: No opened context!\n";
return 1;
}
BRepPrimAPI_MakeBox aBuilder1 (gp_Pnt (10.0, 10.0, 0.0), 10.0, 10.0, 10.0);
BRepPrimAPI_MakeBox aBuilder2 (10.0, 10.0, 10.0);
Handle(AIS_InteractiveObject) aBox1 = new AIS_Shape (aBuilder1.Shape());
Handle(AIS_InteractiveObject) aBox2 = new AIS_Shape (aBuilder2.Shape());
const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext();
aCtx->OpenLocalContext();
aCtx->Display (aBox1, 0, 2);
aCtx->Display (aBox2, 0, 2);
ViewerTest::CurrentView()->FitAll();
aCtx->SetWidth (aBox1, 3);
aCtx->SetWidth (aBox2, 3);
aCtx->MoveTo (305, 322, ViewerTest::CurrentView());
aCtx->ShiftSelect();
aCtx->MoveTo (103, 322, ViewerTest::CurrentView());
aCtx->ShiftSelect();
if (aCtx->NbSelected() != 0)
{
theDI << "ERROR: no boxes must be selected!\n";
return 1;
}
aCtx->SetSelectionSensitivity (aBox1, 2, 5);
aCtx->MoveTo (305, 322, ViewerTest::CurrentView());
aCtx->ShiftSelect();
if (aCtx->NbSelected() != 1)
{
theDI << "ERROR: b1 was not selected\n";
return 1;
}
aCtx->MoveTo (103, 322, ViewerTest::CurrentView());
aCtx->ShiftSelect();
if (aCtx->NbSelected() != 1)
{
theDI << "ERROR: b2 is selected after b1's tolerance increased\n";
return 1;
}
return 0;
}
//=======================================================================
//function : OCC26553
//purpose :
//=======================================================================
#include <BRepBuilderAPI_MakeWire.hxx>
static Standard_Integer OCC26553 (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
{
if (theArgc < 2)
{
theDI << "Error: path to file with shell is missing\n";
return 1;
}
BRep_Builder aBuilder;
TopoDS_Shape aShell;
BRepTools::Read(aShell, theArgv[1], aBuilder);
if (aShell.IsNull())
{
theDI << "Error: shell not loaded\n";
return 1;
}
TopoDS_Edge aPipeEdge = BRepBuilderAPI_MakeEdge (gp_Pnt (0, 0, 0), gp_Pnt (0, 0, 10));
TopoDS_Wire aPipeWire = BRepBuilderAPI_MakeWire(aPipeEdge).Wire();
BRepOffsetAPI_MakePipe aPipeBuilder(aPipeWire, aShell);
if (!aPipeBuilder.IsDone())
{
theDI << "Error: failed to create pipe\n";
return 1;
}
for (TopExp_Explorer aShapeExplorer(aShell, TopAbs_EDGE); aShapeExplorer.More(); aShapeExplorer.Next ()) {
const TopoDS_Shape& aGeneratedShape = aPipeBuilder.Generated(aPipeEdge, aShapeExplorer.Current());
if (aGeneratedShape.IsNull())
{
theDI << "Error: null shape\n";
return 1;
}
}
theDI << "History returned successfully\n";
return 0;
}
void QABugs::Commands_19(Draw_Interpretor& theCommands) { void QABugs::Commands_19(Draw_Interpretor& theCommands) {
const char *group = "QABugs"; const char *group = "QABugs";
@@ -3938,5 +4152,8 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
theCommands.Add ("xprojponf", "xprojponf p f", __FILE__, xprojponf, group); theCommands.Add ("xprojponf", "xprojponf p f", __FILE__, xprojponf, group);
theCommands.Add ("OCC24923", "OCC24923", __FILE__, OCC24923, group); theCommands.Add ("OCC24923", "OCC24923", __FILE__, OCC24923, group);
theCommands.Add ("OCC26139", "OCC26139 [-boxsize value] [-boxgrid value] [-compgrid value]", __FILE__, OCC26139, group); theCommands.Add ("OCC26139", "OCC26139 [-boxsize value] [-boxgrid value] [-compgrid value]", __FILE__, OCC26139, group);
theCommands.Add ("OCC26195", "OCC26195 x1_pix y1_pix [x2_pix y2_pix] [toPrintPixelCoord 0|1]", __FILE__, OCC26195, group);
theCommands.Add ("OCC26462", "OCC26462", __FILE__, OCC26462, group);
theCommands.Add ("OCC26553", "OCC26553 file_path", __FILE__, OCC26553, group);
return; return;
} }

View File

@@ -100,7 +100,7 @@ Standard_Boolean Select3D_SensitiveBox::Matches (SelectBasics_SelectingVolumeMan
} }
Standard_Real aDepth; 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; return Standard_False;
} }

View File

@@ -108,7 +108,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
if (mySensType == Select3D_TOS_BOUNDARY) if (mySensType == Select3D_TOS_BOUNDARY)
{ {
SetSensitivityFactor (6.0); SetSensitivityFactor (6);
} }
} }
@@ -166,7 +166,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectBasics_En
if (mySensType == Select3D_TOS_BOUNDARY) if (mySensType == Select3D_TOS_BOUNDARY)
{ {
SetSensitivityFactor (6.0); SetSensitivityFactor (6);
} }
} }
@@ -177,7 +177,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectBasics_En
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId, Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePnts3d, const Handle(TColgp_HArray1OfPnt)& thePnts3d,
const Standard_Boolean theIsFilled) const Standard_Boolean theIsFilled)
: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled), : Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)),
myStart (0), myStart (0),
myEnd (0) myEnd (0)
{ {
@@ -190,7 +190,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
if (mySensType == Select3D_TOS_BOUNDARY) if (mySensType == Select3D_TOS_BOUNDARY)
{ {
SetSensitivityFactor (6.0); SetSensitivityFactor (6);
} }
} }
@@ -215,7 +215,7 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
if (mySensType == Select3D_TOS_BOUNDARY) if (mySensType == Select3D_TOS_BOUNDARY)
{ {
SetSensitivityFactor (6.0); SetSensitivityFactor (6);
} }
} }
@@ -256,9 +256,10 @@ Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolume
if (!theMgr.IsOverlapAllowed()) if (!theMgr.IsOverlapAllowed())
{ {
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
if (!theMgr.Overlaps (myBndBox.CornerMin(), myBndBox.CornerMax(), Standard_False)) for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx)
{ {
return Standard_False; if (!theMgr.Overlaps (anArrayOfPnt->Value (aPntIdx)))
return Standard_False;
} }
return Standard_True; return Standard_True;
} }

View File

@@ -32,7 +32,7 @@ Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_Enti
myCurve (theCurve) myCurve (theCurve)
{ {
loadPoints (theCurve, theNbPnts); loadPoints (theCurve, theNbPnts);
SetSensitivityFactor (3.0); SetSensitivityFactor (3);
} }
//================================================== //==================================================
@@ -44,7 +44,7 @@ Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_Enti
: Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True) : Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True)
{ {
SetSensitivityFactor (3.0); SetSensitivityFactor (3);
} }
//================================================== //==================================================
@@ -55,7 +55,7 @@ Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_Enti
const TColgp_Array1OfPnt& thePoints) const TColgp_Array1OfPnt& thePoints)
: Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True) : Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True)
{ {
SetSensitivityFactor (3.0); SetSensitivityFactor (3);
} }
//================================================== //==================================================

View File

@@ -25,10 +25,9 @@ IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveEntity, SelectBasics_SensitiveEntit
//======================================================================= //=======================================================================
//function : Select3D_SensitiveEntity //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) {} : SelectBasics_SensitiveEntity (theOwnerId) {}
//======================================================================= //=======================================================================
@@ -71,3 +70,22 @@ void Select3D_SensitiveEntity::Clear()
{ {
Set (NULL); 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();
}

View File

@@ -80,6 +80,13 @@ public:
//! Clears up all resources and memory //! Clears up all resources and memory
Standard_EXPORT virtual void Clear() Standard_OVERRIDE; 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) DEFINE_STANDARD_RTTI(Select3D_SensitiveEntity)
protected: protected:

View File

@@ -29,7 +29,7 @@ Select3D_SensitivePoint::Select3D_SensitivePoint (const Handle(SelectBasics_Enti
const gp_Pnt& thePoint) const gp_Pnt& thePoint)
: Select3D_SensitiveEntity (theOwner) : Select3D_SensitiveEntity (theOwner)
{ {
SetSensitivityFactor (12.0); SetSensitivityFactor (12);
myPoint = thePoint; myPoint = thePoint;
} }

View File

@@ -250,9 +250,8 @@ Standard_Boolean Select3D_SensitivePoly::elementIsInside (SelectBasics_Selecting
{ {
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx); const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
Standard_Real aDummy; return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0))
return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0), aDummy) && theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1));
&& theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1), aDummy);
} }
//================================================== //==================================================

View File

@@ -54,10 +54,9 @@ Standard_Boolean Select3D_SensitiveTriangle::Matches (SelectBasics_SelectingVolu
Standard_Real aDistToCOG = RealLast(); Standard_Real aDistToCOG = RealLast();
if (!theMgr.IsOverlapAllowed()) if (!theMgr.IsOverlapAllowed())
{ {
Standard_Real aDummy; return theMgr.Overlaps (myPoints[0])
return theMgr.Overlaps (myPoints[0], aDummy) && theMgr.Overlaps (myPoints[1])
&& theMgr.Overlaps (myPoints[1], aDummy) && theMgr.Overlaps (myPoints[2]);
&& theMgr.Overlaps (myPoints[2], aDummy);
} }
if (!theMgr.Overlaps (myPoints[0], myPoints[1], myPoints[2], mySensType, aDepth)) if (!theMgr.Overlaps (myPoints[0], myPoints[1], myPoints[2], mySensType, aDepth))

View File

@@ -56,6 +56,7 @@ Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(S
myInitLocation (theInitLoc), myInitLocation (theInitLoc),
myDetectedTr (-1) myDetectedTr (-1)
{ {
myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles(); const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& aNodes = myTriangul->Nodes(); const TColgp_Array1OfPnt& aNodes = myTriangul->Nodes();
@@ -148,6 +149,7 @@ Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(S
myFreeEdges (theFreeEdges), myFreeEdges (theFreeEdges),
myDetectedTr (-1) myDetectedTr (-1)
{ {
myInvInitLocation = myInitLocation.Transformation().Inverted();
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
myPrimitivesNb = theIsInterior ? theTrg->Triangles().Length() : theFreeEdges->Length() / 2; myPrimitivesNb = theIsInterior ? theTrg->Triangles().Length() : theFreeEdges->Length() / 2;
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1); myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
@@ -187,19 +189,15 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer t
Standard_Integer aPrimIdx = myBVHPrimIndexes->Value (theIdx); Standard_Integer aPrimIdx = myBVHPrimIndexes->Value (theIdx);
SelectMgr_Vec3 aMinPnt (RealLast()); SelectMgr_Vec3 aMinPnt (RealLast());
SelectMgr_Vec3 aMaxPnt (RealFirst()); SelectMgr_Vec3 aMaxPnt (RealFirst());
Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_INTERIOR) if (mySensType == Select3D_TOS_INTERIOR)
{ {
Standard_Integer aNode1, aNode2, aNode3; Standard_Integer aNode1, aNode2, aNode3;
myTriangul->Triangles() (aPrimIdx + 1).Get (aNode1, aNode2, aNode3); myTriangul->Triangles() (aPrimIdx + 1).Get (aNode1, aNode2, aNode3);
gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation()) gp_Pnt aPnt1 = myTriangul->Nodes().Value (aNode1);
: myTriangul->Nodes().Value (aNode1); gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation()) gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
: myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode3);
aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())), aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())),
Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())), Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())),
@@ -212,10 +210,8 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer t
{ {
Standard_Integer aNodeIdx1 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx); Standard_Integer aNodeIdx1 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx);
Standard_Integer aNodeIdx2 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx + 1); Standard_Integer aNodeIdx2 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx + 1);
gp_Pnt aNode1 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx1).Transformed (myInitLocation.Transformation()) gp_Pnt aNode1 = myTriangul->Nodes().Value (aNodeIdx1);
: myTriangul->Nodes().Value (aNodeIdx1); gp_Pnt aNode2 = myTriangul->Nodes().Value (aNodeIdx2);
gp_Pnt aNode2 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx2).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNodeIdx2);
aMinPnt = SelectMgr_Vec3 (Min (aNode1.X(), aNode2.X()), aMinPnt = SelectMgr_Vec3 (Min (aNode1.X(), aNode2.X()),
Min (aNode1.Y(), aNode2.Y()), Min (aNode1.Y(), aNode2.Y()),
@@ -266,17 +262,14 @@ Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_
Standard_Real& theMatchDepth) Standard_Real& theMatchDepth)
{ {
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx); const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_BOUNDARY) if (mySensType == Select3D_TOS_BOUNDARY)
{ {
Standard_Integer aSegmStartIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 1); Standard_Integer aSegmStartIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 1);
Standard_Integer aSegmEndIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 2); Standard_Integer aSegmEndIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 2);
Handle(TColgp_HArray1OfPnt) anEdgePnts = new TColgp_HArray1OfPnt (1, 2); Handle(TColgp_HArray1OfPnt) anEdgePnts = new TColgp_HArray1OfPnt (1, 2);
gp_Pnt aSegmStart = hasInitLoc ? myTriangul->Nodes().Value (aSegmStartIdx).Transformed (myInitLocation.Transformation()) gp_Pnt aSegmStart = myTriangul->Nodes().Value (aSegmStartIdx);
: myTriangul->Nodes().Value (aSegmStartIdx); gp_Pnt aSegmEnd = myTriangul->Nodes().Value (aSegmEndIdx);
gp_Pnt aSegmEnd = hasInitLoc ? myTriangul->Nodes().Value (aSegmEndIdx).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aSegmEndIdx);
anEdgePnts->SetValue (1, aSegmStart); anEdgePnts->SetValue (1, aSegmStart);
anEdgePnts->SetValue (2, aSegmEnd); anEdgePnts->SetValue (2, aSegmEnd);
Standard_Boolean isMatched = theMgr.Overlaps (anEdgePnts, Select3D_TOS_BOUNDARY, theMatchDepth); Standard_Boolean isMatched = theMgr.Overlaps (anEdgePnts, Select3D_TOS_BOUNDARY, theMatchDepth);
@@ -288,12 +281,9 @@ Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles(); const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
Standard_Integer aNode1, aNode2, aNode3; Standard_Integer aNode1, aNode2, aNode3;
aTriangles (aPrimitiveIdx + 1).Get (aNode1, aNode2, aNode3); aTriangles (aPrimitiveIdx + 1).Get (aNode1, aNode2, aNode3);
gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation()) gp_Pnt aPnt1 = myTriangul->Nodes().Value (aNode1);
: myTriangul->Nodes().Value (aNode1); gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation()) gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
: myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode3);
return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, Select3D_TOS_INTERIOR, theMatchDepth); return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, Select3D_TOS_INTERIOR, theMatchDepth);
} }
} }
@@ -305,8 +295,6 @@ Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_
Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr, Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
const Standard_Integer theElemIdx) const Standard_Integer theElemIdx)
{ {
Standard_Real aDummy;
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx); const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
if (mySensType == Select3D_TOS_BOUNDARY) if (mySensType == Select3D_TOS_BOUNDARY)
@@ -314,13 +302,7 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
gp_Pnt aSegmPnt1 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 1)); gp_Pnt aSegmPnt1 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 1));
gp_Pnt aSegmPnt2 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 2)); gp_Pnt aSegmPnt2 = myTriangul->Nodes().Value (myFreeEdges->Value (aPrimitiveIdx * 2 + 2));
if (HasInitLocation()) // Note: Should be removed (by transforming frustum) return theMgr.Overlaps (aSegmPnt1) && theMgr.Overlaps (aSegmPnt2);
{
aSegmPnt1.Transform (myInitLocation.Transformation());
aSegmPnt2.Transform (myInitLocation.Transformation());
}
return theMgr.Overlaps (aSegmPnt1, aDummy) && theMgr.Overlaps (aSegmPnt2, aDummy);
} }
else else
{ {
@@ -334,16 +316,9 @@ Standard_Boolean Select3D_SensitiveTriangulation::elementIsInside (SelectBasics_
gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2); gp_Pnt aPnt2 = myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3); gp_Pnt aPnt3 = myTriangul->Nodes().Value (aNode3);
if (HasInitLocation()) // Note: Should be removed (by transforming frustum) return theMgr.Overlaps (aPnt1)
{ && theMgr.Overlaps (aPnt2)
aPnt1.Transform (myInitLocation.Transformation()); && theMgr.Overlaps (aPnt3);
aPnt2.Transform (myInitLocation.Transformation());
aPnt3.Transform (myInitLocation.Transformation());
}
return theMgr.Overlaps (aPnt1, aDummy)
&& theMgr.Overlaps (aPnt2, aDummy)
&& theMgr.Overlaps (aPnt3, aDummy);
} }
} }
@@ -390,7 +365,7 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::applyTransformation()
gp_Pnt aVertex = gp_Pnt (aX == 0 ? myBndBox.CornerMin().x() : myBndBox.CornerMax().x(), gp_Pnt aVertex = gp_Pnt (aX == 0 ? myBndBox.CornerMin().x() : myBndBox.CornerMax().x(),
aY == 0 ? myBndBox.CornerMin().y() : myBndBox.CornerMax().y(), aY == 0 ? myBndBox.CornerMin().y() : myBndBox.CornerMax().y(),
aZ == 0 ? myBndBox.CornerMin().z() : myBndBox.CornerMax().z()); 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())); aBndBox.Add (Select3D_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
} }
} }
@@ -431,7 +406,7 @@ Select3D_BndBox3d Select3D_SensitiveTriangulation::BoundingBox()
//======================================================================= //=======================================================================
gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const
{ {
return HasInitLocation() ? myCDG3D.Transformed (myInitLocation) : myCDG3D; return myCDG3D;
} }
//======================================================================= //=======================================================================
@@ -441,4 +416,22 @@ gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const
Standard_Integer Select3D_SensitiveTriangulation::NbSubElements() Standard_Integer Select3D_SensitiveTriangulation::NbSubElements()
{ {
return myTriangul->Nodes().Length(); return myTriangul->Nodes().Length();
} }
//=======================================================================
//function : HasInitLocation
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
{
return !myInitLocation.IsIdentity();
}
//=======================================================================
//function : InvInitLocation
//purpose :
//=======================================================================
gp_Trsf Select3D_SensitiveTriangulation::InvInitLocation() const
{
return myInvInitLocation;
}

View File

@@ -83,10 +83,6 @@ public:
const Handle_Poly_Triangulation& Triangulation() const; const Handle_Poly_Triangulation& Triangulation() const;
Standard_Boolean HasInitLocation() const;
const TopLoc_Location& GetInitLocation() const;
//! Returns the length of array of triangles or edges //! Returns the length of array of triangles or edges
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE; Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
@@ -110,6 +106,15 @@ public:
//! is set, it will be applied //! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE; 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: public:
DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangulation) DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangulation)
@@ -134,20 +139,18 @@ private:
virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr, virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
const Standard_Integer theElemIdx) Standard_OVERRIDE; const Standard_Integer theElemIdx) Standard_OVERRIDE;
public:
Standard_Real myBVHBuildTime;
private: private:
Handle_Poly_Triangulation myTriangul; Handle_Poly_Triangulation myTriangul;
TopLoc_Location myInitLocation; TopLoc_Location myInitLocation;
gp_Pnt myCDG3D; //!< Center of the whole triangulation gp_Pnt myCDG3D; //!< Center of the whole triangulation
Handle_TColStd_HArray1OfInteger myFreeEdges; Handle_TColStd_HArray1OfInteger myFreeEdges;
Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior
Standard_Integer myDetectedTr; Standard_Integer myDetectedTr;
Standard_Integer myPrimitivesNb; //!< Amount of free edges or triangles depending on sensitivity type 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 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) DEFINE_STANDARD_HANDLE(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)

View File

@@ -23,15 +23,6 @@ inline const Handle(Poly_Triangulation)& Select3D_SensitiveTriangulation::Triang
return myTriangul; return myTriangul;
} }
//=======================================================================
//function : HasInitLocation
//purpose :
//=======================================================================
inline Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
{
return !myInitLocation.IsIdentity();
}
//======================================================================= //=======================================================================
//function : GetInitLocation //function : GetInitLocation
//purpose : //purpose :

View File

@@ -17,8 +17,8 @@
#define _SelectBasics_SelectingVolumeManager_HeaderFile #define _SelectBasics_SelectingVolumeManager_HeaderFile
#include <BVH_Box.hxx> #include <BVH_Box.hxx>
#include <gp_Pnt.hxx>
#include <TColgp_HArray1OfPnt.hxx> #include <TColgp_HArray1OfPnt.hxx>
#include <NCollection_Vec3.hxx>
class Bnd_Box; class Bnd_Box;
class gp_Pnt; class gp_Pnt;
@@ -44,7 +44,8 @@ public:
virtual Standard_Integer GetActiveSelectionType() const = 0; virtual Standard_Integer GetActiveSelectionType() const = 0;
//! Returns true if selecting volume is overlapped by box theBox //! 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; Standard_Real& theDepth) = 0;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box with minimum //! Returns true if selecting volume is overlapped by axis-aligned bounding box with minimum
@@ -53,10 +54,15 @@ public:
const NCollection_Vec3<Standard_Real>& theBoxMax, const NCollection_Vec3<Standard_Real>& theBoxMax,
Standard_Boolean* theInside = NULL) = 0; Standard_Boolean* theInside = NULL) = 0;
//! Returns true if selecting volume is overlapped by point thePt //! Returns true if selecting volume is overlapped by point thePnt
virtual Standard_Boolean Overlaps (const gp_Pnt& thePt, virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth) = 0; 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 //! Returns true if selecting volume is overlapped by planar convex polygon, which points
//! are stored in theArrayOfPts, taking into account sensitivity type theSensType //! are stored in theArrayOfPts, taking into account sensitivity type theSensType
virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts,
@@ -81,7 +87,7 @@ public:
//! to the given point theCOG //! to the given point theCOG
virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) = 0; 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; virtual Standard_Boolean IsOverlapAllowed() const = 0;

View File

@@ -19,7 +19,8 @@ deferred class SensitiveEntity from SelectBasics inherits TShared from MMgt
---Purpose: root class; the inheriting classes will be able to give ---Purpose: root class; the inheriting classes will be able to give
-- sensitive Areas for the dynamic selection algorithms -- sensitive Areas for the dynamic selection algorithms
uses uses
Trsf from gp,
EntityOwner, EntityOwner,
BndBox3d from Select3D, BndBox3d from Select3D,
PickResult, PickResult,
@@ -29,7 +30,7 @@ is
Initialize (theOwnerId : EntityOwner; Initialize (theOwnerId : EntityOwner;
theSensFactor : Real from Standard = 2.0); theSensFactor : Integer from Standard = 2);
Set (me : mutable; Set (me : mutable;
theOwnerId : EntityOwner) theOwnerId : EntityOwner)
@@ -45,6 +46,12 @@ is
---C++: return const& ---C++: return const&
---Purpose: Returns pointer to owner of the entity ---Purpose: Returns pointer to owner of the entity
SetSensitivityFactor (me : mutable;
theSensFactor : Integer from Standard)
is static;
---Level: Public
---Purpose: Allows to manage the sensitivity of the entity
Matches (me : mutable; Matches (me : mutable;
theMgr : out SelectingVolumeManager from SelectBasics; theMgr : out SelectingVolumeManager from SelectBasics;
@@ -55,7 +62,7 @@ is
-- current selecting volume -- current selecting volume
SensitivityFactor (me) SensitivityFactor (me)
returns Real from Standard; returns Integer from Standard;
---C++: inline ---C++: inline
---Purpose: allows a better sensitivity for ---Purpose: allows a better sensitivity for
-- a specific entity in selection algorithms -- a specific entity in selection algorithms
@@ -78,15 +85,21 @@ is
Clear (me : mutable) is deferred; Clear (me : mutable) is deferred;
---Purpose: Clears up all the resources and memory allocated ---Purpose: Clears up all the resources and memory allocated
SetSensitivityFactor (me : mutable; HasInitLocation (me)
theSensFactor :Real from Standard) returns Boolean from Standard
is protected; is deferred;
---C++: inline ---Purpose: Returns true if the shape corresponding to the entity
---Purpose: Allows to manage the sensitivity of the entity -- has init location.
InvInitLocation (me)
returns Trsf from gp
is deferred;
---Purpose: Returns inversed location transformation matrix if the shape corresponding
-- to this entity has init location set. Otherwise, returns identity matrix.
fields fields
myOwnerId : EntityOwner from SelectBasics is protected; myOwnerId : EntityOwner from SelectBasics is protected;
mySFactor : Real from Standard; mySFactor : Integer from Standard;
end SensitiveEntity; end SensitiveEntity;

View File

@@ -22,7 +22,7 @@
// purpose : Creates new empty sensitive entity instance // purpose : Creates new empty sensitive entity instance
//======================================================================= //=======================================================================
SelectBasics_SensitiveEntity::SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId, SelectBasics_SensitiveEntity::SelectBasics_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Standard_Real theSensFactor) const Standard_Integer theSensFactor)
: myOwnerId (theOwnerId), : myOwnerId (theOwnerId),
mySFactor (theSensFactor) {} mySFactor (theSensFactor) {}
@@ -43,3 +43,15 @@ const Handle(SelectBasics_EntityOwner)& SelectBasics_SensitiveEntity::OwnerId()
{ {
return myOwnerId; return myOwnerId;
} }
//=======================================================================
// function : SetSensitivityFactor
// purpose : Allows to manage sensitivity of a particular entity
//=======================================================================
void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Integer theNewSens)
{
Standard_ASSERT_RAISE (theNewSens > 0,
"Error! Selection sensitivity have positive value.");
mySFactor = theNewSens;
}

View File

@@ -12,20 +12,11 @@
// Alternatively, this file may be used under the terms of Open CASCADE // Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement. // commercial license or contractual agreement.
//=======================================================================
// function : SetSensitivityFactor
// purpose : Allows to manage the sensitivity of the entity
//=======================================================================
inline void SelectBasics_SensitiveEntity::SetSensitivityFactor (const Standard_Real theSensFactor)
{
mySFactor = theSensFactor;
}
//======================================================================= //=======================================================================
// function : SensitivityFactor // function : SensitivityFactor
// purpose : Gets sensitivity factor for the entity // purpose : Gets sensitivity factor for the entity
//======================================================================= //=======================================================================
inline Standard_Real SelectBasics_SensitiveEntity::SensitivityFactor() const inline Standard_Integer SelectBasics_SensitiveEntity::SensitivityFactor() const
{ {
return mySFactor; return mySFactor;
} }

View File

@@ -68,7 +68,7 @@ void SelectMgr_BaseFrustum::SetViewport (const Standard_Real theX,
// function : SetPixelTolerance // function : SetPixelTolerance
// purpose : // purpose :
//======================================================================= //=======================================================================
void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Real theTol) void SelectMgr_BaseFrustum::SetPixelTolerance (const Standard_Integer theTol)
{ {
myPixelTolerance = theTol; myPixelTolerance = theTol;
} }
@@ -97,7 +97,8 @@ void SelectMgr_BaseFrustum::SetBuilder (const Handle(SelectMgr_FrustumBuilder)&
// purpose : SAT intersection test between defined volume and // purpose : SAT intersection test between defined volume and
// given axis-aligned box // 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*/) Standard_Real& /*theDepth*/)
{ {
return Standard_False; return Standard_False;
@@ -118,12 +119,21 @@ Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const SelectMgr_Vec3& /*theBox
// function : Overlaps // function : Overlaps
// purpose : Intersection test between defined volume and given point // 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*/) Standard_Real& /*theDepth*/)
{ {
return Standard_False; 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 // function : Overlaps
// purpose : SAT intersection test between defined volume and given // purpose : SAT intersection test between defined volume and given
@@ -131,7 +141,7 @@ Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt*/,
// may be considered of interior part or boundary line defined // may be considered of interior part or boundary line defined
// by segments depending on given sensitivity type // 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*/, Select3D_TypeOfSensitivity /*theSensType*/,
Standard_Real& /*theDepth*/) Standard_Real& /*theDepth*/)
{ {
@@ -158,8 +168,8 @@ Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt1*/,
// function : Overlaps // function : Overlaps
// purpose : Checks if line segment overlaps selecting volume // purpose : Checks if line segment overlaps selecting volume
//======================================================================= //=======================================================================
Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePt1*/, Standard_Boolean SelectMgr_BaseFrustum::Overlaps (const gp_Pnt& /*thePnt1*/,
const gp_Pnt& /*thePt2*/, const gp_Pnt& /*thePnt2*/,
Standard_Real& /*theDepth*/) Standard_Real& /*theDepth*/)
{ {
return Standard_False; return Standard_False;
@@ -175,9 +185,9 @@ Standard_Real SelectMgr_BaseFrustum::DistToGeometryCenter (const gp_Pnt& /*theCO
return DBL_MAX; 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());
} }
//======================================================================= //=======================================================================

View File

@@ -16,8 +16,6 @@
#ifndef _SelectMgr_BaseFrustum_HeaderFile #ifndef _SelectMgr_BaseFrustum_HeaderFile
#define _SelectMgr_BaseFrustum_HeaderFile #define _SelectMgr_BaseFrustum_HeaderFile
#include <Bnd_Box.hxx>
#include <gp_Pnt.hxx> #include <gp_Pnt.hxx>
#include <gp_Pln.hxx> #include <gp_Pln.hxx>
@@ -56,7 +54,7 @@ public:
const Graphic3d_Mat4d& theOrientation, const Graphic3d_Mat4d& theOrientation,
const Standard_Integer theIsOrthographic); const Standard_Integer theIsOrthographic);
void SetPixelTolerance (const Standard_Real theTol); void SetPixelTolerance (const Standard_Integer theTol);
void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight); void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight);
@@ -85,14 +83,19 @@ public:
//! Builds selecting volumes set according to polyline points //! Builds selecting volumes set according to polyline points
virtual void Build (const TColgp_Array1OfPnt2d& /*thePoints*/) {} virtual void Build (const TColgp_Array1OfPnt2d& /*thePoints*/) {}
virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& /*theTrsf*/) { return NULL; } //! 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.
//! IMPORTANT: Makes sense only for frustum built on a single point!
//! Returns a copy of the frustum resized according to the scale factor given //! 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 //! SAT intersection test between defined volume and given axis-aligned box
virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBndBox, virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
const SelectMgr_Vec3& theBoxMax,
Standard_Real& theDepth); Standard_Real& theDepth);
//! Returns true if selecting volume is overlapped by axis-aligned bounding box //! Returns true if selecting volume is overlapped by axis-aligned bounding box
@@ -102,19 +105,25 @@ public:
Standard_Boolean* theInside = NULL); Standard_Boolean* theInside = NULL);
//! Intersection test between defined volume and given point //! Intersection test between defined volume and given point
virtual Standard_Boolean Overlaps (const gp_Pnt& thePt, virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth); 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, //! SAT intersection test between defined volume and given ordered set of points,
//! representing line segments. The test may be considered of interior part or //! representing line segments. The test may be considered of interior part or
//! boundary line defined by segments depending on given sensitivity type //! boundary line defined by segments depending on given sensitivity type
virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
Select3D_TypeOfSensitivity theSensType, Select3D_TypeOfSensitivity theSensType,
Standard_Real& theDepth); Standard_Real& theDepth);
//! Checks if line segment overlaps selecting frustum //! Checks if line segment overlaps selecting frustum
virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1, virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
const gp_Pnt& thePt2, const gp_Pnt& thePnt2,
Standard_Real& theDepth); Standard_Real& theDepth);
//! SAT intersection test between defined volume and given triangle. The test may //! SAT intersection test between defined volume and given triangle. The test may
@@ -130,7 +139,7 @@ public:
//! screen point and given point theCOG //! screen point and given point theCOG
virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG); virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG);
virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const; virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const;
//! Checks if the point of sensitive in which selection was detected belongs //! Checks if the point of sensitive in which selection was detected belongs
//! to the region defined by clipping planes //! to the region defined by clipping planes
@@ -138,8 +147,8 @@ public:
const Standard_Real theDepth); const Standard_Real theDepth);
protected: protected:
Standard_Real myPixelTolerance; //!< Pixel tolerance Standard_Integer myPixelTolerance; //!< Pixel tolerance
Standard_Boolean myIsOrthographic; //!< Defines if current camera is orthographic Standard_Boolean myIsOrthographic; //!< Defines if current camera is orthographic
Handle(SelectMgr_FrustumBuilder) myBuilder; //!< A tool implementing methods for volume build Handle(SelectMgr_FrustumBuilder) myBuilder; //!< A tool implementing methods for volume build
}; };

View File

@@ -18,6 +18,8 @@
#include <BVH_Box.hxx> #include <BVH_Box.hxx>
#include <gp_Pnt.hxx> #include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp_XYZ.hxx>
#include <SelectMgr_BaseFrustum.hxx> #include <SelectMgr_BaseFrustum.hxx>
#include <TColgp_HArray1OfPnt.hxx> #include <TColgp_HArray1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx> #include <TColgp_Array1OfPnt2d.hxx>
@@ -75,39 +77,39 @@ protected:
//! SAT intersection test between frustum given and planar convex polygon represented as ordered point set //! SAT intersection test between frustum given and planar convex polygon represented as ordered point set
Standard_Boolean hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, Standard_Boolean hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
SelectMgr_Vec3& theNormal); gp_Vec& theNormal);
//! SAT intersection test between defined volume and given triangle //! SAT intersection test between defined volume and given triangle
Standard_Boolean hasOverlap (const gp_Pnt& thePnt1, Standard_Boolean hasOverlap (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2, const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3, const gp_Pnt& thePnt3,
SelectMgr_Vec3& theNormal); gp_Vec& theNormal);
private: private:
//! Checks if AABB and frustum are separated along the given axis //! Checks if AABB and frustum are separated along the given axis
Standard_Boolean isSeparated (const SelectMgr_Vec3& theBoxMin, Standard_Boolean isSeparated (const SelectMgr_Vec3& theBoxMin,
const SelectMgr_Vec3& theBoxMax, const SelectMgr_Vec3& theBoxMax,
const SelectMgr_Vec3& theDirect, const gp_XYZ& theDirect,
Standard_Boolean* theInside) const; Standard_Boolean* theInside) const;
//! Checks if triangle and frustum are separated along the given axis //! Checks if triangle and frustum are separated along the given axis
Standard_Boolean isSeparated (const gp_Pnt& thePnt1, Standard_Boolean isSeparated (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2, const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3, const gp_Pnt& thePnt3,
const SelectMgr_Vec3& theAxis) const; const gp_XYZ& theAxis) const;
protected: protected:
SelectMgr_Vec3 myPlanes[N + 2]; //!< Plane equations gp_Vec myPlanes[N + 2]; //!< Plane equations
SelectMgr_Vec3 myVertices[N * 2]; //!< Vertices coordinates gp_Pnt myVertices[N * 2]; //!< Vertices coordinates
Standard_Real myMaxVertsProjections[N + 2]; //!< Cached projections of vertices onto frustum plane directions 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 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 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 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 <SelectMgr_Frustum.lxx>

View File

@@ -17,9 +17,6 @@
#include <Poly_Array1OfTriangle.hxx> #include <Poly_Array1OfTriangle.hxx>
#include <Standard_Assert.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 // function : isSeparated
// purpose : Checks if AABB and frustum are separated along the given axis. // purpose : Checks if AABB and frustum are separated along the given axis.
@@ -27,18 +24,18 @@
template <int N> template <int N>
Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const SelectMgr_Vec3& theBoxMin, Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const SelectMgr_Vec3& theBoxMin,
const SelectMgr_Vec3& theBoxMax, const SelectMgr_Vec3& theBoxMax,
const SelectMgr_Vec3& theDirect, const gp_XYZ& theDirect,
Standard_Boolean* theInside) const Standard_Boolean* theInside) const
{ {
const Standard_Real aMinB = const Standard_Real aMinB =
theDirect.x() * (theDirect.x() < 0.0 ? theBoxMax.x() : theBoxMin.x()) + theDirect.X() * (theDirect.X() < 0.0 ? theBoxMax.x() : theBoxMin.x()) +
theDirect.y() * (theDirect.y() < 0.0 ? theBoxMax.y() : theBoxMin.y()) + theDirect.Y() * (theDirect.Y() < 0.0 ? theBoxMax.y() : theBoxMin.y()) +
theDirect.z() * (theDirect.z() < 0.0 ? theBoxMax.z() : theBoxMin.z()); theDirect.Z() * (theDirect.Z() < 0.0 ? theBoxMax.z() : theBoxMin.z());
const Standard_Real aMaxB = const Standard_Real aMaxB =
theDirect.x() * (theDirect.x() < 0.0 ? theBoxMin.x() : theBoxMax.x()) + theDirect.X() * (theDirect.X() < 0.0 ? theBoxMin.x() : theBoxMax.x()) +
theDirect.y() * (theDirect.y() < 0.0 ? theBoxMin.y() : theBoxMax.y()) + theDirect.Y() * (theDirect.Y() < 0.0 ? theBoxMin.y() : theBoxMax.y()) +
theDirect.z() * (theDirect.z() < 0.0 ? theBoxMin.z() : theBoxMax.z()); theDirect.Z() * (theDirect.Z() < 0.0 ? theBoxMin.z() : theBoxMax.z());
Standard_ASSERT_RAISE (aMaxB >= aMinB, "Error! Failed to project box"); Standard_ASSERT_RAISE (aMaxB >= aMinB, "Error! Failed to project box");
@@ -48,7 +45,7 @@ Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const SelectMgr_Vec3& theBox
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) 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); aMinF = Min (aMinF, aProj);
aMaxF = Max (aMaxF, aProj); aMaxF = Max (aMaxF, aProj);
@@ -83,7 +80,7 @@ template <int N>
Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const gp_Pnt& thePnt1, Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2, const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3, const gp_Pnt& thePnt3,
const SelectMgr_Vec3& theAxis) const const gp_XYZ& theAxis) const
{ {
// frustum projection // frustum projection
Standard_Real aMinF = RealLast(); Standard_Real aMinF = RealLast();
@@ -95,21 +92,21 @@ Standard_Boolean SelectMgr_Frustum<N>::isSeparated (const gp_Pnt& thePnt1,
Standard_Real aTriangleProj; Standard_Real aTriangleProj;
aTriangleProj = DOTp (theAxis, thePnt1); aTriangleProj = theAxis.Dot (thePnt1.XYZ());
aMinTr = Min (aMinTr, aTriangleProj); aMinTr = Min (aMinTr, aTriangleProj);
aMaxTr = Max (aMaxTr, aTriangleProj); aMaxTr = Max (aMaxTr, aTriangleProj);
aTriangleProj = DOTp (theAxis, thePnt2); aTriangleProj = theAxis.Dot (thePnt2.XYZ());
aMinTr = Min (aMinTr, aTriangleProj); aMinTr = Min (aMinTr, aTriangleProj);
aMaxTr = Max (aMaxTr, aTriangleProj); aMaxTr = Max (aMaxTr, aTriangleProj);
aTriangleProj = DOTp (theAxis, thePnt3); aTriangleProj = theAxis.Dot (thePnt3.XYZ());
aMinTr = Min (aMinTr, aTriangleProj); aMinTr = Min (aMinTr, aTriangleProj);
aMaxTr = Max (aMaxTr, aTriangleProj); aMaxTr = Max (aMaxTr, aTriangleProj);
for (Standard_Integer aVertIter = 0; aVertIter < N * 2; ++aVertIter) 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); aMinF = Min (aMinF, aProj);
aMaxF = Max (aMaxF, aProj); aMaxF = Max (aMaxF, aProj);
@@ -152,17 +149,17 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const SelectMgr_Vec3& theMinP
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor) 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 = const Standard_Real aBoxProjMin =
aPlane.x() * (aPlane.x() < 0.f ? theMaxPnt.x() : theMinPnt.x()) + aPlane.X() * (aPlane.X() < 0.f ? theMaxPnt.x() : theMinPnt.x()) +
aPlane.y() * (aPlane.y() < 0.f ? theMaxPnt.y() : theMinPnt.y()) + aPlane.Y() * (aPlane.Y() < 0.f ? theMaxPnt.y() : theMinPnt.y()) +
aPlane.z() * (aPlane.z() < 0.f ? theMaxPnt.z() : theMinPnt.z()); aPlane.Z() * (aPlane.Z() < 0.f ? theMaxPnt.z() : theMinPnt.z());
const Standard_Real aBoxProjMax = const Standard_Real aBoxProjMax =
aPlane.x() * (aPlane.x() < 0.f ? theMinPnt.x() : theMaxPnt.x()) + aPlane.X() * (aPlane.X() < 0.f ? theMinPnt.x() : theMaxPnt.x()) +
aPlane.y() * (aPlane.y() < 0.f ? theMinPnt.y() : theMaxPnt.y()) + aPlane.Y() * (aPlane.Y() < 0.f ? theMinPnt.y() : theMaxPnt.y()) +
aPlane.z() * (aPlane.z() < 0.f ? theMinPnt.z() : theMaxPnt.z()); aPlane.Z() * (aPlane.Z() < 0.f ? theMinPnt.z() : theMaxPnt.z());
Standard_ASSERT_RAISE (aBoxProjMax >= aBoxProjMin, "Error! Failed to project box"); Standard_ASSERT_RAISE (aBoxProjMax >= aBoxProjMin, "Error! Failed to project box");
@@ -180,13 +177,16 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const SelectMgr_Vec3& theMinP
for (Standard_Integer aDim = 0; aDim < 3; ++aDim) 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) 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(), gp_XYZ aDirection (DBL_MAX, DBL_MAX, DBL_MAX);
anEdge1.z() * myEdgeDirs[aVolDir].x() - anEdge1.x() * myEdgeDirs[aVolDir].z(), aDirection.Ptr()[aDim] = 0;
anEdge1.x() * myEdgeDirs[aVolDir].y() - anEdge1.y() * myEdgeDirs[aVolDir].x()); aDirection.Ptr()[aNext] = -myEdgeDirs[aVolDir].XYZ().Ptr()[aNextNext];
aDirection.Ptr()[aNextNext] = myEdgeDirs[aVolDir].XYZ().Ptr()[aNext];
if (isSeparated (theMinPnt, theMaxPnt, aDirection, theInside)) if (isSeparated (theMinPnt, theMaxPnt, aDirection, theInside))
{ {
@@ -209,11 +209,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt)
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor) for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
{ {
const Select3D_Vec3& aPlane = myPlanes[aPlaneIdx]; const Standard_Real aPointProj = myPlanes[aPlaneIdx].XYZ().Dot (thePnt.XYZ());
const Standard_Real aPointProj = aPlane.x() * thePnt.X() +
aPlane.y() * thePnt.Y() +
aPlane.z() * thePnt.Z();
if (aPointProj > myMaxVertsProjections[aPlaneIdx] if (aPointProj > myMaxVertsProjections[aPlaneIdx]
|| aPointProj < myMinVertsProjections[aPlaneIdx]) || aPointProj < myMinVertsProjections[aPlaneIdx])
@@ -233,10 +229,8 @@ template <int N>
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt, Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
const gp_Pnt& theEndPnt) const gp_Pnt& theEndPnt)
{ {
const SelectMgr_Vec3& aDir = SelectMgr_Vec3 (theEndPnt.X() - theStartPnt.X(), const gp_XYZ& aDir = theEndPnt.XYZ() - theStartPnt.XYZ();
theEndPnt.Y() - theStartPnt.Y(), if (aDir.Modulus() < Precision::Confusion())
theEndPnt.Z() - theStartPnt.Z());
if (std::sqrt (aDir.x() * aDir.x() + aDir.y() * aDir.y() + aDir.z () * aDir.z()) < Precision::Confusion())
return Standard_True; return Standard_True;
const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1; const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
@@ -244,10 +238,9 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
{ {
Standard_Real aMinSegm = RealLast(), aMaxSegm = RealFirst(); Standard_Real aMinSegm = RealLast(), aMaxSegm = RealFirst();
Standard_Real aMinF = RealLast(), aMaxF = RealFirst(); Standard_Real aMinF = RealLast(), aMaxF = RealFirst();
SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx];
Standard_Real aProj1 = DOTp (aPlane, theStartPnt); Standard_Real aProj1 = myPlanes[aPlaneIdx].XYZ().Dot (theStartPnt.XYZ());
Standard_Real aProj2 = DOTp (aPlane, theEndPnt); Standard_Real aProj2 = myPlanes[aPlaneIdx].XYZ().Dot (theEndPnt.XYZ());
aMinSegm = Min (aProj1, aProj2); aMinSegm = Min (aProj1, aProj2);
aMaxSegm = Max (aProj1, aProj2); aMaxSegm = Max (aProj1, aProj2);
@@ -265,12 +258,12 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
Standard_Real aMin2 = DBL_MAX, aMax2 = -DBL_MAX; Standard_Real aMin2 = DBL_MAX, aMax2 = -DBL_MAX;
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) 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); aMax2 = Max (aMax2, aProjection);
aMin2 = Min (aMin2, aProjection); aMin2 = Min (aMin2, aProjection);
} }
Standard_Real aProj1 = DOTp (aDir, theStartPnt); Standard_Real aProj1 = aDir.Dot (theStartPnt.XYZ());
Standard_Real aProj2 = DOTp (aDir, theEndPnt); Standard_Real aProj2 = aDir.Dot (theEndPnt.XYZ());
aMin1 = Min (aProj1, aProj2); aMin1 = Min (aProj1, aProj2);
aMax1 = Max (aProj1, aProj2); aMax1 = Max (aProj1, aProj2);
if (aMin1 > aMax2 if (aMin1 > aMax2
@@ -285,18 +278,16 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
Standard_Real aMinSegm = DBL_MAX, aMaxSegm = -DBL_MAX; Standard_Real aMinSegm = DBL_MAX, aMaxSegm = -DBL_MAX;
Standard_Real aMinF = DBL_MAX, aMaxF = -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(), const gp_XYZ aTestDir = aDir.Crossed (myEdgeDirs[aEdgeDirIdx].XYZ());
aDir.z() * myEdgeDirs[aEdgeDirIdx].x() - aDir.x() * myEdgeDirs[aEdgeDirIdx].z(),
aDir.x() * myEdgeDirs[aEdgeDirIdx].y() - aDir.y() * myEdgeDirs[aEdgeDirIdx].x());
Standard_Real Proj1 = DOTp (aTestDir, theStartPnt); Standard_Real Proj1 = aTestDir.Dot (theStartPnt.XYZ());
Standard_Real Proj2 = DOTp (aTestDir, theEndPnt); Standard_Real Proj2 = aTestDir.Dot (theEndPnt.XYZ());
aMinSegm = Min (Proj1, Proj2); aMinSegm = Min (Proj1, Proj2);
aMaxSegm = Max (Proj1, Proj2); aMaxSegm = Max (Proj1, Proj2);
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) 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); aMaxF = Max (aMaxF, aProjection);
aMinF = Min (aMinF, aProjection); aMinF = Min (aMinF, aProjection);
} }
@@ -318,26 +309,25 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& theStartPnt,
// ======================================================================= // =======================================================================
template <int N> template <int N>
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts, Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
SelectMgr_Vec3& theNormal) gp_Vec& theNormal)
{ {
Standard_Integer aStartIdx = theArrayOfPnts->Lower(); Standard_Integer aStartIdx = theArrayOfPnts->Lower();
Standard_Integer anEndIdx = theArrayOfPnts->Upper(); Standard_Integer anEndIdx = theArrayOfPnts->Upper();
const gp_Pnt& aPnt1 = theArrayOfPnts->Value (aStartIdx); const gp_XYZ& aPnt1 = theArrayOfPnts->Value (aStartIdx).XYZ();
const gp_Pnt& aPnt2 = theArrayOfPnts->Value (aStartIdx + 1); const gp_XYZ& aPnt2 = theArrayOfPnts->Value (aStartIdx + 1).XYZ();
const gp_Pnt& aPnt3 = theArrayOfPnts->Value (aStartIdx + 2); const gp_XYZ& aPnt3 = theArrayOfPnts->Value (aStartIdx + 2).XYZ();
const gp_XYZ aVec1 = aPnt1.XYZ() - aPnt2.XYZ(); const gp_XYZ aVec1 = aPnt1 - aPnt2;
const gp_XYZ aVec2 = aPnt3.XYZ() - aPnt2.XYZ(); const gp_XYZ aVec2 = aPnt3 - aPnt2;
theNormal = SelectMgr_Vec3 (aVec2.Y() * aVec1.Z() - aVec2.Z() * aVec1.Y(), theNormal = aVec2.Crossed (aVec1);
aVec2.Z() * aVec1.X() - aVec2.X() * aVec1.Z(), const gp_XYZ& aNormal = theNormal.XYZ();
aVec2.X() * aVec1.Y() - aVec2.Y() * aVec1.X()); Standard_Real aPolygProjection = aNormal.Dot (aPnt1);
Standard_Real aPolygProjection = DOTp (theNormal, aPnt1);
Standard_Real aMax = RealFirst(); Standard_Real aMax = RealFirst();
Standard_Real aMin = RealLast(); Standard_Real aMin = RealLast();
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) 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); aMax = Max (aMax, aProjection);
aMin = Min (aMin, aProjection); aMin = Min (aMin, aProjection);
} }
@@ -347,17 +337,17 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1Of
return Standard_False; return Standard_False;
} }
Standard_Integer aPlanesNb = N == 4 ? N + 2 : N + 1; const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < aPlanesNb; ++aPlaneIdx) for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor)
{ {
Standard_Real aMaxF = RealFirst(); Standard_Real aMaxF = RealFirst();
Standard_Real aMinF = RealLast(); Standard_Real aMinF = RealLast();
Standard_Real aMaxPolyg = RealFirst(); Standard_Real aMaxPolyg = RealFirst();
Standard_Real aMinPolyg = RealLast(); Standard_Real aMinPolyg = RealLast();
SelectMgr_Vec3 aPlane = myPlanes[aPlaneIdx]; const gp_XYZ& aPlane = myPlanes[aPlaneIdx].XYZ();
for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter) 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); aMaxPolyg = Max (aMaxPolyg, aProjection);
aMinPolyg = Min (aMinPolyg, aProjection); aMinPolyg = Min (aMinPolyg, aProjection);
} }
@@ -371,30 +361,28 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const Handle(TColgp_HArray1Of
} }
Standard_Integer aDirectionsNb = myIsOrthographic ? 4 : 6; 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() const gp_XYZ aSegmDir = theArrayOfPnts->Value ((aPntsIter + 1) % aLen + aStartIdx).XYZ()
: theArrayOfPnts->Value (aPntsIter + 1).XYZ() - theArrayOfPnts->Value (aPntsIter).XYZ(); - theArrayOfPnts->Value (aPntsIter + aStartIdx).XYZ();
for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir) for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir)
{ {
Standard_Real aMaxPolyg = RealFirst(); Standard_Real aMaxPolyg = RealFirst();
Standard_Real aMinPolyg = RealLast(); Standard_Real aMinPolyg = RealLast();
Standard_Real aMaxF = RealFirst(); Standard_Real aMaxF = RealFirst();
Standard_Real aMinF = RealLast(); Standard_Real aMinF = RealLast();
SelectMgr_Vec3 aTestDir = SelectMgr_Vec3 (aSegmDir.Y() * myEdgeDirs[aVolDir].z() - aSegmDir.Z() * myEdgeDirs[aVolDir].y(), const gp_XYZ aTestDir = aSegmDir.Crossed (myEdgeDirs[aVolDir].XYZ());
aSegmDir.Z() * myEdgeDirs[aVolDir].x() - aSegmDir.X() * myEdgeDirs[aVolDir].z(),
aSegmDir.X() * myEdgeDirs[aVolDir].y() - aSegmDir.Y() * myEdgeDirs[aVolDir].x());
for (Standard_Integer aPntIter = aStartIdx; aPntIter <= anEndIdx; ++aPntIter) 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); aMaxPolyg = Max (aMaxPolyg, aProjection);
aMinPolyg = Min (aMinPolyg, aProjection); aMinPolyg = Min (aMinPolyg, aProjection);
} }
for (Standard_Integer aVertIdx = 0; aVertIdx < N * 2; ++aVertIdx) 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); aMaxF = Max (aMaxF, aProjection);
aMinF = Min (aMinF, aProjection); aMinF = Min (aMinF, aProjection);
} }
@@ -418,31 +406,27 @@ template <int N>
Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1, Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2, const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3, const gp_Pnt& thePnt3,
SelectMgr_Vec3& theNormal) gp_Vec& theNormal)
{ {
const gp_XYZ aTrEdges[3] = { thePnt2.XYZ() - thePnt1.XYZ(),
SelectMgr_Vec3 aPnt1 (thePnt1.X(), thePnt1.Y(), thePnt1.Z()); thePnt3.XYZ() - thePnt2.XYZ(),
SelectMgr_Vec3 aPnt2 (thePnt2.X(), thePnt2.Y(), thePnt2.Z()); thePnt1.XYZ() - thePnt3.XYZ() };
SelectMgr_Vec3 aPnt3 (thePnt3.X(), thePnt3.Y(), thePnt3.Z());
SelectMgr_Vec3 aTrEdges[3] = { aPnt2 - aPnt1,
aPnt3 - aPnt2,
aPnt1 - aPnt3 };
const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1; const Standard_Integer anIncFactor = (myIsOrthographic && N == 4) ? 2 : 1;
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < N + 1; aPlaneIdx += anIncFactor) 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; Standard_Real aTriangleProj;
aTriangleProj = DOT (aPlane, aPnt1); aTriangleProj = aPlane.Dot (thePnt1.XYZ());
Standard_Real aTriangleProjMin = aTriangleProj; Standard_Real aTriangleProjMin = aTriangleProj;
Standard_Real aTriangleProjMax = aTriangleProj; Standard_Real aTriangleProjMax = aTriangleProj;
aTriangleProj = DOT (aPlane, aPnt2); aTriangleProj = aPlane.Dot (thePnt2.XYZ());
aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj); aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj);
aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj); aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj);
aTriangleProj = DOT (aPlane, aPnt3); aTriangleProj = aPlane.Dot (thePnt3.XYZ());
aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj); aTriangleProjMin = Min (aTriangleProjMin, aTriangleProj);
aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj); aTriangleProjMax = Max (aTriangleProjMax, aTriangleProj);
@@ -455,10 +439,8 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
} }
} }
theNormal = SelectMgr_Vec3 (aTrEdges[2].y() * aTrEdges[0].z() - aTrEdges[2].z() * aTrEdges[0].y(), theNormal = aTrEdges[2].Crossed (aTrEdges[0]);
aTrEdges[2].z() * aTrEdges[0].x() - aTrEdges[2].x() * aTrEdges[0].z(), if (isSeparated (thePnt1, thePnt2, thePnt3, theNormal.XYZ()))
aTrEdges[2].x() * aTrEdges[0].y() - aTrEdges[2].y() * aTrEdges[0].x());
if (isSeparated (thePnt1, thePnt2, thePnt3, theNormal))
{ {
return Standard_False; return Standard_False;
} }
@@ -468,12 +450,7 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
{ {
for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir) for (Standard_Integer aVolDir = 0; aVolDir < aDirectionsNb; ++aVolDir)
{ {
SelectMgr_Vec3 anEdge1 = myEdgeDirs[aVolDir]; const gp_XYZ& aTestDirection = myEdgeDirs[aVolDir].XYZ().Crossed (aTrEdges[aTriangleEdgeIdx]);
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());
if (isSeparated (thePnt1, thePnt2, thePnt3, aTestDirection)) if (isSeparated (thePnt1, thePnt2, thePnt3, aTestDirection))
{ {
@@ -484,6 +461,3 @@ Standard_Boolean SelectMgr_Frustum<N>::hasOverlap (const gp_Pnt& thePnt1,
return Standard_True; return Standard_True;
} }
#undef DOT
#undef DOTp

View File

@@ -127,7 +127,7 @@ static NCollection_Vec4<Standard_Real> safePointCast (const gp_Pnt& thePnt)
// function : unProject // function : unProject
// purpose : Unprojects point from NDC coords to 3d world space // 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 aInvView;
Graphic3d_Mat4d aInvProj; Graphic3d_Mat4d aInvProj;
@@ -135,7 +135,7 @@ SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
// this case should never happen // this case should never happen
if (!myOrientation.Inverted (aInvView) || !myProjection.Inverted (aInvProj)) if (!myOrientation.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 // use compatible type of point
@@ -146,7 +146,7 @@ SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
const Standard_Real aInvW = 1.0 / Standard_Real (aPnt.w()); 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);
} }
// ======================================================================= // =======================================================================
@@ -155,9 +155,9 @@ SelectMgr_Vec3 SelectMgr_FrustumBuilder::unProject (const gp_Pnt& thePnt) const
// theZ = 0 - near plane, // theZ = 0 - near plane,
// theZ = 1 - far plane // theZ = 1 - far plane
// ======================================================================= // =======================================================================
SelectMgr_Vec3 SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& theX, gp_Pnt SelectMgr_FrustumBuilder::ProjectPntOnViewPlane (const Standard_Real& theX,
const Standard_Real& theY, const Standard_Real& theY,
const Standard_Real& theZ) const const Standard_Real& theZ) const
{ {
Standard_Real aX, anY, aZ; Standard_Real aX, anY, aZ;

View File

@@ -57,16 +57,16 @@ public:
//! Projects 2d screen point onto view frustum plane: //! Projects 2d screen point onto view frustum plane:
//! theZ = 0 - near plane, //! theZ = 0 - near plane,
//! theZ = 1 - far plane //! theZ = 1 - far plane
SelectMgr_Vec3 ProjectPntOnViewPlane (const Standard_Real& theX, gp_Pnt ProjectPntOnViewPlane (const Standard_Real& theX,
const Standard_Real& theY, const Standard_Real& theY,
const Standard_Real& theZ) const; const Standard_Real& theZ) const;
DEFINE_STANDARD_RTTI(SelectMgr_FrustumBuilder) DEFINE_STANDARD_RTTI(SelectMgr_FrustumBuilder)
private: private:
//! Unprojects point from NDC coords to 3d world space //! 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: private:

View File

@@ -18,11 +18,6 @@
#include <SelectMgr_RectangularFrustum.hxx> #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 // function : segmentSegmentDistance
// purpose : // purpose :
@@ -31,18 +26,15 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
const gp_Pnt& theSegPnt2, const gp_Pnt& theSegPnt2,
Standard_Real& theDepth) Standard_Real& theDepth)
{ {
SelectMgr_Vec3 anU = SelectMgr_Vec3 (theSegPnt2.X() - theSegPnt1.X(), gp_XYZ anU = theSegPnt2.XYZ() - theSegPnt1.XYZ();
theSegPnt2.Y() - theSegPnt1.Y(), gp_XYZ aV = myViewRayDir.XYZ();
theSegPnt2.Z() - theSegPnt1.Z()); gp_XYZ aW = theSegPnt1.XYZ() - myNearPickedPnt.XYZ();
SelectMgr_Vec3 aV = myViewRayDir;
SelectMgr_Vec3 aW = SelectMgr_Vec3 (theSegPnt1.X() - myNearPickedPnt.x(), Standard_Real anA = anU.Dot (anU);
theSegPnt1.Y() - myNearPickedPnt.y(), Standard_Real aB = anU.Dot (aV);
theSegPnt1.Z() - myNearPickedPnt.z()); Standard_Real aC = aV.Dot (aV);
Standard_Real anA = DOT (anU, anU); Standard_Real aD = anU.Dot (aW);
Standard_Real aB = DOT (anU, aV); Standard_Real anE = aV.Dot (aW);
Standard_Real aC = DOT (aV, aV);
Standard_Real aD = DOT (anU, aW);
Standard_Real anE = DOT (aV, aW);
Standard_Real aCoef = anA * aC - aB * aB; Standard_Real aCoef = anA * aC - aB * aB;
Standard_Real aSc, aSn, aSd = aCoef; Standard_Real aSc, aSn, aSd = aCoef;
Standard_Real aTc, aTn, aTd = aCoef; Standard_Real aTc, aTn, aTd = aCoef;
@@ -99,24 +91,22 @@ void SelectMgr_RectangularFrustum::segmentSegmentDistance (const gp_Pnt& theSegP
aSc = (Abs (aSn) < Precision::Confusion() ? 0.0 : aSn / aSd); aSc = (Abs (aSn) < Precision::Confusion() ? 0.0 : aSn / aSd);
aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd); aTc = (Abs (aTn) < Precision::Confusion() ? 0.0 : aTn / aTd);
SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + myViewRayDir * aTc; gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTc;
theDepth = DISTANCE (myNearPickedPnt, aClosestPnt); theDepth = myNearPickedPnt.Distance (aClosestPnt);
} }
// ======================================================================= // =======================================================================
// function : segmentPlaneIntersection // function : segmentPlaneIntersection
// purpose : // purpose :
// ======================================================================= // =======================================================================
void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const SelectMgr_Vec3& thePlane, void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const gp_Vec& thePlane,
const gp_Pnt& thePntOnPlane, const gp_Pnt& thePntOnPlane,
Standard_Real& theDepth) Standard_Real& theDepth)
{ {
SelectMgr_Vec3 anU = myViewRayDir; gp_XYZ anU = myViewRayDir.XYZ();
SelectMgr_Vec3 aW = SelectMgr_Vec3 (myNearPickedPnt.x() - thePntOnPlane.X(), gp_XYZ aW = myNearPickedPnt.XYZ() - thePntOnPlane.XYZ();
myNearPickedPnt.y() - thePntOnPlane.Y(), Standard_Real aD = thePlane.Dot (anU);
myNearPickedPnt.z() - thePntOnPlane.Z()); Standard_Real aN = -thePlane.Dot (aW);
Standard_Real aD = DOT (thePlane, anU);
Standard_Real aN = -DOT (thePlane, aW);
if (Abs (aD) < Precision::Confusion()) if (Abs (aD) < Precision::Confusion())
{ {
@@ -139,36 +129,144 @@ void SelectMgr_RectangularFrustum::segmentPlaneIntersection (const SelectMgr_Vec
return; return;
} }
SelectMgr_Vec3 aClosestPnt = myNearPickedPnt + anU * aParam; gp_Pnt aClosestPnt = myNearPickedPnt.XYZ() + anU * aParam;
theDepth = DISTANCE (myNearPickedPnt, aClosestPnt); theDepth = myNearPickedPnt.Distance (aClosestPnt);
} }
namespace 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 // function : computeNormals
// purpose : Computes normals to frustum faces // 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 // Top
theNormals[0] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0], theNormals[0] = theEdges[0].Crossed (theEdges[4]);
theVertices[4] - theVertices[0]);
// Bottom // Bottom
theNormals[1] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[2], theNormals[1] = theEdges[2].Crossed (theEdges[3]);
theVertices[6] - theVertices[2]);
// Left // Left
theNormals[2] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0], theNormals[2] = theEdges[4].Crossed (theEdges[1]);
theVertices[2] - theVertices[0]);
// Right // Right
theNormals[3] = SelectMgr_Vec3::Cross (theVertices[5] - theVertices[4], theNormals[3] = theEdges[5].Crossed (theEdges[3]);
theVertices[6] - theVertices[4]);
// Near // Near
theNormals[4] = SelectMgr_Vec3::Cross (theVertices[6] - theVertices[4], theNormals[4] = theEdges[0].Crossed (theEdges[1]);
theVertices[0] - theVertices[4]);
// Far // Far
theNormals[5] = SelectMgr_Vec3::Cross (theVertices[7] - theVertices[5], theNormals[5] = -theNormals[4];
theVertices[1] - theVertices[5]); }
}
// =======================================================================
// function : cacheVertexProjections
// purpose : Caches projection of frustum's vertices onto its plane directions
// and {i, j, k}
// =======================================================================
void SelectMgr_RectangularFrustum::cacheVertexProjections (SelectMgr_RectangularFrustum* theFrustum)
{
if (theFrustum->myIsOrthographic)
{
// 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 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);
}
}
else
{
// 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;
for (Standard_Integer aVertIdx = 0; aVertIdx < 8; ++aVertIdx)
{
const gp_XYZ& aVert = theFrustum->myVertices[aVertIdx].XYZ();
aMax = Max (aVert.Ptr()[aDim], aMax);
aMin = Min (aVert.Ptr()[aDim], aMin);
}
theFrustum->myMaxOrthoVertsProjections[aDim] = aMax;
theFrustum->myMinOrthoVertsProjections[aDim] = aMin;
} }
} }
@@ -180,94 +278,24 @@ namespace
void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint) void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d &thePoint)
{ {
myNearPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 0.0); myNearPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 0.0);
myFarPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 1.0); myFarPickedPnt = myBuilder->ProjectPntOnViewPlane (thePoint.X(), thePoint.Y(), 1.0);
myViewRayDir = myFarPickedPnt - myNearPickedPnt; myViewRayDir = myFarPickedPnt.XYZ() - myNearPickedPnt.XYZ();
myMousePos = thePoint; myMousePos = thePoint;
// LeftTopNear gp_Pnt2d aMinPnt (thePoint.X() - myPixelTolerance * 0.5,
myVertices[0] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0, thePoint.Y() - myPixelTolerance * 0.5);
thePoint.Y() + myPixelTolerance / 2.0, gp_Pnt2d aMaxPnt (thePoint.X() + myPixelTolerance * 0.5,
0.0); thePoint.Y() + myPixelTolerance * 0.5);
// LeftTopFar
myVertices[1] = myBuilder->ProjectPntOnViewPlane (thePoint.X() - myPixelTolerance / 2.0, // calculate base frustum characteristics: vertices and edge directions
thePoint.Y() + myPixelTolerance / 2.0, computeFrustum (aMinPnt, aMaxPnt, myBuilder, myVertices, myEdgeDirs);
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 // compute frustum normals
computeNormals (myVertices, myPlanes); computeNormals (myEdgeDirs, myPlanes);
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx) // compute vertices projections onto frustum normals and
{ // {i, j, k} vectors and store them to corresponding class fields
Standard_Real aMax = -DBL_MAX; cacheVertexProjections (this);
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 (aProjection, aMax);
aMin = Min (aProjection, aMin);
}
myMaxOrthoVertsProjections[aDim] = aMax;
myMinOrthoVertsProjections[aDim] = aMin;
}
// 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];
} }
// ======================================================================= // =======================================================================
@@ -283,278 +311,104 @@ void SelectMgr_RectangularFrustum::Build (const gp_Pnt2d& theMinPnt,
myFarPickedPnt = myBuilder->ProjectPntOnViewPlane ((theMinPnt.X() + theMaxPnt.X()) * 0.5, myFarPickedPnt = myBuilder->ProjectPntOnViewPlane ((theMinPnt.X() + theMaxPnt.X()) * 0.5,
(theMinPnt.Y() + theMaxPnt.Y()) * 0.5, (theMinPnt.Y() + theMaxPnt.Y()) * 0.5,
1.0); 1.0);
myViewRayDir = myFarPickedPnt - myNearPickedPnt; myViewRayDir = myFarPickedPnt.XYZ() - myNearPickedPnt.XYZ();
// LeftTopNear // calculate base frustum characteristics: vertices and edge directions
myVertices[0] = myBuilder->ProjectPntOnViewPlane (theMinPnt.X(), computeFrustum (theMinPnt, theMaxPnt, myBuilder, myVertices, myEdgeDirs);
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);
// compute frustum normals // compute frustum normals
computeNormals (myVertices, myPlanes); computeNormals (myEdgeDirs, myPlanes);
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx) // compute vertices projections onto frustum normals and
{ // {i, j, k} vectors and store them to corresponding class fields
Standard_Real aMax = -DBL_MAX; cacheVertexProjections (this);
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;
}
// 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];
} }
// ======================================================================= // =======================================================================
// function : Transform // function : ScaleAndTransform
// purpose : Returns a copy of the frustum transformed according to the matrix given // 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.
NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::Transform (const gp_Trsf& theTrsf)
{
SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
aRes->myNearPickedPnt = SelectMgr_MatOp::Transform (theTrsf, myNearPickedPnt);
aRes->myFarPickedPnt = SelectMgr_MatOp::Transform (theTrsf, myFarPickedPnt);
aRes->myViewRayDir = aRes->myFarPickedPnt - aRes->myNearPickedPnt;
aRes->myIsOrthographic = myIsOrthographic;
// 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)
{
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 // 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::Scale (const Standard_Real theScaleFactor) NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_RectangularFrustum::ScaleAndTransform (const Standard_Integer theScaleFactor,
const gp_Trsf& theTrsf)
{ {
SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum(); Standard_ASSERT_RAISE (theScaleFactor > 0,
"Error! Pixel tolerance for selection should be greater than zero");
aRes->myNearPickedPnt = myNearPickedPnt; SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();
aRes->myFarPickedPnt = myFarPickedPnt; const Standard_Boolean isToScale = theScaleFactor != 1;
aRes->myViewRayDir = myViewRayDir; const Standard_Boolean isToTrsf = theTrsf.Form() != gp_Identity;
if (!isToScale && !isToTrsf)
return aRes;
aRes->myIsOrthographic = myIsOrthographic; aRes->myIsOrthographic = myIsOrthographic;
SelectMgr_RectangularFrustum* aRef = this;
if (isToScale)
{
aRes->myNearPickedPnt = myNearPickedPnt;
aRes->myFarPickedPnt = myFarPickedPnt;
aRes->myViewRayDir = myViewRayDir;
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);
// recompute base frustum characteristics from scratch
computeFrustum (aMinPnt, aMaxPnt, myBuilder, aRes->myVertices, aRes->myEdgeDirs);
aRef = aRes;
}
if (isToTrsf)
{
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();
}
// 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 // compute frustum normals
computeNormals (aRes->myVertices, aRes->myPlanes); computeNormals (aRes->myEdgeDirs, aRes->myPlanes);
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 6; ++aPlaneIdx) cacheVertexProjections (aRes);
{
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); return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
} }
@@ -577,20 +431,19 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const SelectMgr_Vec3& t
// purpose : SAT intersection test between defined volume and // purpose : SAT intersection test between defined volume and
// given axis-aligned box // 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) Standard_Real& theDepth)
{ {
const SelectMgr_Vec3& aMinPnt = theBox.CornerMin(); if (!hasOverlap (theBoxMin, theBoxMax))
const SelectMgr_Vec3& aMaxPnt = theBox.CornerMax();
if (!hasOverlap (aMinPnt, aMaxPnt))
return Standard_False; return Standard_False;
SelectMgr_Vec3 aNearestPnt = SelectMgr_Vec3 (RealLast(), RealLast(), RealLast()); gp_Pnt aNearestPnt (RealLast(), RealLast(), RealLast());
aNearestPnt.x() = Max (Min (myNearPickedPnt.x(), aMaxPnt.x()), aMinPnt.x()); aNearestPnt.SetX (Max (Min (myNearPickedPnt.X(), theBoxMax.x()), theBoxMin.x()));
aNearestPnt.y() = Max (Min (myNearPickedPnt.y(), aMaxPnt.y()), aMinPnt.y()); aNearestPnt.SetY (Max (Min (myNearPickedPnt.Y(), theBoxMax.y()), theBoxMin.y()));
aNearestPnt.z() = Max (Min (myNearPickedPnt.z(), aMaxPnt.z()), aMinPnt.z()); aNearestPnt.SetZ (Max (Min (myNearPickedPnt.Z(), theBoxMax.z()), theBoxMin.z()));
theDepth = DISTANCE (aNearestPnt, myNearPickedPnt); theDepth = aNearestPnt.Distance (myNearPickedPnt);
return Standard_True; return Standard_True;
} }
@@ -605,15 +458,24 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt,
if (!hasOverlap (thePnt)) if (!hasOverlap (thePnt))
return Standard_False; return Standard_False;
SelectMgr_Vec3 aPnt (thePnt.X(), thePnt.Y(), thePnt.Z()); gp_XYZ aV = thePnt.XYZ() - myNearPickedPnt.XYZ();
SelectMgr_Vec3 aV = aPnt - myNearPickedPnt; gp_Pnt aDetectedPnt =
SelectMgr_Vec3 aDetectedPnt = myNearPickedPnt + myViewRayDir * (DOT (aV, myViewRayDir) / DOT (myViewRayDir, myViewRayDir)); myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * (aV.Dot (myViewRayDir.XYZ()) / myViewRayDir.Dot (myViewRayDir));
theDepth = DISTANCE (aDetectedPnt, myNearPickedPnt); theDepth = aDetectedPnt.Distance (myNearPickedPnt);
return Standard_True; 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 // function : Overlaps
// purpose : Checks if line segment overlaps selecting frustum // purpose : Checks if line segment overlaps selecting frustum
@@ -668,7 +530,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const Handle(TColgp_HAr
} }
else if (theSensType == Select3D_TOS_INTERIOR) else if (theSensType == Select3D_TOS_INTERIOR)
{ {
SelectMgr_Vec3 aPolyNorm (RealLast()); gp_Vec aPolyNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
if (!hasOverlap (theArrayOfPnts, aPolyNorm)) if (!hasOverlap (theArrayOfPnts, aPolyNorm))
return Standard_False; return Standard_False;
@@ -704,48 +566,41 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
} }
else if (theSensType == Select3D_TOS_INTERIOR) else if (theSensType == Select3D_TOS_INTERIOR)
{ {
SelectMgr_Vec3 aTriangleNormal (RealLast()); gp_Vec aTriangleNormal (gp_XYZ (RealLast(), RealLast(), RealLast()));
if (!hasOverlap (thePnt1, thePnt2, thePnt3, aTriangleNormal)) if (!hasOverlap (thePnt1, thePnt2, thePnt3, aTriangleNormal))
return Standard_False; return Standard_False;
// check if intersection point belongs to triangle's interior part // check if intersection point belongs to triangle's interior part
SelectMgr_Vec3 aPnt1 (thePnt1.X(), thePnt1.Y(), thePnt1.Z()); gp_XYZ aTrEdges[3] = { thePnt2.XYZ() - thePnt1.XYZ(),
SelectMgr_Vec3 aTrEdges[3] = { SelectMgr_Vec3 (thePnt2.X() - thePnt1.X(), thePnt2.Y() - thePnt1.Y(), thePnt2.Z() - thePnt1.Z()), thePnt3.XYZ() - thePnt2.XYZ(),
SelectMgr_Vec3 (thePnt3.X() - thePnt2.X(), thePnt3.Y() - thePnt2.Y(), thePnt3.Z() - thePnt2.Z()), thePnt1.XYZ() - thePnt3.XYZ() };
SelectMgr_Vec3 (thePnt1.X() - thePnt3.X(), thePnt1.Y() - thePnt3.Y(), thePnt1.Z() - thePnt3.Z()) }; gp_XYZ anEdge = (thePnt1.XYZ() - myNearPickedPnt.XYZ()) * (1.0 / aTriangleNormal.Dot (myViewRayDir));
SelectMgr_Vec3 anEdge = (aPnt1 - myNearPickedPnt) * (1.0 / DOT (aTriangleNormal, myViewRayDir));
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(), gp_XYZ aVec = myViewRayDir.XYZ().Crossed (anEdge);
myViewRayDir.z() * anEdge.x() - myViewRayDir.x() * anEdge.z(),
myViewRayDir.x() * anEdge.y() - myViewRayDir.y() * anEdge.x());
Standard_Real anU = DOT (aVec, aTrEdges[2]); Standard_Real anU = aVec.Dot (aTrEdges[2]);
Standard_Real aV = DOT (aVec, aTrEdges[0]); Standard_Real aV = aVec.Dot (aTrEdges[0]);
Standard_Boolean isInterior = (aTime >= 0.0) && (anU >= 0.0) && (aV >= 0.0) && (anU + aV <= 1.0); Standard_Boolean isInterior = (aTime >= 0.0) && (anU >= 0.0) && (aV >= 0.0) && (anU + aV <= 1.0);
if (isInterior) if (isInterior)
{ {
SelectMgr_Vec3 aDetectedPnt = myNearPickedPnt + myViewRayDir * aTime; gp_Pnt aDetectedPnt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aTime;
theDepth = DISTANCE (myNearPickedPnt, aDetectedPnt); theDepth = myNearPickedPnt.Distance (aDetectedPnt);
return Standard_True; return Standard_True;
} }
gp_Pnt aPnts[3] = {thePnt1, thePnt2, thePnt3}; gp_Pnt aPnts[3] = {thePnt1, thePnt2, thePnt3};
Standard_Real aMinDist = RealLast(); Standard_Real aMinDist = RealLast();
Standard_Integer aNearestEdgeIdx = -1; 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) for (Standard_Integer anEdgeIdx = 0; anEdgeIdx < 3; ++anEdgeIdx)
{ {
SelectMgr_Vec3 aW = SelectMgr_Vec3 (aPtOnPlane.x() - aPnts[anEdgeIdx].X(), gp_XYZ aW = aPtOnPlane.XYZ() - aPnts[anEdgeIdx].XYZ();
aPtOnPlane.y() - aPnts[anEdgeIdx].Y(), Standard_Real aCoef = aTrEdges[anEdgeIdx].Dot (aW) / aTrEdges[anEdgeIdx].Dot (aTrEdges[anEdgeIdx]);
aPtOnPlane.z() - aPnts[anEdgeIdx].Z()); Standard_Real aDist = aPtOnPlane.Distance (aPnts[anEdgeIdx].XYZ() + aCoef * aTrEdges[anEdgeIdx]);
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()));
if (aMinDist > aDist) if (aMinDist > aDist)
{ {
aMinDist = aDist; aMinDist = aDist;
@@ -765,8 +620,7 @@ Standard_Boolean SelectMgr_RectangularFrustum::Overlaps (const gp_Pnt& thePnt1,
// ======================================================================= // =======================================================================
Standard_Real SelectMgr_RectangularFrustum::DistToGeometryCenter (const gp_Pnt& theCOG) Standard_Real SelectMgr_RectangularFrustum::DistToGeometryCenter (const gp_Pnt& theCOG)
{ {
const SelectMgr_Vec3& aCOG = SelectMgr_Vec3 (theCOG.X(), theCOG.Y(), theCOG.Z()); return theCOG.Distance (myNearPickedPnt);
return DISTANCE (aCOG, myNearPickedPnt);
} }
// ======================================================================= // =======================================================================
@@ -774,9 +628,9 @@ Standard_Real SelectMgr_RectangularFrustum::DistToGeometryCenter (const gp_Pnt&
// purpose : Calculates the point on a view ray that was detected during // purpose : Calculates the point on a view ray that was detected during
// the run of selection algo by given depth // 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 * theDepth; return myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * theDepth;
} }
// ======================================================================= // =======================================================================
@@ -803,8 +657,9 @@ Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_Sequen
const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ(); const gp_XYZ& aPlaneDirXYZ = aGeomPlane.Axis().Direction().XYZ();
Standard_Real aDotProduct = DOTp (myViewRayDir, aPlaneDirXYZ); Standard_Real aDotProduct = myViewRayDir.XYZ().Dot (aPlaneDirXYZ);
Standard_Real aDistance = - (DOTp (myNearPickedPnt, aPlaneDirXYZ) + aPlaneD); Standard_Real aDistance = - myNearPickedPnt.XYZ().Dot (aPlaneDirXYZ) +
aPlaneD;
// check whether the pick line is parallel to clip plane // check whether the pick line is parallel to clip plane
if (Abs (aDotProduct) < Precision::Angular()) if (Abs (aDotProduct) < Precision::Angular())
@@ -823,8 +678,8 @@ Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_Sequen
continue; continue;
} }
const SelectMgr_Vec3 anIntersectionPt = myNearPickedPnt + myViewRayDir * aParam; const gp_Pnt anIntersectionPt = myNearPickedPnt.XYZ() + myViewRayDir.XYZ() * aParam;
const Standard_Real aDistToPln = DISTANCE (anIntersectionPt, myNearPickedPnt); const Standard_Real aDistToPln = anIntersectionPt.Distance (myNearPickedPnt);
// change depth limits for case of opposite and directed planes // change depth limits for case of opposite and directed planes
if (aDotProduct < 0.0) if (aDotProduct < 0.0)

View File

@@ -42,18 +42,22 @@ public:
virtual void Build (const gp_Pnt2d& theMinPnt, virtual void Build (const gp_Pnt2d& theMinPnt,
const gp_Pnt2d& theMaxPnt) Standard_OVERRIDE; const gp_Pnt2d& theMaxPnt) Standard_OVERRIDE;
//! Returns a copy of the frustum transformed according to the matrix given //! IMPORTANT: Scaling makes sense only for frustum built on a single point!
virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE; //! Note that this method does not perform any checks on type of the frustum.
//! IMPORTANT: Makes sense only for frustum built on a single point!
//! Returns a copy of the frustum resized according to the scale factor given //! Returns a copy of the frustum resized according to the scale factor given
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.
virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScaleFactor,
const gp_Trsf& theTrsf) Standard_OVERRIDE;
// SAT Tests for different objects // SAT Tests for different objects
//! SAT intersection test between defined volume and given axis-aligned box //! SAT intersection test between defined volume and given axis-aligned box
virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox, virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theBoxMin,
const SelectMgr_Vec3& theBoxMax,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box //! Returns true if selecting volume is overlapped by axis-aligned bounding box
@@ -66,6 +70,9 @@ public:
virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt, virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth) Standard_OVERRIDE; 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, //! SAT intersection test between defined volume and given ordered set of points,
//! representing line segments. The test may be considered of interior part or //! representing line segments. The test may be considered of interior part or
//! boundary line defined by segments depending on given sensitivity type //! boundary line defined by segments depending on given sensitivity type
@@ -92,29 +99,45 @@ public:
virtual Standard_Real DistToGeometryCenter (const gp_Pnt& theCOG) Standard_OVERRIDE; 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 //! Calculates the point on a view ray that was detected during the run of selection algo by given depth
virtual SelectMgr_Vec3 DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE; virtual gp_Pnt DetectedPoint (const Standard_Real theDepth) const Standard_OVERRIDE;
//! Checks if the point of sensitive in which selection was detected belongs //! Checks if the point of sensitive in which selection was detected belongs
//! to the region defined by clipping planes //! to the region defined by clipping planes
virtual Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes, virtual Standard_Boolean IsClipped (const Graphic3d_SequenceOfHClipPlane& thePlanes,
const Standard_Real theDepth) Standard_OVERRIDE; 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: protected:
void segmentSegmentDistance (const gp_Pnt& theSegPnt1, void segmentSegmentDistance (const gp_Pnt& theSegPnt1,
const gp_Pnt& theSegPnt2, const gp_Pnt& theSegPnt2,
Standard_Real& theDepth); Standard_Real& theDepth);
void segmentPlaneIntersection (const SelectMgr_Vec3& thePlane, void segmentPlaneIntersection (const gp_Vec& thePlane,
const gp_Pnt& thePntOnPlane, const gp_Pnt& thePntOnPlane,
Standard_Real& theDepth); Standard_Real& theDepth);
private: private:
SelectMgr_Vec3 myNearPickedPnt; //!< 3d projection of user-picked selection point onto near view plane void cacheVertexProjections (SelectMgr_RectangularFrustum* theFrustum);
SelectMgr_Vec3 myFarPickedPnt; //!< 3d projection of user-picked selection point onto far view plane
SelectMgr_Vec3 myViewRayDir; private:
gp_Pnt2d myMousePos; //!< Mouse coordinates 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 #endif // _SelectMgr_RectangularFrustum_HeaderFile

View File

@@ -25,7 +25,7 @@
//======================================================================= //=======================================================================
SelectMgr_SelectableObjectSet::SelectMgr_SelectableObjectSet() 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);
} }
//======================================================================= //=======================================================================

View File

@@ -32,10 +32,19 @@ SelectMgr_SelectingVolumeManager::SelectMgr_SelectingVolumeManager (Standard_Boo
} }
//======================================================================= //=======================================================================
// function : Transform // function : ScaleAndTransform
// purpose : Returns a copy of active frustum transformed according to the matrix given // 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::Transform (const gp_Trsf& theTrsf) SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::ScaleAndTransform (const Standard_Integer theScaleFactor,
const gp_Trsf& theTrsf)
{ {
SelectMgr_SelectingVolumeManager aMgr (Standard_False); SelectMgr_SelectingVolumeManager aMgr (Standard_False);
@@ -44,31 +53,13 @@ SelectMgr_SelectingVolumeManager SelectMgr_SelectingVolumeManager::Transform (co
aMgr.myActiveSelectionType = myActiveSelectionType; 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; aMgr.myToAllowOverlap = myToAllowOverlap;
return aMgr; 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 // function : GetActiveSelectionType
// purpose : // purpose :
@@ -147,7 +138,7 @@ void SelectMgr_SelectingVolumeManager::SetWindowSize (const Standard_Integer the
// function : SetPixelTolerance // function : SetPixelTolerance
// purpose : Updates pixel tolerance in all selecting volumes // 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) for (Standard_Integer anIdx = 0; anIdx < VolumeTypesNb; ++anIdx)
{ {
@@ -198,13 +189,14 @@ void SelectMgr_SelectingVolumeManager::BuildSelectingVolume (const TColgp_Array1
// purpose : SAT intersection test between defined volume and // purpose : SAT intersection test between defined volume and
// given axis-aligned box // 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) Standard_Real& theDepth)
{ {
if (myActiveSelectionType == Unknown) if (myActiveSelectionType == Unknown)
return Standard_False; return Standard_False;
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBndBox, theDepth); return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theBoxMin, theBoxMax, theDepth);
} }
//======================================================================= //=======================================================================
@@ -225,16 +217,28 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const SelectMgr_Vec
// function : Overlaps // function : Overlaps
// purpose : Intersection test between defined volume and given point // 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) Standard_Real& theDepth)
{ {
if (myActiveSelectionType == Unknown) if (myActiveSelectionType == Unknown)
return Standard_False; return Standard_False;
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePt, return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (thePnt,
theDepth); 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 // function : Overlaps
// purpose : SAT intersection test between defined volume and given // purpose : SAT intersection test between defined volume and given
@@ -242,14 +246,14 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::Overlaps (const gp_Pnt& thePt
// may be considered of interior part or boundary line defined // may be considered of interior part or boundary line defined
// by segments depending on given sensitivity type // 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_Integer theSensType,
Standard_Real& theDepth) Standard_Real& theDepth)
{ {
if (myActiveSelectionType == Unknown) if (myActiveSelectionType == Unknown)
return Standard_False; return Standard_False;
return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPts, return mySelectingVolumes[myActiveSelectionType / 2]->Overlaps (theArrayOfPnts,
(Select3D_TypeOfSensitivity)theSensType, (Select3D_TypeOfSensitivity)theSensType,
theDepth); theDepth);
} }
@@ -310,10 +314,10 @@ Standard_Real SelectMgr_SelectingVolumeManager::DistToGeometryCenter (const gp_P
// the run of selection algo by given depth. Is valid for point // the run of selection algo by given depth. Is valid for point
// selection only // 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) if (myActiveSelectionType != Point)
return NCollection_Vec3<Standard_Real> (RealLast()); return gp_Pnt (RealLast(), RealLast(), RealLast());
return mySelectingVolumes[Frustum]->DetectedPoint (theDepth); return mySelectingVolumes[Frustum]->DetectedPoint (theDepth);
} }
@@ -351,3 +355,45 @@ Standard_Boolean SelectMgr_SelectingVolumeManager::IsOverlapAllowed() const
{ {
return myActiveSelectionType != Box || myToAllowOverlap; 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].Access());
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].Access());
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].Access());
return aFr->GetFarPnt();
}

View File

@@ -37,12 +37,16 @@ public:
Standard_EXPORT virtual ~SelectMgr_SelectingVolumeManager() {}; Standard_EXPORT virtual ~SelectMgr_SelectingVolumeManager() {};
//! Returns a copy of active frustum transformed according to the matrix given //! IMPORTANT: Scaling makes sense only for frustum built on a single point!
Standard_EXPORT virtual SelectMgr_SelectingVolumeManager Transform (const gp_Trsf& theTrsf); //! Note that this method does not perform any checks on type of the frustum.
//!
//! IMPORTANT: Makes sense only for point selection!
//! Returns a copy of the frustum resized according to the scale factor given //! 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; Standard_EXPORT virtual Standard_Integer GetActiveSelectionType() const Standard_OVERRIDE;
@@ -63,7 +67,7 @@ public:
const Standard_Real theHeight); const Standard_Real theHeight);
//! Updates pixel tolerance in all selecting volumes //! 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 //! Updates window size in all selecting volumes
Standard_EXPORT void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight); Standard_EXPORT void SetWindowSize (const Standard_Integer theWidth, const Standard_Integer theHeight);
@@ -81,7 +85,8 @@ public:
//! SAT intersection test between defined volume and given axis-aligned box //! 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; Standard_Real& theDepth) Standard_OVERRIDE;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box //! Returns true if selecting volume is overlapped by axis-aligned bounding box
@@ -91,9 +96,12 @@ public:
Standard_Boolean* theInside = NULL) Standard_OVERRIDE; Standard_Boolean* theInside = NULL) Standard_OVERRIDE;
//! Intersection test between defined volume and given point //! 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; 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, //! SAT intersection test between defined volume and given ordered set of points,
//! representing line segments. The test may be considered of interior part or //! representing line segments. The test may be considered of interior part or
//! boundary line defined by segments depending on given sensitivity type //! boundary line defined by segments depending on given sensitivity type
@@ -102,16 +110,16 @@ public:
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
//! Checks if line segment overlaps selecting frustum //! Checks if line segment overlaps selecting frustum
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1, Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
const gp_Pnt& thePt2, const gp_Pnt& thePnt2,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
//! SAT intersection test between defined volume and given triangle. The test may //! SAT intersection test between defined volume and given triangle. The test may
//! be considered of interior part or boundary line defined by triangle vertices //! be considered of interior part or boundary line defined by triangle vertices
//! depending on given sensitivity type //! depending on given sensitivity type
Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1, Standard_EXPORT virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
const gp_Pnt& thePt2, const gp_Pnt& thePnt2,
const gp_Pnt& thePt3, const gp_Pnt& thePnt3,
Standard_Integer theSensType, Standard_Integer theSensType,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
@@ -122,7 +130,7 @@ public:
//! Calculates the point on a view ray that was detected during the run of selection algo by given depth. Is valid for point //! 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 //! 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 //! Checks if the point of sensitive in which selection was detected belongs
//! to the region defined by clipping planes //! to the region defined by clipping planes
@@ -136,6 +144,13 @@ public:
Standard_EXPORT virtual Standard_Boolean IsOverlapAllowed() const Standard_OVERRIDE; 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: private:
enum { Frustum, FrustumSet, VolumeTypesNb }; //!< Defines the amount of available selecting volumes enum { Frustum, FrustumSet, VolumeTypesNb }; //!< Defines the amount of available selecting volumes

View File

@@ -29,7 +29,8 @@ SelectMgr_Selection::SelectMgr_Selection (const Standard_Integer theModeIdx)
: myMode (theModeIdx), : myMode (theModeIdx),
mySelectionState (SelectMgr_SOS_Unknown), mySelectionState (SelectMgr_SOS_Unknown),
myBVHUpdateStatus (SelectMgr_TBU_None), myBVHUpdateStatus (SelectMgr_TBU_None),
mySensFactor (2.0) mySensFactor (2),
myIsCustomSens (Standard_False)
{} {}
SelectMgr_Selection::~SelectMgr_Selection() SelectMgr_Selection::~SelectMgr_Selection()
@@ -48,7 +49,7 @@ void SelectMgr_Selection::Destroy()
Handle(SelectMgr_SensitiveEntity)& anEntity = myEntities.ChangeValue (anEntityIdx); Handle(SelectMgr_SensitiveEntity)& anEntity = myEntities.ChangeValue (anEntityIdx);
anEntity->BaseSensitive()->Set (NULL); anEntity->BaseSensitive()->Set (NULL);
} }
mySensFactor = 2.0; mySensFactor = 2;
} }
//================================================== //==================================================
@@ -73,8 +74,15 @@ void SelectMgr_Selection::Add (const Handle(SelectBasics_SensitiveEntity)& theSe
anEntity->SetActiveForSelection(); anEntity->SetActiveForSelection();
} }
mySensFactor = Max (mySensFactor, if (myIsCustomSens)
anEntity->BaseSensitive()->SensitivityFactor()); {
anEntity->BaseSensitive()->SetSensitivityFactor (mySensFactor);
}
else
{
mySensFactor = Max (mySensFactor,
anEntity->BaseSensitive()->SensitivityFactor());
}
} }
} }
@@ -134,7 +142,24 @@ void SelectMgr_Selection::SetSelectionState (const SelectMgr_StateOfSelection th
// function: Sensitivity // function: Sensitivity
// purpose : Returns sensitivity of the selection // purpose : Returns sensitivity of the selection
//================================================== //==================================================
Standard_Real SelectMgr_Selection::Sensitivity() const Standard_Integer SelectMgr_Selection::Sensitivity() const
{ {
return mySensFactor; return mySensFactor;
} }
//==================================================
// function: SetSensitivity
// purpose : Changes sensitivity of the selection and all its entities to the given value.
// IMPORTANT: This method does not update any outer selection structures, so for
// proper updates use SelectMgr_SelectionManager::SetSelectionSensitivity method.
//==================================================
void SelectMgr_Selection::SetSensitivity (const Standard_Integer theNewSens)
{
mySensFactor = theNewSens;
myIsCustomSens = Standard_True;
for (Standard_Integer anIdx = 0; anIdx < myEntities.Size(); ++anIdx)
{
Handle(SelectMgr_SensitiveEntity)& anEntity = myEntities.ChangeValue (anIdx);
anEntity->BaseSensitive()->SetSensitivityFactor (theNewSens);
}
}

View File

@@ -131,7 +131,12 @@ public:
Standard_EXPORT void SetSelectionState (const SelectMgr_StateOfSelection theState) const; Standard_EXPORT void SetSelectionState (const SelectMgr_StateOfSelection theState) const;
//! Returns sensitivity of the selection //! Returns sensitivity of the selection
Standard_EXPORT Standard_Real Sensitivity() const; Standard_EXPORT Standard_Integer Sensitivity() const;
//! Changes sensitivity of the selection and all its entities to the given value.
//! IMPORTANT: This method does not update any outer selection structures, so for
//! proper updates use SelectMgr_SelectionManager::SetSelectionSensitivity method.
Standard_EXPORT void SetSensitivity (const Standard_Integer theNewSens);
DEFINE_STANDARD_RTTI (SelectMgr_Selection) DEFINE_STANDARD_RTTI (SelectMgr_Selection)
@@ -148,7 +153,8 @@ private:
SelectMgr_TypeOfUpdate myUpdateStatus; SelectMgr_TypeOfUpdate myUpdateStatus;
mutable SelectMgr_StateOfSelection mySelectionState; mutable SelectMgr_StateOfSelection mySelectionState;
mutable SelectMgr_TypeOfBVHUpdate myBVHUpdateStatus; mutable SelectMgr_TypeOfBVHUpdate myBVHUpdateStatus;
Standard_Real mySensFactor; Standard_Integer mySensFactor;
Standard_Boolean myIsCustomSens;
}; };
DEFINE_STANDARD_HANDLE(SelectMgr_Selection, MMgt_TShared) DEFINE_STANDARD_HANDLE(SelectMgr_Selection, MMgt_TShared)

View File

@@ -201,7 +201,14 @@ is
is static; is static;
---Purpose: Sets type of update of selection with theMode of theObject to the given theType. ---Purpose: Sets type of update of selection with theMode of theObject to the given theType.
SetSelectionSensitivity (me : mutable;
theObject : SelectableObject from SelectMgr;
theMode : Integer from Standard;
theNewSens : Integer from Standard)
is static;
---Purpose: Allows to manage sensitivity of a particular selection of interactive object theObject and
-- changes previous sensitivity value of all sensitive entities in selection with theMode
-- to the given theNewSensitivity.

View File

@@ -914,3 +914,51 @@ void SelectMgr_SelectionManager::SetUpdateMode (const Handle(SelectMgr_Selectabl
theObject->Selection (theMode)->UpdateStatus (theType); theObject->Selection (theMode)->UpdateStatus (theType);
} }
//=======================================================================
//function : SetSelectionSensitivity
//purpose : Allows to manage sensitivity of a particular selection of interactive object theObject and
// changes previous sensitivity value of all sensitive entities in selection with theMode
// to the given theNewSensitivity.
//=======================================================================
void SelectMgr_SelectionManager::SetSelectionSensitivity (const Handle(SelectMgr_SelectableObject)& theObject,
const Standard_Integer theMode,
const Standard_Integer theNewSens)
{
Standard_ASSERT_RAISE (theNewSens > 0,
"Error! Selection sensitivity have positive value.");
if (theObject.IsNull() || !theObject->HasSelection (theMode))
return;
Handle(SelectMgr_Selection) aSel = theObject->Selection (theMode);
const Standard_Integer aPrevSens = aSel->Sensitivity();
aSel->SetSensitivity (theNewSens);
if (!(myGlobal.Contains (theObject) || myLocal.IsBound (theObject)))
return;
if (myGlobal.Contains (theObject))
{
for (TColStd_MapIteratorOfMapOfTransient aSelectorsIter (mySelectors); aSelectorsIter.More(); aSelectorsIter.Next())
{
Handle(SelectMgr_ViewerSelector) aSelector = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectorsIter.Key());
if (aSelector->Contains (theObject))
{
aSelector->myTolerances.Decrement (aPrevSens);
aSelector->myTolerances.Add (theNewSens);
aSelector->myToUpdateTolerance = Standard_True;
}
}
}
if (myLocal.IsBound (theObject))
{
const SelectMgr_SequenceOfSelector& aSelectors = myLocal (theObject);
for (Standard_Integer aSelectorsIdx = 1; aSelectorsIdx <= aSelectors.Length(); aSelectorsIdx++)
{
Handle(SelectMgr_ViewerSelector) aCurSel = Handle(SelectMgr_ViewerSelector)::DownCast (aSelectors (aSelectorsIdx));
aCurSel->myTolerances.Decrement (aPrevSens);
aCurSel->myTolerances.Add (theNewSens);
aCurSel->myToUpdateTolerance = Standard_True;
}
}
}

View File

@@ -15,10 +15,6 @@
#include <SelectMgr_TriangularFrustum.hxx> #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() SelectMgr_TriangularFrustum::~SelectMgr_TriangularFrustum()
{ {
Clear(); Clear();
@@ -26,23 +22,55 @@ SelectMgr_TriangularFrustum::~SelectMgr_TriangularFrustum()
namespace namespace
{ {
void computeFrustumNormals (const SelectMgr_Vec3* theVertices, SelectMgr_Vec3* theNormals) void computeFrustumNormals (const gp_Vec* theEdges, gp_Vec* theNormals)
{ {
// V0V1 // V0V1
theNormals[0] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[0], theNormals[0] = theEdges[0].Crossed (theEdges[1]);
theVertices[4] - theVertices[0]);
// V1V2 // V1V2
theNormals[1] = SelectMgr_Vec3::Cross (theVertices[4] - theVertices[1], theNormals[1] = theEdges[1].Crossed (theEdges[2]);
theVertices[5] - theVertices[1]);
// V0V2 // V0V2
theNormals[2] = SelectMgr_Vec3::Cross (theVertices[3] - theVertices[0], theNormals[2] = theEdges[0].Crossed (theEdges[2]);
theVertices[5] - theVertices[0]);
// Near // Near
theNormals[3] = SelectMgr_Vec3::Cross (theVertices[1] - theVertices[0], theNormals[3] = theEdges[3].Crossed (theEdges[5]);
theVertices[2] - theVertices[0]);
// Far // Far
theNormals[4] = SelectMgr_Vec3::Cross (theVertices[4] - theVertices[3], theNormals[4] = -theNormals[3];
theVertices[5] - theVertices[3]); }
}
// =======================================================================
// function : cacheVertexProjections
// purpose : Caches projection of frustum's vertices onto its plane directions
// and {i, j, k}
// =======================================================================
void SelectMgr_TriangularFrustum::cacheVertexProjections (SelectMgr_TriangularFrustum* theFrustum)
{
for (Standard_Integer aPlaneIdx = 0; aPlaneIdx < 5; ++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 < 6; ++aVertIdx)
{
Standard_Real aProjection = aPlane.Dot (theFrustum->myVertices[aVertIdx].XYZ());
aMax = Max (aMax, aProjection);
aMin = Min (aMin, aProjection);
}
theFrustum->myMaxVertsProjections[aPlaneIdx] = aMax;
theFrustum->myMinVertsProjections[aPlaneIdx] = aMin;
}
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 = theFrustum->myVertices[aVertIdx].XYZ().Ptr()[aDim];
aMax = Max (aMax, aProjection);
aMin = Min (aMin, aProjection);
}
theFrustum->myMaxOrthoVertsProjections[aDim] = aMax;
theFrustum->myMinOrthoVertsProjections[aDim] = aMin;
} }
} }
@@ -69,131 +97,71 @@ void SelectMgr_TriangularFrustum::Build (const gp_Pnt2d& theP1,
// V2_Far // V2_Far
myVertices[5] = myBuilder->ProjectPntOnViewPlane (theP3.X(), theP3.Y(), 1.0); 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];
for (Standard_Integer aVertIdx = 0; aVertIdx < 6; ++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 < 6; ++aVertIdx)
{
Standard_Real aProjection = DOT (aDimensions[aDim], myVertices[aVertIdx]);
aMax = Max (aMax, aProjection);
aMin = Min (aMin, aProjection);
}
myMaxOrthoVertsProjections[aDim] = aMax;
myMinOrthoVertsProjections[aDim] = aMin;
}
// V0_Near - V0_Far // V0_Near - V0_Far
myEdgeDirs[0] = myVertices[0] - myVertices[3]; myEdgeDirs[0] = myVertices[0].XYZ() - myVertices[3].XYZ();
// V1_Near - V1_Far // V1_Near - V1_Far
myEdgeDirs[1] = myVertices[1] - myVertices[4]; myEdgeDirs[1] = myVertices[1].XYZ() - myVertices[4].XYZ();
// V2_Near - V1_Far // V2_Near - V1_Far
myEdgeDirs[2] = myVertices[2] - myVertices[5]; myEdgeDirs[2] = myVertices[2].XYZ() - myVertices[5].XYZ();
// V1_Near - V0_Near // V1_Near - V0_Near
myEdgeDirs[3] = myVertices[1] - myVertices[0]; myEdgeDirs[3] = myVertices[1].XYZ() - myVertices[0].XYZ();
// V2_Near - V1_Near // V2_Near - V1_Near
myEdgeDirs[4] = myVertices[2] - myVertices[1]; myEdgeDirs[4] = myVertices[2].XYZ() - myVertices[1].XYZ();
// V1_Near - V0_Near // 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 // function : ScaleAndTransform
// purpose : Returns a copy of the frustum transformed according to the matrix given // 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(); SelectMgr_TriangularFrustum* aRes = new SelectMgr_TriangularFrustum();
// V0_Near // V0_Near
aRes->myVertices[0] = SelectMgr_MatOp::Transform (theTrsf, myVertices[0]); aRes->myVertices[0] = myVertices[0].Transformed (theTrsf);
// V1_Near // V1_Near
aRes->myVertices[1] = SelectMgr_MatOp::Transform (theTrsf, myVertices[1]); aRes->myVertices[1] = myVertices[1].Transformed (theTrsf);
// V2_Near // V2_Near
aRes->myVertices[2] = SelectMgr_MatOp::Transform (theTrsf, myVertices[2]); aRes->myVertices[2] = myVertices[2].Transformed (theTrsf);
// V0_Far // V0_Far
aRes->myVertices[3] = SelectMgr_MatOp::Transform (theTrsf, myVertices[3]); aRes->myVertices[3] = myVertices[3].Transformed (theTrsf);
// V1_Far // V1_Far
aRes->myVertices[4] = SelectMgr_MatOp::Transform (theTrsf, myVertices[4]); aRes->myVertices[4] = myVertices[4].Transformed (theTrsf);
// V2_Far // V2_Far
aRes->myVertices[5] = SelectMgr_MatOp::Transform (theTrsf, myVertices[5]); aRes->myVertices[5] = myVertices[5].Transformed (theTrsf);
aRes->myIsOrthographic = myIsOrthographic; 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 // 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 // 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 // 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 // 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 // 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 // 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); return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
} }
@@ -203,10 +171,11 @@ NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustum::Transform
// purpose : SAT intersection test between defined volume and // purpose : SAT intersection test between defined volume and
// given axis-aligned box // 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*/) Standard_Real& /*theDepth*/)
{ {
return hasOverlap (theBox.CornerMin(), theBox.CornerMax()); return hasOverlap (theMinPt, theMaxPt);
} }
// ======================================================================= // =======================================================================
@@ -261,7 +230,7 @@ Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const Handle(TColgp_HArr
} }
else if (theSensType == Select3D_TOS_INTERIOR) else if (theSensType == Select3D_TOS_INTERIOR)
{ {
SelectMgr_Vec3 aNorm (RealLast()); gp_Vec aNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
return hasOverlap (theArrayOfPnts, aNorm); return hasOverlap (theArrayOfPnts, aNorm);
} }
@@ -302,7 +271,7 @@ Standard_Boolean SelectMgr_TriangularFrustum::Overlaps (const gp_Pnt& thePnt1,
} }
else if (theSensType == Select3D_TOS_INTERIOR) else if (theSensType == Select3D_TOS_INTERIOR)
{ {
SelectMgr_Vec3 aNorm (RealLast()); gp_Vec aNorm (gp_XYZ (RealLast(), RealLast(), RealLast()));
return hasOverlap (thePnt1, thePnt2, thePnt3, aNorm); return hasOverlap (thePnt1, thePnt2, thePnt3, aNorm);
} }

View File

@@ -40,12 +40,14 @@ public:
const gp_Pnt2d& theP3) Standard_OVERRIDE; const gp_Pnt2d& theP3) Standard_OVERRIDE;
//! Returns a copy of the frustum transformed according to the matrix given //! Returns a copy of the frustum transformed according to the matrix given
virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE; virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScale,
const gp_Trsf& theTrsf) Standard_OVERRIDE;
// SAT Tests for different objects // SAT Tests for different objects
//! SAT intersection test between defined volume and given axis-aligned box //! SAT intersection test between defined volume and given axis-aligned box
virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox, virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
const SelectMgr_Vec3& theMaxPnt,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
//! Returns true if selecting volume is overlapped by axis-aligned bounding box //! Returns true if selecting volume is overlapped by axis-aligned bounding box
@@ -81,6 +83,10 @@ public:
//! Nullifies the handle to corresponding builder instance to prevent memory leaks //! Nullifies the handle to corresponding builder instance to prevent memory leaks
void Clear(); void Clear();
private:
void cacheVertexProjections (SelectMgr_TriangularFrustum* theFrustum);
}; };
#endif // _SelectMgr_TriangularFrustum_HeaderFile #endif // _SelectMgr_TriangularFrustum_HeaderFile

View File

@@ -102,17 +102,24 @@ void SelectMgr_TriangularFrustumSet::Build (const TColgp_Array1OfPnt2d& thePoint
} }
// ======================================================================= // =======================================================================
// function : Transform // function : ScaleAndTransform
// purpose : Returns a copy of the frustum with all sub-volumes transformed // purpose : IMPORTANT: Scaling makes sense only for frustum built on a single point!
// according to the matrix given // 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::Transform (const gp_Trsf& theTrsf) NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::ScaleAndTransform (const Standard_Integer theScale,
const gp_Trsf& theTrsf)
{ {
SelectMgr_TriangularFrustumSet* aRes = new SelectMgr_TriangularFrustumSet(); SelectMgr_TriangularFrustumSet* aRes = new SelectMgr_TriangularFrustumSet();
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next())
{ {
aRes->myFrustums.Append (NCollection_Handle<SelectMgr_TriangularFrustum>::DownCast (anIter.Value()->Transform (theTrsf))); aRes->myFrustums.Append (NCollection_Handle<SelectMgr_TriangularFrustum>::DownCast (anIter.Value()->ScaleAndTransform (theScale, theTrsf)));
} }
return NCollection_Handle<SelectMgr_BaseFrustum> (aRes); return NCollection_Handle<SelectMgr_BaseFrustum> (aRes);
@@ -122,12 +129,13 @@ NCollection_Handle<SelectMgr_BaseFrustum> SelectMgr_TriangularFrustumSet::Transf
// function : Overlaps // function : Overlaps
// purpose : // 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) Standard_Real& theDepth)
{ {
for (SelectMgr_TriangFrustumsIter anIter (myFrustums); anIter.More(); anIter.Next()) 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; return Standard_True;
} }

View File

@@ -48,29 +48,31 @@ public:
virtual void Build (const TColgp_Array1OfPnt2d& thePoints) Standard_OVERRIDE; 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 //! Returns a copy of the frustum with all sub-volumes transformed according to the matrix given
virtual NCollection_Handle<SelectMgr_BaseFrustum> Transform (const gp_Trsf& theTrsf) Standard_OVERRIDE; virtual NCollection_Handle<SelectMgr_BaseFrustum> ScaleAndTransform (const Standard_Integer theScale,
const gp_Trsf& theTrsf) Standard_OVERRIDE;
virtual Standard_Boolean Overlaps (const BVH_Box<Standard_Real, 3>& theBox, virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
const SelectMgr_Vec3& theMaxPnt,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt, virtual Standard_Boolean Overlaps (const SelectMgr_Vec3& theMinPnt,
const SelectMgr_Vec3& theMaxPnt, const SelectMgr_Vec3& theMaxPnt,
Standard_Boolean* theInside) Standard_OVERRIDE; Standard_Boolean* theInside) Standard_OVERRIDE;
virtual Standard_Boolean Overlaps (const gp_Pnt& thePt, virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPts, virtual Standard_Boolean Overlaps (const Handle(TColgp_HArray1OfPnt)& theArrayOfPnts,
Select3D_TypeOfSensitivity theSensType, Select3D_TypeOfSensitivity theSensType,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1, virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
const gp_Pnt& thePt2, const gp_Pnt& thePnt2,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;
virtual Standard_Boolean Overlaps (const gp_Pnt& thePt1, virtual Standard_Boolean Overlaps (const gp_Pnt& thePnt1,
const gp_Pnt& thePt2, const gp_Pnt& thePnt2,
const gp_Pnt& thePt3, const gp_Pnt& thePnt3,
Select3D_TypeOfSensitivity theSensType, Select3D_TypeOfSensitivity theSensType,
Standard_Real& theDepth) Standard_OVERRIDE; Standard_Real& theDepth) Standard_OVERRIDE;

View File

@@ -45,8 +45,8 @@ IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, MMgt_TShared)
//======================================================================= //=======================================================================
SelectMgr_ToleranceMap::SelectMgr_ToleranceMap() SelectMgr_ToleranceMap::SelectMgr_ToleranceMap()
{ {
myLargestKey = -1.0; myLargestKey = 2;
myCustomTolerance = -1.0; myCustomTolerance = -1;
} }
//======================================================================= //=======================================================================
@@ -63,7 +63,7 @@ SelectMgr_ToleranceMap::~SelectMgr_ToleranceMap()
// purpose : Adds the value given to map, checks if the current tolerance value // purpose : Adds the value given to map, checks if the current tolerance value
// should be replaced by theTolerance // 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)) if (myTolerances.IsBound (theTolerance))
{ {
@@ -92,7 +92,7 @@ void SelectMgr_ToleranceMap::Add (const Standard_Real& theTolerance)
// purpose : Decrements a counter of the tolerance given, checks if the current tolerance value // purpose : Decrements a counter of the tolerance given, checks if the current tolerance value
// should be recalculated // should be recalculated
//======================================================================= //=======================================================================
void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance) void SelectMgr_ToleranceMap::Decrement (const Standard_Integer& theTolerance)
{ {
if (myTolerances.IsBound (theTolerance)) if (myTolerances.IsBound (theTolerance))
{ {
@@ -101,8 +101,8 @@ void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0) if (Abs (theTolerance - myLargestKey) < Precision::Confusion() && aFreq == 0)
{ {
myLargestKey = 0.0; myLargestKey = 0;
for (NCollection_DataMap<Standard_Real, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next()) for (NCollection_DataMap<Standard_Integer, Standard_Integer>::Iterator anIter (myTolerances); anIter.More(); anIter.Next())
{ {
if (anIter.Value() != 0) if (anIter.Value() != 0)
myLargestKey = Max (myLargestKey, anIter.Key()); myLargestKey = Max (myLargestKey, anIter.Key());
@@ -115,16 +115,16 @@ void SelectMgr_ToleranceMap::Decrement (const Standard_Real& theTolerance)
// function: Tolerance // function: Tolerance
// purpose : Returns a current tolerance that must be applied // purpose : Returns a current tolerance that must be applied
//======================================================================= //=======================================================================
Standard_Real SelectMgr_ToleranceMap::Tolerance() Standard_Integer SelectMgr_ToleranceMap::Tolerance() const
{ {
return myCustomTolerance < 0.0 ? myLargestKey : myCustomTolerance; return myCustomTolerance < 0 ? myLargestKey : myCustomTolerance;
} }
//======================================================================= //=======================================================================
// function: SetCustomTolerance // function: SetCustomTolerance
// purpose : Sets tolerance to the given one and disables adaptive checks // purpose : Sets tolerance to the given one and disables adaptive checks
//======================================================================= //=======================================================================
void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theTolerance) void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Integer theTolerance)
{ {
myCustomTolerance = theTolerance; myCustomTolerance = theTolerance;
} }
@@ -135,7 +135,7 @@ void SelectMgr_ToleranceMap::SetCustomTolerance (const Standard_Real theToleranc
//======================================================================= //=======================================================================
void SelectMgr_ToleranceMap::ResetDefaults() void SelectMgr_ToleranceMap::ResetDefaults()
{ {
myCustomTolerance = -1.0; myCustomTolerance = -1;
} }
//================================================== //==================================================
@@ -144,7 +144,6 @@ void SelectMgr_ToleranceMap::ResetDefaults()
//================================================== //==================================================
SelectMgr_ViewerSelector::SelectMgr_ViewerSelector(): SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
preferclosest(Standard_True), preferclosest(Standard_True),
mytolerance(2.0),
myToUpdateTolerance (Standard_True), myToUpdateTolerance (Standard_True),
myCurRank (0), myCurRank (0),
myIsLeftChildQueuedFirst (Standard_False), myIsLeftChildQueuedFirst (Standard_False),
@@ -168,7 +167,6 @@ void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theS
theSelection->SetSelectionState (SelectMgr_SOS_Activated); theSelection->SetSelectionState (SelectMgr_SOS_Activated);
myTolerances.Add (theSelection->Sensitivity()); myTolerances.Add (theSelection->Sensitivity());
mytolerance = myTolerances.Tolerance();
myToUpdateTolerance = Standard_True; myToUpdateTolerance = Standard_True;
} }
@@ -187,7 +185,6 @@ void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& th
theSelection->SetSelectionState (SelectMgr_SOS_Deactivated); theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
myTolerances.Decrement (theSelection->Sensitivity()); myTolerances.Decrement (theSelection->Sensitivity());
mytolerance = myTolerances.Tolerance();
myToUpdateTolerance = Standard_True; myToUpdateTolerance = Standard_True;
} }
@@ -211,29 +208,6 @@ Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select
&& theEntity->SensitivityFactor() < myTolerances.Tolerance(); && theEntity->SensitivityFactor() < 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: checkOverlap // function: checkOverlap
// purpose : Internal function that checks if a particular sensitive // purpose : Internal function that checks if a particular sensitive
@@ -261,7 +235,7 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
Standard_Integer aPriority = anOwner->Priority(); 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 (mystored.Contains (anOwner))
{ {
if (theMgr.GetActiveSelectionType() != 1) if (theMgr.GetActiveSelectionType() != 1)
@@ -283,6 +257,40 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive
} }
} }
//=======================================================================
// 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 = theEnt->SensitivityFactor();
}
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 // function: traverseObject
// purpose : Internal function that checks if there is possible overlap // purpose : Internal function that checks if there is possible overlap
@@ -300,9 +308,9 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH(); const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ? SelectMgr_SelectingVolumeManager aMgr = theObject->HasTransformation() ?
mySelectingVolumeMgr.Transform (theObject->InversedTransformation()) : mySelectingVolumeMgr; mySelectingVolumeMgr.ScaleAndTransform (1, theObject->InversedTransformation()) : mySelectingVolumeMgr;
NCollection_DataMap<Handle(Standard_Type), SelectMgr_SelectingVolumeManager> aScaledTrnsfFrustums; SelectMgr_FrustumCache aScaledTrnsfFrustums;
Standard_Integer aNode = 0; // a root node Standard_Integer aNode = 0; // a root node
if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0), if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
@@ -357,16 +365,7 @@ void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_Selectable
{ {
const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive(); const Handle(SelectBasics_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
SelectMgr_SelectingVolumeManager aTmpMgr = aMgr; SelectMgr_SelectingVolumeManager aTmpMgr = aMgr;
if (isToScaleFrustum (anEnt)) computeFrustum (anEnt, theObject->InversedTransformation(), aScaledTrnsfFrustums, aTmpMgr);
{
if (!aScaledTrnsfFrustums.IsBound (anEnt->DynamicType()))
{
aScaledTrnsfFrustums.Bind (anEnt->DynamicType(),
scaleAndTransform (anEnt->SensitivityFactor(), theObject->InversedTransformation()));
}
aTmpMgr = aScaledTrnsfFrustums.Find (anEnt->DynamicType());
}
checkOverlap (anEnt, anIdx, aTmpMgr); checkOverlap (anEnt, anIdx, aTmpMgr);
} }
} }
@@ -839,9 +838,8 @@ const Handle(SelectBasics_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEn
// function : ActiveOwners // function : ActiveOwners
// purpose : Returns the list of active entity owners // purpose : Returns the list of active entity owners
//======================================================================= //=======================================================================
NCollection_List<Handle(SelectBasics_EntityOwner)> SelectMgr_ViewerSelector::ActiveOwners() const void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const
{ {
NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next()) for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
{ {
const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value(); const NCollection_Handle<SelectMgr_SensitiveEntitySet>& anEntitySet = anIter.Value();
@@ -850,10 +848,8 @@ NCollection_List<Handle(SelectBasics_EntityOwner)> SelectMgr_ViewerSelector::Act
{ {
if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection()) if (anEntitySet->GetSensitiveById (anIdx)->IsActiveForSelection())
{ {
anActiveOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId()); theOwners.Append (anEntitySet->GetSensitiveById (anIdx)->BaseSensitive()->OwnerId());
} }
} }
} }
return anActiveOwners;
} }

View File

@@ -57,6 +57,8 @@ typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), NCollection_Hand
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwnerDetectedEntities; typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer> SelectMgr_MapOfOwnerDetectedEntities;
typedef NCollection_DataMap<Handle(SelectMgr_EntityOwner), Standard_Integer>::Iterator SelectMgr_MapOfOwnerDetectedEntitiesIterator; 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 //! 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, //! 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 //! maximum tolerance value will be recalculated. If a user enables custom precision using
@@ -73,25 +75,25 @@ public:
//! Adds the value given to map, checks if the current tolerance value //! Adds the value given to map, checks if the current tolerance value
//! should be replaced by theTolerance //! 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 //! Decrements a counter of the tolerance given, checks if the current tolerance value
//! should be recalculated //! 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 //! Returns a current tolerance that must be applied
Standard_EXPORT Standard_Real Tolerance(); Standard_EXPORT Standard_Integer Tolerance() const;
//! Sets tolerance to the given one and disables adaptive checks //! Sets tolerance to the given one and disables adaptive checks
Standard_EXPORT void SetCustomTolerance (const Standard_Real theTolerance); Standard_EXPORT void SetCustomTolerance (const Standard_Integer theTolerance);
//! Unsets a custom tolerance and enables adaptive checks //! Unsets a custom tolerance and enables adaptive checks
Standard_EXPORT void ResetDefaults(); Standard_EXPORT void ResetDefaults();
private: private:
NCollection_DataMap<Standard_Real, Standard_Integer> myTolerances; NCollection_DataMap<Standard_Integer, Standard_Integer> myTolerances;
Standard_Real myLargestKey; Standard_Integer myLargestKey;
Standard_Real myCustomTolerance; Standard_Integer myCustomTolerance;
}; };
//! A framework to define finding, sorting the sensitive //! A framework to define finding, sorting the sensitive
@@ -132,7 +134,7 @@ public:
Standard_EXPORT void Clear(); Standard_EXPORT void Clear();
//! returns the Sensitivity of picking //! returns the Sensitivity of picking
Standard_Real Sensitivity() const; Standard_Integer Sensitivity() const;
//! Sorts the detected entites by priority and distance. //! Sorts the detected entites by priority and distance.
//! to be redefined if other criterion are used... //! to be redefined if other criterion are used...
@@ -203,7 +205,7 @@ public:
Standard_EXPORT TCollection_AsciiString Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const; Standard_EXPORT TCollection_AsciiString Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const;
//! Returns the list of active entity owners //! Returns the list of active entity owners
Standard_EXPORT NCollection_List<Handle(SelectBasics_EntityOwner)> ActiveOwners() const; Standard_EXPORT void ActiveOwners (NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners) const;
//! Adds new object to the map of selectable objects //! Adds new object to the map of selectable objects
Standard_EXPORT void AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject); Standard_EXPORT void AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject);
@@ -283,10 +285,6 @@ protected:
//! Checks if the entity given requires to scale current selecting frustum //! Checks if the entity given requires to scale current selecting frustum
Standard_Boolean isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity); Standard_Boolean isToScaleFrustum (const Handle(SelectBasics_SensitiveEntity)& theEntity);
//! Applies given scale and transformation matrices to the default selecting volume manager
SelectMgr_SelectingVolumeManager scaleAndTransform (const Standard_Real theScale,
const gp_Trsf& theTrsf);
private: private:
void Activate (const Handle(SelectMgr_Selection)& theSelection); void Activate (const Handle(SelectMgr_Selection)& theSelection);
@@ -296,10 +294,17 @@ private:
//! removes a Selection from the Selector //! removes a Selection from the Selector
void Remove (const Handle(SelectMgr_Selection)& aSelection); 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: protected:
Standard_Boolean preferclosest; Standard_Boolean preferclosest;
Standard_Real mytolerance;
Standard_Boolean myToUpdateTolerance; Standard_Boolean myToUpdateTolerance;
SelectMgr_IndexedDataMapOfOwnerCriterion mystored; SelectMgr_IndexedDataMapOfOwnerCriterion mystored;
SelectMgr_SelectingVolumeManager mySelectingVolumeMgr; SelectMgr_SelectingVolumeManager mySelectingVolumeMgr;

View File

@@ -12,9 +12,9 @@
// Alternatively, this file may be used under the terms of Open CASCADE // Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement. // commercial license or contractual agreement.
inline Standard_Real SelectMgr_ViewerSelector::Sensitivity() const inline Standard_Integer SelectMgr_ViewerSelector::Sensitivity() const
{ {
return mytolerance; return myTolerances.Tolerance();
} }
inline void SelectMgr_ViewerSelector::Init() inline void SelectMgr_ViewerSelector::Init()

View File

@@ -93,15 +93,14 @@ StdSelect_ViewerSelector3d::StdSelect_ViewerSelector3d() {}
// Function: SetPixelTolerance // Function: SetPixelTolerance
// Purpose : // Purpose :
//======================================================================= //=======================================================================
void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Real theTolerance) void StdSelect_ViewerSelector3d::SetPixelTolerance (const Standard_Integer theTolerance)
{ {
if (mytolerance != theTolerance) if (myTolerances.Tolerance() != theTolerance)
{ {
if (theTolerance < 0.0) if (theTolerance < 0)
myTolerances.ResetDefaults(); myTolerances.ResetDefaults();
else else
myTolerances.SetCustomTolerance (theTolerance); myTolerances.SetCustomTolerance (theTolerance);
mytolerance = myTolerances.Tolerance();
myToUpdateTolerance = Standard_True; myToUpdateTolerance = Standard_True;
} }
} }
@@ -118,7 +117,7 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
if(myToUpdateTolerance) if(myToUpdateTolerance)
{ {
mySelectingVolumeMgr.SetPixelTolerance (mytolerance); mySelectingVolumeMgr.SetPixelTolerance (myTolerances.Tolerance());
myToUpdateTolerance = Standard_False; myToUpdateTolerance = Standard_False;
} }

View File

@@ -48,10 +48,10 @@ public:
Standard_EXPORT StdSelect_ViewerSelector3d(); Standard_EXPORT StdSelect_ViewerSelector3d();
//! Sets the pixel tolerance <theTolerance>. //! 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. //! Returns the pixel tolerance.
Standard_Real PixelTolerance() const; inline Standard_Integer PixelTolerance() const;
//! Picks the sensitive entity at the pixel coordinates of //! Picks the sensitive entity at the pixel coordinates of
//! the mouse <theXPix> and <theYPix>. The selector looks for touched areas and owners. //! the mouse <theXPix> and <theYPix>. The selector looks for touched areas and owners.

View File

@@ -12,7 +12,7 @@
// Alternatively, this file may be used under the terms of Open CASCADE // Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement. // commercial license or contractual agreement.
inline Standard_Real StdSelect_ViewerSelector3d::PixelTolerance() const inline Standard_Integer StdSelect_ViewerSelector3d::PixelTolerance() const
{ {
return mytolerance; return myTolerances.Tolerance();
} }

View File

@@ -768,11 +768,11 @@ static int VSelPrecision(Draw_Interpretor& di, Standard_Integer argc, const char
anArg.LowerCase(); anArg.LowerCase();
if (anArg == "-unset") if (anArg == "-unset")
{ {
aContext->SetPixelTolerance (-1.0); aContext->SetPixelTolerance (-1);
} }
else else
{ {
aContext->SetPixelTolerance (anArg.RealValue()); aContext->SetPixelTolerance (anArg.IntegerValue());
} }
} }
@@ -1392,6 +1392,10 @@ struct ViewerTest_AspectsChangeSet
Standard_Integer ToSetFreeBoundaryColor; Standard_Integer ToSetFreeBoundaryColor;
Quantity_Color FreeBoundaryColor; Quantity_Color FreeBoundaryColor;
Standard_Integer ToSetSensitivity;
Standard_Integer SelectionMode;
Standard_Integer Sensitivity;
//! Empty constructor //! Empty constructor
ViewerTest_AspectsChangeSet() ViewerTest_AspectsChangeSet()
: ToSetVisibility (0), : ToSetVisibility (0),
@@ -1408,7 +1412,10 @@ struct ViewerTest_AspectsChangeSet
ToSetFreeBoundaryWidth (0), ToSetFreeBoundaryWidth (0),
FreeBoundaryWidth (1.0), FreeBoundaryWidth (1.0),
ToSetFreeBoundaryColor (0), ToSetFreeBoundaryColor (0),
FreeBoundaryColor (DEFAULT_FREEBOUNDARY_COLOR) {} FreeBoundaryColor (DEFAULT_FREEBOUNDARY_COLOR),
ToSetSensitivity (0),
SelectionMode (-1),
Sensitivity (-1) {}
//! @return true if no changes have been requested //! @return true if no changes have been requested
Standard_Boolean IsEmpty() const Standard_Boolean IsEmpty() const
@@ -1420,7 +1427,8 @@ struct ViewerTest_AspectsChangeSet
&& ToSetMaterial == 0 && ToSetMaterial == 0
&& ToSetShowFreeBoundary == 0 && ToSetShowFreeBoundary == 0
&& ToSetFreeBoundaryColor == 0 && ToSetFreeBoundaryColor == 0
&& ToSetFreeBoundaryWidth == 0; && ToSetFreeBoundaryWidth == 0
&& ToSetSensitivity == 0;
} }
//! @return true if properties are valid //! @return true if properties are valid
@@ -1462,6 +1470,11 @@ struct ViewerTest_AspectsChangeSet
std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n"; std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n";
isOk = Standard_False; isOk = Standard_False;
} }
if (Sensitivity <= 0 && ToSetSensitivity)
{
std::cout << "Error: sensitivity parameter value should be positive (specified " << Sensitivity << ")\n";
isOk = Standard_False;
}
return isOk; return isOk;
} }
@@ -1950,6 +1963,29 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
aChangeSet->ToSetFreeBoundaryWidth = -1; aChangeSet->ToSetFreeBoundaryWidth = -1;
aChangeSet->FreeBoundaryWidth = 1.0; aChangeSet->FreeBoundaryWidth = 1.0;
} }
else if (anArg == "-setsensitivity")
{
if (isDefaults)
{
std::cout << "Error: wrong syntax. -setSensitivity can not be used together with -defaults call!\n";
return 1;
}
if (aNames.IsEmpty())
{
std::cout << "Error: object and selection mode should specified explicitly when -setSensitivity is used!\n";
return 1;
}
if (anArgIter + 2 >= theArgNb)
{
std::cout << "Error: wrong syntax at " << anArg << "\n";
return 1;
}
aChangeSet->ToSetSensitivity = 1;
aChangeSet->SelectionMode = Draw::Atoi (theArgVec[++anArgIter]);
aChangeSet->Sensitivity = Draw::Atoi (theArgVec[++anArgIter]);
}
else else
{ {
std::cout << "Error: wrong syntax at " << anArg << "\n"; std::cout << "Error: wrong syntax at " << anArg << "\n";
@@ -2102,6 +2138,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
{ {
aCtx->UnsetWidth (aPrs, Standard_False); aCtx->UnsetWidth (aPrs, Standard_False);
} }
else if (aChangeSet->ToSetSensitivity != 0)
{
aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
}
if (!aDrawer.IsNull()) if (!aDrawer.IsNull())
{ {
if (aChangeSet->ToSetShowFreeBoundary == 1) if (aChangeSet->ToSetShowFreeBoundary == 1)
@@ -2159,6 +2199,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/,
{ {
aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True); aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True);
} }
if (aChangeSet->ToSetSensitivity != 0)
{
aCtx->SetSelectionSensitivity (aPrs, aChangeSet->SelectionMode, aChangeSet->Sensitivity);
}
} }
} }
if (toDisplay) if (toDisplay)
@@ -4278,11 +4322,12 @@ static Standard_Integer VState (Draw_Interpretor& theDI,
const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity(); const Handle(SelectBasics_SensitiveEntity)& anEntity = aSelector->DetectedEntity();
Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId()); Handle(SelectMgr_EntityOwner) anOwner = Handle(SelectMgr_EntityOwner)::DownCast (anEntity->OwnerId());
Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable()); Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
SelectMgr_SelectingVolumeManager aMgr = anObj->HasTransformation() ? aSelector->GetManager().Transform (anObj->InversedTransformation()) SelectMgr_SelectingVolumeManager aMgr =
: aSelector->GetManager(); anObj->HasTransformation() ? aSelector->GetManager().ScaleAndTransform (1, anObj->InversedTransformation())
: aSelector->GetManager();
SelectBasics_PickResult aResult; SelectBasics_PickResult aResult;
anEntity->Matches (aMgr, 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); TCollection_AsciiString aName = GetMapOfAIS().Find1 (anObj);
aName.LeftJustify (20, ' '); aName.LeftJustify (20, ' ');
@@ -4291,7 +4336,7 @@ static Standard_Integer VState (Draw_Interpretor& theDI,
" Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f", " Depth: %+.3f Distance: %+.3f Point: %+.3f %+.3f %+.3f",
aResult.Depth(), aResult.Depth(),
aResult.DistToGeomCenter(), aResult.DistToGeomCenter(),
aDetectedPnt.x(), aDetectedPnt.y(), aDetectedPnt.z()); aDetectedPnt.X(), aDetectedPnt.Y(), aDetectedPnt.Z());
theDI << " " << aName theDI << " " << aName
<< anInfoStr << anInfoStr
<< " (" << anEntity->DynamicType()->Name() << ")" << " (" << anEntity->DynamicType()->Name() << ")"
@@ -5214,6 +5259,7 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands)
"\n\t\t: [-setFreeBoundaryWidth Width] [-unsetFreeBoundaryWidth]" "\n\t\t: [-setFreeBoundaryWidth Width] [-unsetFreeBoundaryWidth]"
"\n\t\t: [-setFreeBoundaryColor {ColorName | R G B}] [-unsetFreeBoundaryColor]" "\n\t\t: [-setFreeBoundaryColor {ColorName | R G B}] [-unsetFreeBoundaryColor]"
"\n\t\t: [-subshapes subname1 [subname2 [...]]]" "\n\t\t: [-subshapes subname1 [subname2 [...]]]"
"\n\t\t: [-setSensitivity {selection_mode} {value}]"
"\n\t\t: Manage presentation properties of all, selected or named objects." "\n\t\t: Manage presentation properties of all, selected or named objects."
"\n\t\t: When -subshapes is specified than following properties will be" "\n\t\t: When -subshapes is specified than following properties will be"
"\n\t\t: assigned to specified sub-shapes." "\n\t\t: assigned to specified sub-shapes."

View File

@@ -101,6 +101,17 @@ is
---C++: inline ---C++: inline
---Purpose: Returns the Z coordinate ---Purpose: Returns the Z coordinate
Ptr (me) returns Real
--- Purpose : Returns a const ptr to coordinates location.
-- Is useful for algorithms, but DOES NOT PERFORM ANY CHECKS!
---C++: return const *
is static;
Ptr (me : in out) returns Real;
--- Purpose : Returns a ptr to coordinates location.
-- Is useful for algorithms, but DOES NOT PERFORM ANY CHECKS!
---C++: return *
Modulus (me) returns Real is static; Modulus (me) returns Real is static;
--- Purpose : computes Sqrt (X*X + Y*Y + Z*Z) where X, Y and Z are the three coordinates of this XYZ object. --- Purpose : computes Sqrt (X*X + Y*Y + Z*Z) where X, Y and Z are the three coordinates of this XYZ object.
---C++: inline ---C++: inline

View File

@@ -304,8 +304,6 @@ inline gp_XYZ operator* (const Standard_Real Scalar, const gp_XYZ& Coord1) {
return Coord1.Multiplied (Scalar); return Coord1.Multiplied (Scalar);
} }
inline const Standard_Real* gp_XYZ::Ptr() const { return (&x); }
inline Standard_Real* gp_XYZ::Ptr() { return (&x); }

View File

@@ -0,0 +1,34 @@
puts "========"
puts "OCC26305"
puts "========"
puts ""
###################################################
# BRepFeat_MakePrism returns inconsistent results
###################################################
circle aCircle -9 -9 0 0 0 1 1 0 0 10
mkedge anEdge aCircle
wire aWire anEdge
mkplane aCircle aWire 0
plane aFromPlane 0 0 -10 0 0 1 1 0 0
mkface aFromPlane aFromPlane
plane aToPlane 0 0 10 0 0 1 1 0 0
mkface aToPlane aToPlane
featprism aCircle aCircle aCircle 0 0 1 2 1
featperform prism aResult aFromPlane aToPlane
checkshape aResult
vinit
vdisplay aResult
vsetdispmode aResult 1
vfit
set bug_info [vreadpixel 300 340 name]
if {$bug_info == "BLACK 0"} {
puts "ERROR: OCC26305 is reproduced. Prism is incorrect."
}
set only_screen 1

View File

@@ -0,0 +1,34 @@
puts "========"
puts "OCC26305"
puts "========"
puts ""
###################################################
# BRepFeat_MakePrism returns inconsistent results
###################################################
circle aCircle -10 -10 0 0 0 1 1 0 0 10
mkedge anEdge aCircle
wire aWire anEdge
mkplane aCircle aWire 0
plane aFromPlane 0 0 -10 0 0 1 1 0 0
mkface aFromPlane aFromPlane
plane aToPlane 0 0 10 0 0 1 1 0 0
mkface aToPlane aToPlane
featprism aCircle aCircle aCircle 0 0 1 2 1
featperform prism aResult aFromPlane aToPlane
checkshape aResult
vinit
vdisplay aResult
vsetdispmode aResult 1
vfit
set bug_info [vreadpixel 300 340 name]
if {$bug_info == "BLACK 0"} {
puts "ERROR: OCC26305 is reproduced. Prism is incorrect."
}
set only_screen 1

View File

@@ -0,0 +1,34 @@
puts "========"
puts "OCC26305"
puts "========"
puts ""
###################################################
# BRepFeat_MakePrism returns inconsistent results
###################################################
circle aCircle 0 0 0 0 0 1 1 0 0 10
mkedge anEdge aCircle
wire aWire anEdge
mkplane aCircle aWire 0
plane aFromPlane 0 0 10 0 0 1 1 0 0
mkface aFromPlane aFromPlane
plane aToPlane 0 0 20 0 0 1 1 0 0
mkface aToPlane aToPlane
featprism aCircle aCircle aCircle 0 0 1 2 1
featperform prism aResult aToPlane aFromPlane
checkshape aResult
vinit
vdisplay aResult
vsetdispmode aResult 1
vfit
set bug_info [vreadpixel 300 300 name]
if {$bug_info == "BLACK 0"} {
puts "ERROR: OCC26305 is reproduced. Prism is incorrect."
}
set only_screen 1

View File

@@ -0,0 +1,29 @@
puts "========"
puts "OCC26315"
puts "========"
puts ""
#######################################################
# BRepFeat_MakeRevol fails to create revol from shape
#######################################################
circle aCircle 0 0 0 0 0 1 1 0 0 10
mkedge anEdge aCircle
wire aWire anEdge
mkplane aCircle aWire 0
plane aFromPlane 0 0 -10 0 0 1 1 0 0
mkface aFromPlane aFromPlane
plane aToPlane 0 0 10 0 0 1 1 0 0
mkface aToPlane aToPlane
featrevol aCircle aCircle aCircle 20 0 0 0 1 0 2 1
featperform revol aResult aFromPlane aToPlane
checkshape aResult
vinit
vdisplay aResult
vsetdispmode aResult 1
vfit
set only_screen 1

View File

@@ -0,0 +1,11 @@
puts "================"
puts "OCC26553"
puts "================"
puts ""
#######################################################################
# Out of range exception in BRepFill_Pipe::FindEdge
#######################################################################
pload QAcommands
OCC26553 [locate_data_file bug26553_wire.brep]

53
tests/bugs/vis/bug26462_1 Normal file
View File

@@ -0,0 +1,53 @@
puts "============"
puts "CR26462"
puts "============"
puts ""
##########################################################################################
puts "Visualization - selection does not adapt to line width change"
##########################################################################################
pload VISUALIZATION MODELING
vinit
box b1 10 10 10
box b2 10 10 10
vdisplay b1 b2
vsetlocation b1 10 10 0
vfit
vaspects b1 b2 -setWidth 3
vselmode 2 1
# try to select b1 and b2
vselect 305 322 1
vselect 103 322 1
# check that both boxes were not selected with default tolerance value
set aNbSelected [vnbselected]
if {$aNbSelected != "0"} {
puts "ERROR: no boxes must be selected!"
}
# increase tolerance for b1
vaspects b1 -setSensitivity 2 4
# enable selection with local context opened
vselmode 2 1
# select edge of b1
vselect 305 322
# check that b1's edge was selected
set aNbSelected [vnbselected]
if {$aNbSelected != "1"} {
puts "ERROR: b1 was not selected"
}
# try to select b2
vselect 103 322 1
# check that increase of tolerance for b1 doesn't influence
# on b2
set aNbSelected [vnbselected]
if {$aNbSelected != "1"} {
puts "ERROR: b2 is selected after b1's tolerance increased"
}
set only_screen 1

15
tests/bugs/vis/bug26462_2 Normal file
View File

@@ -0,0 +1,15 @@
puts "============"
puts "CR26462"
puts "============"
puts ""
##########################################################################################
puts "Visualization - selection does not adapt to line width change"
##########################################################################################
pload VISUALIZATION QAcommands
vinit
OCC26462
set only_screen 1