-// Copyright: Matra-Datavision 1995
-// File: Select3D_SensitiveFace.cxx
-// Created: Mon Mar 27 10:15:15 1995
-// Author: Robert COUBLANC
-// <rob>
-//Modif on jun-24-97 : introduction de CSLib_Class2d de LBR
-// pour teste si on est dedans ou dehors...
-//Modif on jul-21-97 : changement en harray1 pour eventuelles connexions ...
+// Created on: 1995-03-27
+// Created by: Robert COUBLANC
+// Copyright (c) 1995-1999 Matra Datavision
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <Select3D_SensitiveFace.hxx>
+
+#include <Select3D_SensitivePoly.hxx>
+#include <Select3D_InteriorSensitivePointSet.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveFace,Select3D_SensitiveEntity)
-#include <Select3D_SensitiveFace.ixx>
-#include <Select3D_Projector.hxx>
-#include <SelectBasics_BasicTool.hxx>
-#include <gp_Pnt2d.hxx>
-#include <gp_Pnt.hxx>
-#include <Precision.hxx>
-#include <ElCLib.hxx>
-
-#include <CSLib_Class2d.hxx>
-
-
-#define AutoInterMask 0x01
-#define AutoComputeMask 0x02
-// Standard_True if the flag is one
-#define AutoInterFlag(aflag) ( aflag & AutoInterMask )
-#define AutoComputeFlag(aflag) ( aflag & AutoComputeMask )
-// set the flag to one
-#define SetAutoInterFlag(aflag) ( aflag = aflag & AutoInterMask)
-#define SetAutoComputeFlag(aflag) ( aflag = aflag & AutoComputeMask)
-// Initialize flags
-#define AutoInitFlags(aflag) (aflag = 0)
-
-//==================================================
-// Function: faire disparaitre ce constructeur a la prochaine version...
-// Purpose : simplement garde pour ne pas perturber la version update
//==================================================
-
-Select3D_SensitiveFace::
-Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
- const TColgp_Array1OfPnt& ThePoints,
- const Select3D_TypeOfSensitivity aType):
-Select3D_SensitivePoly(OwnerId, ThePoints),
-mytype (aType),
-myDetectedIndex(-1)
-{
- AutoInitFlags(myautointer);
-}
-
-//==================================================
-// Function:
-// Purpose :
+// Function: Hide this constructor to the next version...
+// Purpose : simply avoid interfering with the version update
//==================================================
-
-Select3D_SensitiveFace::
-Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
- const Handle(TColgp_HArray1OfPnt)& ThePoints,
- const Select3D_TypeOfSensitivity aType):
-Select3D_SensitivePoly(OwnerId, ThePoints),
-mytype (aType),
-myDetectedIndex(-1)
+Select3D_SensitiveFace::Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+ const TColgp_Array1OfPnt& thePoints,
+ const Select3D_TypeOfSensitivity theType)
+: Select3D_SensitiveEntity (theOwnerId),
+ mySensType (theType)
{
- AutoInitFlags(myautointer);
+ if (mySensType == Select3D_TOS_INTERIOR)
+ {
+ myFacePoints = new Select3D_InteriorSensitivePointSet (theOwnerId, thePoints);
+ }
+ else
+ {
+ myFacePoints = new Select3D_SensitivePoly (theOwnerId, thePoints, Standard_True);
+ }
}
//==================================================
-// Function:
+// Function: Creation
// Purpose :
//==================================================
-
-Standard_Boolean Select3D_SensitiveFace::
-Matches(const Standard_Real X,
- const Standard_Real Y,
- const Standard_Real aTol,
- Standard_Real& DMin)
+Select3D_SensitiveFace::Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
+ const Handle(TColgp_HArray1OfPnt)& thePoints,
+ const Select3D_TypeOfSensitivity theType)
+: Select3D_SensitiveEntity (theOwnerId),
+ mySensType (theType)
{
-#ifndef DEB
- Standard_Real DMin2 = 0.;
-#else
- Standard_Real DMin2;
-#endif
- Standard_Real Xmin,Ymin,Xmax,Ymax;
- if(!Bnd_Box2d(mybox2d).IsVoid()){
- Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax);
- DMin2 = gp_XY(Xmax-Xmin,Ymax-Ymin).SquareModulus();
- }
- // calcul d'un critere de distance mini...
- // au depart Dmin = taille de la boite englobante 2D,
- // ensuite distance mini du polyedre ou du cdg...
-
- Standard_Real aTol2 = aTol*aTol;
- gp_XY CDG(0.,0.);
-// for(Standard_Integer I=1;I<=Nbp-1;I++){
- Standard_Integer I;
- for(I=1;I<mynbpoints-1;I++){
- CDG+=((Select3D_Pnt2d*)mypolyg2d)[I-1];
- }
-
- if(mynbpoints>1){
- CDG/= (mynbpoints-1);
- }
- DMin2=Min(DMin2,gp_XY(CDG.X()-X,CDG.Y()-Y).SquareModulus());
- DMin = Sqrt(DMin2);
-
-
- Standard_Boolean isplane2d(Standard_True);
-
- for( I=1;I<mynbpoints-1;I++){
- gp_XY V1(((Select3D_Pnt2d*)mypolyg2d)[I]),V(X,Y);
- V1-=((Select3D_Pnt2d*)mypolyg2d)[I-1];
- V-=((Select3D_Pnt2d*)mypolyg2d)[I-1];
- Standard_Real Vector = V1^V;
- Standard_Real V1V1 = V1.SquareModulus();
- DMin2 =
- (V1V1 <=aTol2) ?
- Min(DMin2,V.SquareModulus()): // si le segment est trop petit...
- Min(DMin2,Vector*Vector/V1V1);
- //cdg ...
- gp_XY PlaneTest(CDG);PlaneTest-=((Select3D_Pnt2d*)mypolyg2d)[I-1];
- Standard_Real valtst = PlaneTest^V1;
- if(isplane2d && Abs(valtst)>aTol) isplane2d=Standard_False;
+ if (mySensType == Select3D_TOS_INTERIOR)
+ {
+ myFacePoints = new Select3D_InteriorSensitivePointSet (theOwnerId, thePoints->Array1());
}
- if (isplane2d)
+ else
{
- return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
+ myFacePoints = new Select3D_SensitivePoly (theOwnerId, thePoints->Array1(), Standard_True);
}
- //detection d'une auto - intersection dans le polygon 2D; si oui on sort
-// if (!AutoComputeFlag(myautointer)) {
-// if(mypolyg2d.Length()>4) {
-// if (SelectBasics_BasicTool::AutoInter(mypolyg2d)) {
-// SetAutoInterFlag(myautointer);
-// }
-// }
-// SetAutoComputeFlag(myautointer);
-// }
-// if (AutoInterFlag(myautointer)) return Standard_True;
-// //
+}
- //sinon on regarde si le point est dans la face...
- TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mynbpoints);
- Points2D(aArrayOf2dPnt);
- CSLib_Class2d TheInOutTool(aArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
- Standard_Integer TheStat = TheInOutTool.SiDans(gp_Pnt2d(X,Y));
-
- Standard_Boolean res(Standard_False);
- switch(TheStat){
- case 0:
- res = Standard_True;
- case 1:
- {
- if(mytype!=Select3D_TOS_BOUNDARY)
- res = Standard_True;
- }
+//=======================================================================
+// function : GetPoints
+// purpose : Initializes the given array theHArrayOfPnt by 3d
+// coordinates of vertices of the face
+//=======================================================================
+void Select3D_SensitiveFace::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt)
+{
+ if (myFacePoints->IsKind(STANDARD_TYPE(Select3D_SensitivePoly)))
+ {
+ Handle(Select3D_SensitivePoly)::DownCast (myFacePoints)->Points3D (theHArrayOfPnt);
}
- if (res)
+ else
{
- return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
+ Handle(Select3D_InteriorSensitivePointSet)::DownCast (myFacePoints)->GetPoints (theHArrayOfPnt);
}
- return Standard_False;
+
}
//=======================================================================
-//function : Matches
-//purpose :
+// function : BVH
+// purpose : Builds BVH tree for the face
//=======================================================================
+void Select3D_SensitiveFace::BVH()
+{
+ myFacePoints->BVH();
+}
-Standard_Boolean Select3D_SensitiveFace::
-Matches (const Standard_Real XMin,
- const Standard_Real YMin,
- const Standard_Real XMax,
- const Standard_Real YMax,
- const Standard_Real aTol)
-{
- Bnd_Box2d BoundBox;
- BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
-
- for(Standard_Integer j=1;j<=mynbpoints-1;j++){
- if(BoundBox.IsOut(((Select3D_Pnt2d*)mypolyg2d)[j-1])) return Standard_False;
- }
- return Standard_True;
+//=======================================================================
+// function : Matches
+// purpose : Checks whether the face overlaps current selecting volume
+//=======================================================================
+Standard_Boolean Select3D_SensitiveFace::Matches (SelectBasics_SelectingVolumeManager& theMgr,
+ SelectBasics_PickResult& thePickResult)
+{
+ return myFacePoints->Matches (theMgr, thePickResult);
}
//=======================================================================
-//function : Matches
-//purpose :
+//function : GetConnected
+//purpose :
//=======================================================================
+Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected()
+{
+ // Create a copy of this
+ Handle(TColgp_HArray1OfPnt) aPoints;
+ GetPoints (aPoints);
-Standard_Boolean Select3D_SensitiveFace::
-Matches (const TColgp_Array1OfPnt2d& aPoly,
- const Bnd_Box2d& aBox,
- const Standard_Real aTol)
-{
- Standard_Real Umin,Vmin,Umax,Vmax;
- aBox.Get(Umin,Vmin,Umax,Vmax);
- Standard_Real Tolu,Tolv;
- Tolu = 1e-7;
- Tolv = 1e-7;
- CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
+ Handle(Select3D_SensitiveEntity) aNewEntity =
+ new Select3D_SensitiveFace (myOwnerId, aPoints, mySensType);
- for(Standard_Integer j=1;j<=mynbpoints;j++){
- Standard_Integer RES = aClassifier2d.SiDans(((Select3D_Pnt2d*)mypolyg2d)[j-1]);
- if(RES!=1) return Standard_False;
- }
- return Standard_True;
+ return aNewEntity;
}
+//=======================================================================
+// function : BoundingBox
+// purpose : Returns bounding box of the face. If location transformation
+// is set, it will be applied
+//=======================================================================
+Select3D_BndBox3d Select3D_SensitiveFace::BoundingBox()
+{
+ return myFacePoints->BoundingBox();
+}
//=======================================================================
-//function : Dump
-//purpose :
+// function : CenterOfGeometry
+// purpose : Returns center of the face. If location transformation
+// is set, it will be applied
//=======================================================================
-void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
+gp_Pnt Select3D_SensitiveFace::CenterOfGeometry() const
{
- S<<"\tSensitiveFace 3D :"<<endl;;
- if(HasLocation())
- S<<"\t\tExisting Location"<<endl;
-
- if(mytype==Select3D_TOS_BOUNDARY)
- S<<"\t\tSelection Of Bounding Polyline Only"<<endl;
-
- if(FullDump){
- S<<"\t\tNumber Of Points :"<<mynbpoints<<endl;
-
-// S<<"\t\t\tOwner:"<<myOwnerId<<endl;
- Select3D_SensitiveEntity::DumpBox(S,mybox2d);
- }
+ return myFacePoints->CenterOfGeometry();
}
//=======================================================================
-//function : ComputeDepth
-//purpose :
+// function : NbSubElements
+// purpose : Returns the amount of sub-entities (points or planar convex
+// polygons)
//=======================================================================
-Standard_Real Select3D_SensitiveFace::ComputeDepth(const gp_Lin& EyeLine) const
+Standard_Integer Select3D_SensitiveFace::NbSubElements()
{
- Standard_Real aDepth = Precision::Infinite();
- Standard_Real aDepthMin = !mylastprj.IsNull() ? mylastprj->DepthMin() : -Precision::Infinite();
- Standard_Real aDepthMax = !mylastprj.IsNull() ? mylastprj->DepthMax() : Precision::Infinite();
- Standard_Real aDepthTest;
- for (Standard_Integer i = 0; i < mynbpoints - 1; i++)
- {
- aDepthTest = ElCLib::Parameter (EyeLine, ((Select3D_Pnt* )mypolyg3d)[i]);
- if (aDepthTest < aDepth && (aDepthTest > aDepthMin) && (aDepthTest < aDepthMax))
- {
- aDepth = aDepthTest;
- }
- }
- return aDepth;
+ return myFacePoints->NbSubElements();
}