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

0024623: Visualization - improve selection mechanism

Redesign of selection mechanism:
- implemented 3-level BVH tree for selection;
- selection now calculates in 3D space;
- intersection tests were moved to SelectMgr_BaseFrustum descendants;
- removed .cdl files in Select3D and .cdl related to selection in MeshVS;
- SelectMgr_ViewerSelectors are now shared between local and global contexts;
- transformations of sensitive entities are now stored in SelectMgr_SelectableObject only. Sensitive entities are independent from transformations, it is applied to SelectMgr_SelectingVolumeManager instance only;
- connected and multiple connected interactive objects are now represented by their child objects only for SelectMgr_SelectionManager;
- if interactive object has child objects, they will be stored as separate objects in SelectMgr_SelectionManager now.
- test cases bugs/vis/bug24623_1, bug24623_2, bug24623_3, bug24623_4 to test performance and memory issues.
This commit is contained in:
vpa
2015-04-06 12:31:00 +03:00
committed by bugmaster
parent 7a91ad6e81
commit f751596e46
269 changed files with 12626 additions and 11723 deletions

View File

@@ -1,5 +1,43 @@
Select3D_Pnt.hxx
Select3D_Pnt2d.hxx
Select3D_Box2d.hxx
Select3D_Macro.hxx
Select3D_PointData.hxx
Select3D_PointData.hxx
Select3D_BoundarySensitivePointSet.hxx
Select3D_BoundarySensitivePointSet.cxx
Select3D_BndBox3d.hxx
Select3D_BVHPrimitiveContent.hxx
Select3D_BVHPrimitiveContent.cxx
Select3D_InteriorSensitivePointSet.hxx
Select3D_InteriorSensitivePointSet.cxx
Select3D_ISensitivePointSet.hxx
Select3D_EntitySequence.hxx
Select3D_SensitiveBox.hxx
Select3D_SensitiveBox.cxx
Select3D_SensitiveCircle.hxx
Select3D_SensitiveCircle.cxx
Select3D_SensitiveCurve.hxx
Select3D_SensitiveCurve.cxx
Select3D_SensitiveEntity.hxx
Select3D_SensitiveEntity.cxx
Select3D_SensitiveFace.hxx
Select3D_SensitiveFace.cxx
Select3D_SensitiveGroup.hxx
Select3D_SensitiveGroup.cxx
Select3D_SensitiveGroup.lxx
Select3D_SensitivePoint.hxx
Select3D_SensitivePoint.cxx
Select3D_SensitivePoly.hxx
Select3D_SensitivePoly.cxx
Select3D_SensitivePoly.lxx
Select3D_SensitiveSegment.hxx
Select3D_SensitiveSegment.cxx
Select3D_SensitiveSegment.lxx
Select3D_SensitiveSet.hxx
Select3D_SensitiveSet.cxx
Select3D_SensitiveTriangle.hxx
Select3D_SensitiveTriangle.cxx
Select3D_SensitiveTriangulation.hxx
Select3D_SensitiveTriangulation.cxx
Select3D_SensitiveTriangulation.lxx
Select3D_SensitiveWire.hxx
Select3D_SensitiveWire.cxx
Select3D_TypeOfSensitivity.hxx

View File

@@ -37,60 +37,34 @@ uses
TopLoc,
Geom,
SelectBasics,
SelectMgr,
V3d,
Graphic3d
is
---Category: sensitive entities
enumeration TypeOfSensitivity is TOS_INTERIOR,TOS_BOUNDARY
end TypeOfSensitivity;
---Purpose: Provides values for type of sensitivity in 3D.
-- These are used to specify whether it is the interior,
-- the boundary, or the exterior of a 3D sensitive entity which is sensitive.
deferred class SensitiveEntity;
deferred class SensitivePoly;
class SensitivePoint;
class SensitiveSegment;
class SensitiveCircle;
class SensitiveCurve;
class SensitiveTriangle;
class SensitiveTriangulation;
class SensitiveFace;
class SensitiveBox;
class SensitiveWire;
class SensitiveGroup;
class SensitiveEntitySequence instantiates Sequence from TCollection
(SensitiveEntity from Select3D);
---Category: selectors/projectors
class Projector;
class ListOfSensitiveTriangle instantiates List from TCollection
(SensitiveTriangle from Select3D);
class ListOfSensitive instantiates List from TCollection
(SensitiveEntity from Select3D);
imported BndBox3d;
imported BoundarySensitivePointSet;
imported BVHPrimitiveContent;
imported InteriorSensitivePointSet;
imported ISensitivePointSet;
imported EntitySequence;
imported Pnt;
imported Pnt2d;
imported Box2d;
imported PointData;
imported SelectingVolumeManager;
imported SensitiveBox;
imported SensitiveCircle;
imported SensitiveCurve;
imported transient class SensitiveEntity;
imported SensitiveFace;
imported SensitiveGroup;
imported SensitivePoint;
imported SensitivePoly;
imported SensitiveSegment;
imported SensitiveSet;
imported SensitiveTriangle;
imported SensitiveTriangulation;
imported SensitiveWire;
imported TypeOfSensitivity;
end Select3D;

View File

@@ -0,0 +1,80 @@
// Created on: 2014-05-30
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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 <BVH_LinearBuilder.hxx>
#include <Select3D_SensitiveSet.hxx>
#include <Select3D_BVHPrimitiveContent.hxx>
//=======================================================================
// function : Select3D_BVHPrimitiveContent
// purpose : Initializes new linear BVH builder for the set of sensitives
// theSensitiveSet given
//=======================================================================
Select3D_BVHPrimitiveContent::Select3D_BVHPrimitiveContent (const Handle(Select3D_SensitiveSet)& theSensitiveSet)
{
mySensitiveSet = theSensitiveSet;
myBuilder = new BVH_LinearBuilder<Standard_Real, 3> (8, 32);
MarkDirty();
}
//=======================================================================
// function : Size
// purpose : Returns the length of set of sensitives
//=======================================================================
Standard_Integer Select3D_BVHPrimitiveContent::Size() const
{
return mySensitiveSet->Size();
}
//=======================================================================
// function : Box
// purpose : Returns bounding box of sensitive with index theIdx
//=======================================================================
Select3D_BndBox3d Select3D_BVHPrimitiveContent::Box (const Standard_Integer theIdx) const
{
return mySensitiveSet->Box (theIdx);
}
//=======================================================================
// function : Center
// purpose : Returns center of sensitive with index theIdx in the set
// along the given axis theAxis
//=======================================================================
Standard_Real Select3D_BVHPrimitiveContent::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
{
return mySensitiveSet->Center (theIdx, theAxis);
}
//=======================================================================
// function : Swap
// purpose : Swaps items with indexes theIdx1 and theIdx2 in the set
//=======================================================================
void Select3D_BVHPrimitiveContent::Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2)
{
mySensitiveSet->Swap (theIdx1, theIdx2);
}
//=======================================================================
// function : GetBVH
// purpose : Returns the tree built for set of sensitives
//=======================================================================
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& Select3D_BVHPrimitiveContent::GetBVH()
{
return BVH();
}

View File

@@ -0,0 +1,57 @@
// Created on: 2014-05-30
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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.
#ifndef _Select3D_BVHPrimitiveContent_Header
#define _Select3D_BVHPrimitiveContent_Header
#include <BVH_PrimitiveSet.hxx>
class Select3D_SensitiveSet;
//! The purpose of this class is to provide a link between BVH_PrimitiveSet
//! and Select3D_SensitiveSet instance to build BVH tree for set of sensitives
class Select3D_BVHPrimitiveContent : public BVH_PrimitiveSet<Standard_Real, 3>
{
public:
//! Initializes new linear BVH builder for the set of sensitives
//! theSensitiveSet given
Select3D_BVHPrimitiveContent (const Handle(Select3D_SensitiveSet)& theSensitiveSet);
~Select3D_BVHPrimitiveContent() {};
//! Returns the length of set of sensitives
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns bounding box of sensitive with index theIdx
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
//! Returns center of sensitive with index theIdx in the set along the
//! given axis theAxis
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIdx1 and theIdx2 in the set
Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2) Standard_OVERRIDE;
//! Returns the tree built for set of sensitives
Standard_EXPORT const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& GetBVH();
protected:
Handle(Select3D_SensitiveSet) mySensitiveSet; //!< Set of sensitive entities
};
#endif // _Select3D_BVHPrimitiveContent_Header

View File

@@ -1,5 +1,6 @@
// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
// Created on: 2014-29-05
// Created by: Varvara POSKONINA
// Copyright (c) 2005-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@@ -12,6 +13,17 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
inline Standard_Boolean Select3D_SensitiveEntity::NeedsConversion() const
{return Standard_True;}
#ifndef _Select3D_BndBox3d_Header
#define _Select3D_BndBox3d_Header
#include <BVH_Box.hxx>
#include <BVH_Types.hxx>
#include <gp_Trsf.hxx>
#include <NCollection_Vector.hxx>
typedef BVH_Box<Standard_Real, 3> Select3D_BndBox3d;
typedef NCollection_Vec3<Standard_Real> Select3D_Vec3;
#endif // _Select3D_BndBox3d_Header

View File

@@ -0,0 +1,95 @@
// Created on: 2014-11-10
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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_BoundarySensitivePointSet.hxx>
//=======================================================================
// function : Select3D_BoundarySensitivePointSet
// purpose : Creates new instance of Select3D_SensitivePoly with BVH tree
// required and initializes it with the given array of points
//=======================================================================
Select3D_BoundarySensitivePointSet::Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId,
const TColgp_Array1OfPnt& ThePoints)
: Select3D_SensitivePoly (OwnerId, ThePoints, Standard_True)
{}
//=======================================================================
// function : Select3D_BoundarySensitivePointSet
// purpose : Creates new instance of Select3D_SensitivePoly with BVH tree
// required and initializes it with the given array of points
//=======================================================================
Select3D_BoundarySensitivePointSet::Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(TColgp_HArray1OfPnt)& ThePoints)
: Select3D_SensitivePoly (OwnerId, ThePoints, Standard_True)
{}
//=======================================================================
// function : Matches
// purpose : Checks whether the point set overlaps current selecting
// volume
//=======================================================================
Standard_Boolean Select3D_BoundarySensitivePointSet::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
return Select3D_SensitivePoly::Matches (theMgr, thePickResult);
}
//=======================================================================
// function : GetPoints
// purpose : Initializes the given array theHArrayOfPnt by 3d
// coordinates of vertices of the point set
//=======================================================================
void Select3D_BoundarySensitivePointSet::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt)
{
Points3D (theHArrayOfPnt);
}
//=======================================================================
// function : BoundingBox
// purpose : Returns bounding box of the point set. If location transformation
// is set, it will be applied
//=======================================================================
Select3D_BndBox3d Select3D_BoundarySensitivePointSet::BoundingBox()
{
return Select3D_SensitivePoly::BoundingBox();
}
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of the point set. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_BoundarySensitivePointSet::CenterOfGeometry() const
{
return Select3D_SensitivePoly::CenterOfGeometry();
}
//=======================================================================
// function : BVH
// purpose : Builds BVH tree for the point set
//=======================================================================
void Select3D_BoundarySensitivePointSet::BVH()
{
Select3D_SensitivePoly::BVH();
}
//=======================================================================
// function : NbSubElements
// purpose : Returns the amount of points in set
//=======================================================================
Standard_Integer Select3D_BoundarySensitivePointSet::NbSubElements()
{
return Select3D_SensitivePoly::NbSubElements();
}

View File

@@ -0,0 +1,67 @@
// Created on: 2014-08-15
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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.
#ifndef _Select3D_BoundarySensitivePointSet_HeaderFile
#define _Select3D_BoundarySensitivePointSet_HeaderFile
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Handle_TColgp_HArray1OfPnt.hxx>
#include <Select3D_ISensitivePointSet.hxx>
#include <Select3D_SensitivePoly.hxx>
class SelectBasics_EntityOwner;
class TColgp_Array1OfPnt;
class TColgp_HArray1OfPnt;
//! This class handles the selection of arbitrary point set with boundary type of sensitivity.
class Select3D_BoundarySensitivePointSet : public Select3D_ISensitivePointSet, public Select3D_SensitivePoly
{
public:
//! Creates new instance of Select3D_SensitivePoly with BVH tree
//! required and initializes it with the given array of points
Standard_EXPORT Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId,
const TColgp_Array1OfPnt& ThePoints);
//! Creates new instance of Select3D_SensitivePoly with BVH tree
//! required and initializes it with the given array of points
Standard_EXPORT Select3D_BoundarySensitivePointSet (const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(TColgp_HArray1OfPnt)& ThePoints);
//! Checks whether the point set overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Initializes the given array theHArrayOfPnt by 3d coordinates
//! of vertices of the point set
Standard_EXPORT virtual void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) Standard_OVERRIDE;
//! Returns bounding box of the point set. If there is a
//! location transformation set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of the point set. If there is a
//! location transformation set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Builds BVH tree for the point set
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
//! Returns the amount of points in set
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
};
#endif // _Select3D_BoundarySensitivePointSet_HeaderFile

View File

@@ -1,95 +0,0 @@
// 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.
#ifndef _Select3D_Box2d_HeaderFile
#define _Select3D_Box2d_HeaderFile
#include<Bnd_Box2d.hxx>
#include<Standard_ShortReal.hxx>
#include<Select3D_Macro.hxx>
struct Select3D_Box2d
{
Standard_ShortReal xmin, ymin, xmax, ymax;
Select3D_Box2d()
: xmin( ShortRealLast() ),
ymin( ShortRealLast() ),
xmax( ShortRealFirst() ),
ymax( ShortRealFirst() )
{
}
Select3D_Box2d(const Bnd_Box2d& theBox)
{
SetField(theBox);
}
inline operator Bnd_Box2d() const
{
Bnd_Box2d aBox;
aBox.SetVoid();
if( !IsVoid() )
aBox.Update(xmin, ymin, xmax, ymax);
return aBox;
}
inline Select3D_Box2d operator = ( const Bnd_Box2d& theBox)
{
SetField(theBox);
return *this;
}
inline void Update(const gp_Pnt2d& thePnt)
{
Bnd_Box2d aBox;
aBox.Set(thePnt);
if( !IsVoid() )
aBox.Update(xmin, ymin, xmax, ymax);
SetField(aBox);
}
inline void SetVoid()
{
xmin = ymin = ShortRealLast();
xmax = ymax = ShortRealFirst();
}
inline Standard_Boolean IsVoid() const
{
return ( xmin == ShortRealLast() && ymin == ShortRealLast() && xmax == ShortRealFirst() && ymax == ShortRealFirst() );
}
private:
inline void SetField(const Bnd_Box2d& theBox)
{
if( theBox.IsVoid() )
SetVoid();
else {
Standard_Real x, y, x1, y1;
theBox.Get(x, y, x1, y1);
xmin = DToF(x);
ymin = DToF(y);
xmax = DToF(x1);
ymax = DToF(y1);
}
}
};
#endif

View File

@@ -0,0 +1,11 @@
#ifndef _Select3D_EntitySequence_Header
#define _Select3D_EntitySequence_Header
#include <NCollection_Sequence.hxx>
class Handle(Select3D_SensitiveEntity);
typedef NCollection_Sequence<Handle(Select3D_SensitiveEntity)> Select3D_EntitySequence;
typedef NCollection_Sequence<Handle(Select3D_SensitiveEntity)>::Iterator Select3D_EntitySequenceIter;
#endif // _Select3D_EntitySequence_Header

View File

@@ -0,0 +1,70 @@
// Created on: 2014-08-15
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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.
#ifndef _Select3D_ISensitivePointSet_HeaderFile
#define _Select3D_ISensitivePointSet_HeaderFile
#include <Standard.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_OStream.hxx>
#include <Standard_Real.hxx>
#include <Select3D_BndBox3d.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <SelectBasics_EntityOwner.hxx>
#include <SelectBasics_PickResult.hxx>
#include <SelectBasics_SelectingVolumeManager.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Handle_TColgp_HArray1OfPnt.hxx>
class gp_Pnt;
class Standard_ConstructionError;
class Standard_OutOfRange;
class TColgp_Array1OfPnt;
class TColgp_HArray1OfPnt;
class TColgp_Array1OfPnt2d;
class TopLoc_Location;
//! Interface class to unify the work with both internal and boundary
//! sensitive sets of points.
class Select3D_ISensitivePointSet
{
public:
//! Checks whether the point set overlaps current selecting volume
virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) = 0;
//! Initializes the given array theHArrayOfPnt by 3d coordinates
//! of vertices of the point set
virtual void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) = 0;
//! Returns bounding box of the point set. If location
//! transformation is set, it will be applied
virtual Select3D_BndBox3d BoundingBox() = 0;
//! Returns center of the point set. If location
//! transformation is set, it will be applied
virtual gp_Pnt CenterOfGeometry() const = 0;
//! Builds BVH tree for the point set
virtual void BVH() = 0;
//! Returns the amount of points in set
virtual Standard_Integer NbSubElements() = 0;
};
#endif // _Select3D_ISensitivePointSet_HeaderFile

View File

@@ -0,0 +1,418 @@
// Created on: 2014-08-15
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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 <gp_Pnt.hxx>
#include <gp_XYZ.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <Select3D_InteriorSensitivePointSet.hxx>
// Internal class for creation of planar polygons
class Select3D_Plane
{
public:
Select3D_Plane()
: myPlane (0.0),
myIsInitialized (Standard_False)
{}
Standard_Boolean Contains (const gp_Pnt& thePnt) const
{
if (!myIsInitialized)
return Standard_False;
Standard_Real aRes = myPlane.x() * thePnt.X() +
myPlane.y() * thePnt.Y() +
myPlane.z() * thePnt.Z() +
myPlane.w();
if (aRes < Precision::Confusion())
return Standard_True;
return Standard_False;
}
void MakePlane (const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
const gp_Pnt& thePnt3)
{
const gp_XYZ& aVec1 = thePnt2.XYZ() - thePnt1.XYZ();
const gp_XYZ& aVec2 = thePnt3.XYZ() - thePnt1.XYZ();
const gp_XYZ& aDir = aVec1.Crossed (aVec2);
Standard_Real aD = aDir.Dot (thePnt1.XYZ().Reversed());
myPlane = NCollection_Vec4<Standard_Real> (aDir.X(), aDir.Y(), aDir.Z(), aD);
myIsInitialized = Standard_True;
}
void Invalidate()
{
myIsInitialized = Standard_False;
}
Standard_Boolean IsValid() const
{
return myIsInitialized;
}
private:
NCollection_Vec4<Standard_Real> myPlane;
Standard_Boolean myIsInitialized;
};
// =======================================================================
// function : Select3D_InteriorSensitivePointSet
// purpose : Splits the given point set thePoints onto planar convex
// polygons
// =======================================================================
Select3D_InteriorSensitivePointSet::Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints)
: Select3D_SensitiveSet (theOwnerId)
{
Select3D_Plane aPlane;
Standard_Integer aStartIdx = 1, anEndIdx = 0;
Standard_Integer aLowerIdx = thePoints.Lower();
Standard_Integer anUpperIdx = thePoints.Upper();
Select3D_BndBox3d aBndBox;
gp_XYZ aPntSum (0.0, 0.0, 0.0);
if (thePoints.Length() > 3)
{
for (Standard_Integer aPntIter = aLowerIdx; aPntIter <= anUpperIdx; ++aPntIter)
{
gp_Pnt aPnt1, aPnt2;
const gp_Pnt& aPnt3 = thePoints.Value (aPntIter);
aBndBox.Add (SelectMgr_Vec3 (aPnt3.X(), aPnt3.Y(), aPnt3.Z()));
aPntSum += aPnt3.XYZ();
if (aPntIter - aLowerIdx >= 2)
{
aPnt1 = thePoints.Value (aPntIter - 2);
aPnt2 = thePoints.Value (aPntIter - 1);
}
if (aPntIter - aStartIdx == 2 && !aPlane.IsValid())
{
aPlane.MakePlane (aPnt1, aPnt2, aPnt3);
aStartIdx = aPntIter - 2;
anEndIdx = aPntIter;
}
else if (aPlane.IsValid())
{
const gp_XYZ& aVec1 = aPnt1.XYZ() - aPnt2.XYZ();
const gp_XYZ& aVec2 = aPnt3.XYZ() - aPnt2.XYZ();
Standard_Real anAngle = aVec1.Dot (aVec2);
if (!aPlane.Contains (thePoints.Value (aPntIter)) || anAngle > Precision::Confusion())
{
Standard_Integer anUpperBound = aPntIter - aStartIdx;
Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anUpperBound);
for (Standard_Integer aIdx = aStartIdx; aIdx <= aStartIdx + anUpperBound; ++aIdx)
{
aPointsArray->SetValue (aIdx - aStartIdx, thePoints.Value (aIdx));
}
Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
aPointsArray,
Standard_False);
myPlanarPolygons.Append (aPlanarPolyg);
aStartIdx = aPntIter;
anEndIdx = aPntIter;
aPlane.Invalidate();
}
else
{
if (anEndIdx == anUpperIdx)
{
Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anEndIdx - aStartIdx);
for (Standard_Integer aIdx = aStartIdx; aIdx <= anEndIdx; ++aIdx)
{
aPointsArray->SetValue (aIdx - aStartIdx, thePoints.Value (aIdx));
}
Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
aPointsArray,
Standard_False);
myPlanarPolygons.Append (aPlanarPolyg);
}
anEndIdx++;
}
}
}
}
else
{
Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, 2);
const gp_Pnt& aPnt1 = thePoints.Value (aLowerIdx);
const gp_Pnt& aPnt2 = thePoints.Value (aLowerIdx + 1);
const gp_Pnt& aPnt3 = thePoints.Value (aLowerIdx + 2);
aPointsArray->SetValue (0, aPnt1);
aPointsArray->SetValue (1, aPnt2);
aPointsArray->SetValue (2, aPnt3);
aBndBox.Add (SelectMgr_Vec3 (aPnt1.X(), aPnt1.Y(), aPnt1.Z()));
aBndBox.Add (SelectMgr_Vec3 (aPnt2.X(), aPnt2.Y(), aPnt2.Z()));
aBndBox.Add (SelectMgr_Vec3 (aPnt3.X(), aPnt3.Y(), aPnt3.Z()));
aPntSum += aPnt1.XYZ() + aPnt2.XYZ() + aPnt3.XYZ();
Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
aPointsArray,
Standard_False);
myPlanarPolygons.Append (aPlanarPolyg);
}
myPolygonsIdxs = new TColStd_HArray1OfInteger (0, myPlanarPolygons.Length() - 1);
for (Standard_Integer aIdx = 0; aIdx < myPlanarPolygons.Length(); ++aIdx)
{
myPolygonsIdxs->SetValue (aIdx, aIdx);
}
myCOG = aPntSum / thePoints.Length();
myBndBox = aBndBox;
}
// =======================================================================
// function : Select3D_InteriorSensitivePointSet
// purpose : Splits the given point set thePoints onto planar convex
// polygons
// =======================================================================
Select3D_InteriorSensitivePointSet::Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints)
: Select3D_SensitiveSet (theOwnerId)
{
Select3D_Plane aPlane;
Standard_Integer aLowerIdx = thePoints->Lower();
Standard_Integer anUpperIdx = thePoints->Upper();
Standard_Integer aStartIdx = aLowerIdx, anEndIdx = 0;
Select3D_BndBox3d aBndBox;
gp_XYZ aPntSum (0.0, 0.0, 0.0);
for (Standard_Integer aPntIter = aLowerIdx; aPntIter <= anUpperIdx; ++aPntIter)
{
gp_Pnt aPnt1, aPnt2;
const gp_Pnt& aPnt3 = thePoints->Value (aPntIter);
aPntSum += aPnt3.XYZ();
SelectMgr_Vec3 aCurrPnt (aPnt3.X(), aPnt3.Y(), aPnt3.Z());
aBndBox.Add (aCurrPnt);
if (aPntIter - aLowerIdx >= 2)
{
aPnt1 = thePoints->Value (aPntIter - 2);
aPnt2 = thePoints->Value (aPntIter - 1);
}
if (aPntIter - aStartIdx == 2 && !aPlane.IsValid())
{
aPlane.MakePlane (aPnt1, aPnt2, aPnt3);
aStartIdx = aPntIter - 2;
anEndIdx = aPntIter;
}
else if (aPlane.IsValid())
{
const gp_XYZ& aVec1 = aPnt1.XYZ() - aPnt2.XYZ();
const gp_XYZ& aVec2 = aPnt3.XYZ() - aPnt2.XYZ();
Standard_Real anAngle = aVec1.Dot (aVec2);
if (!aPlane.Contains (thePoints->Value (aPntIter)) || anAngle > Precision::Confusion())
{
Standard_Integer anUpperBound = aPntIter - aStartIdx;
Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anUpperBound);
for (Standard_Integer aIdx = aStartIdx; aIdx <= aStartIdx + anUpperBound; ++aIdx)
{
aPointsArray->SetValue (aIdx - aStartIdx, thePoints->Value (aIdx));
}
Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
aPointsArray,
Standard_False);
myPlanarPolygons.Append (aPlanarPolyg);
aStartIdx = aPntIter;
anEndIdx = aPntIter;
aPlane.Invalidate();
}
else
{
anEndIdx++;
if (anEndIdx == anUpperIdx)
{
Handle (TColgp_HArray1OfPnt) aPointsArray = new TColgp_HArray1OfPnt (0, anEndIdx - aStartIdx);
for (Standard_Integer aIdx = aStartIdx; aIdx <= anEndIdx; ++aIdx)
{
aPointsArray->SetValue (aIdx - aStartIdx, thePoints->Value (aIdx));
}
Handle(Select3D_SensitivePoly) aPlanarPolyg = new Select3D_SensitivePoly (theOwnerId,
aPointsArray,
Standard_False);
myPlanarPolygons.Append (aPlanarPolyg);
}
}
}
}
myPolygonsIdxs = new TColStd_HArray1OfInteger (0, myPlanarPolygons.Length() - 1);
for (Standard_Integer aIdx = 0; aIdx < myPlanarPolygons.Length(); ++aIdx)
{
myPolygonsIdxs->SetValue (aIdx, aIdx);
}
myCOG = aPntSum / thePoints->Length();
myBndBox = aBndBox;
}
// =======================================================================
// function : Matches
// purpose : Checks whether the point set overlaps current selecting
// volume
// =======================================================================
Standard_Boolean Select3D_InteriorSensitivePointSet::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
return Select3D_SensitiveSet::Matches (theMgr, thePickResult);
}
// =======================================================================
// function : GetPoints
// purpose : Initializes the given array theHArrayOfPnt by 3d
// coordinates of vertices of the whole point set
// =======================================================================
void Select3D_InteriorSensitivePointSet::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt)
{
Standard_Integer aSize = 0;
for (Standard_Integer anIdx = 0; anIdx < myPlanarPolygons.Length(); ++anIdx)
{
const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (anIdx);
aSize += aPolygon->NbSubElements();
}
aSize -= (myPlanarPolygons.Length() - 1) * 2;
theHArrayOfPnt = new TColgp_HArray1OfPnt (1, aSize);
Standard_Integer anOutputPntArrayIdx = 1;
for (Standard_Integer aPolygIdx = 0; aPolygIdx < myPlanarPolygons.Length(); ++aPolygIdx)
{
const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (aPolygIdx);
Handle(TColgp_HArray1OfPnt) aPoints;
aPolygon->Points3D (aPoints);
Standard_Integer anUpper = aPolygIdx < myPlanarPolygons.Length() - 1 ? aPoints->Upper() : aPoints->Upper() + 1;
for (Standard_Integer aPntIter = 1; aPntIter < anUpper; ++aPntIter)
{
theHArrayOfPnt->SetValue (anOutputPntArrayIdx, aPoints->Value (aPntIter));
anOutputPntArrayIdx++;
}
aPoints.Nullify();
}
}
//=======================================================================
// function : Size
// purpose : Returns the length of vector of planar convex polygons
//=======================================================================
Standard_Integer Select3D_InteriorSensitivePointSet::Size() const
{
return myPlanarPolygons.Length();
}
//=======================================================================
// function : Box
// purpose : Returns bounding box of planar convex polygon with index
// theIdx
//=======================================================================
Select3D_BndBox3d Select3D_InteriorSensitivePointSet::Box (const Standard_Integer theIdx) const
{
Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theIdx);
return myPlanarPolygons.Value (aPolygIdx)->BoundingBox();
}
//=======================================================================
// function : Center
// purpose : Returns geometry center of planar convex polygon with index
// theIdx in the vector along the given axis theAxis
//=======================================================================
Standard_Real Select3D_InteriorSensitivePointSet::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
{
Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theIdx);
const gp_XYZ& aCOG = myPlanarPolygons.Value (aPolygIdx)->CenterOfGeometry().XYZ();
Standard_Real aCenter = theAxis == 0 ? aCOG.X() : (theAxis == 1 ? aCOG.Y() : aCOG.Z());
return aCenter;
}
//=======================================================================
// function : Swap
// purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector
//=======================================================================
void Select3D_InteriorSensitivePointSet::Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2)
{
Standard_Integer aPolygIdx1 = myPolygonsIdxs->Value (theIdx1);
Standard_Integer aPolygIdx2 = myPolygonsIdxs->Value (theIdx2);
myPolygonsIdxs->ChangeValue (theIdx1) = aPolygIdx2;
myPolygonsIdxs->ChangeValue (theIdx2) = aPolygIdx1;
}
// =======================================================================
// function : overlapsElement
// purpose : Checks whether the planar convex polygon with index theIdx
// in myPlanarPolygons overlaps the current selecting volume
// =======================================================================
Standard_Boolean Select3D_InteriorSensitivePointSet::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth)
{
Standard_Integer aPolygIdx = myPolygonsIdxs->Value (theElemIdx);
const Handle(Select3D_SensitivePoly)& aPolygon = myPlanarPolygons.Value (aPolygIdx);
Handle(TColgp_HArray1OfPnt) aPoints;
aPolygon->Points3D (aPoints);
return theMgr.Overlaps (aPoints, Select3D_TOS_INTERIOR, theMatchDepth);
}
// =======================================================================
// function : distanceToCOG
// purpose : Calculates distance from the 3d projection of used-picked
// screen point to center of the geometry
// =======================================================================
Standard_Real Select3D_InteriorSensitivePointSet::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
{
return theMgr.DistToGeometryCenter (myCOG);
}
//=======================================================================
// function : BoundingBox
// purpose : Returns bounding box of the point set. If location
// transformation is set, it will be applied
//=======================================================================
Select3D_BndBox3d Select3D_InteriorSensitivePointSet::BoundingBox()
{
return myBndBox;
}
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of the point set. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_InteriorSensitivePointSet::CenterOfGeometry() const
{
return myCOG;
}
//=======================================================================
// function : BVH
// purpose : Builds BVH tree for the point set
//=======================================================================
void Select3D_InteriorSensitivePointSet::BVH()
{
BVH();
}
//=======================================================================
// function : NbSubElements
// purpose : Returns the amount of points in set
//=======================================================================
Standard_Integer Select3D_InteriorSensitivePointSet::NbSubElements()
{
return myPlanarPolygons.Length();
}

View File

@@ -0,0 +1,109 @@
// Created on: 2014-08-15
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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.
#ifndef _Select3D_InteriorSensitivePointSet_HeaderFile
#define _Select3D_InteriorSensitivePointSet_HeaderFile
#include <NCollection_Vector.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Handle_TColgp_HArray1OfPnt.hxx>
#include <Handle_TColStd_HArray1OfInteger.hxx>
#include <Select3D_ISensitivePointSet.hxx>
#include <Select3D_SensitivePoly.hxx>
#include <Select3D_SensitiveSet.hxx>
class gp_Pnt;
class SelectBasics_EntityOwner;
class TColgp_Array1OfPnt;
class TColgp_HArray1OfPnt;
class TColStd_HArray1OfInteger;
typedef NCollection_Vector<Handle(Select3D_SensitivePoly)> Select3D_VectorOfHPoly;
//! This class handles the selection of arbitrary point set with internal type of sensitivity.
//! The main principle is to split the point set given onto planar convex polygons and search
//! for the overlap with one or more of them through traverse of BVH tree.
class Select3D_InteriorSensitivePointSet : public Select3D_ISensitivePointSet, public Select3D_SensitiveSet
{
public:
//! Splits the given point set thePoints onto planar convex polygons
Standard_EXPORT Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints);
//! Splits the given point set thePoints onto planar convex polygons
Standard_EXPORT Select3D_InteriorSensitivePointSet (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints);
//! Checks whether the point set overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Initializes the given array theHArrayOfPnt by 3d coordinates of vertices of the
//! whole point set
Standard_EXPORT virtual void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt) Standard_OVERRIDE;
//! Returns the length of vector of planar convex polygons
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns bounding box of planar convex polygon with index theIdx
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
//! Returns geometry center of planar convex polygon with index
//! theIdx in the vector along the given axis theAxis
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIdx1 and theIdx2 in the vector
Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2) Standard_OVERRIDE;
//! Returns bounding box of the point set. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of the point set. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Builds BVH tree for the point set
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
//! Returns the amount of points in set
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
protected:
//! Checks whether the planar convex polygon with index theIdx
//! in myPlanarPolygons overlaps the current selecting volume
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth) Standard_OVERRIDE;
//! Calculates distance from the 3d projection of used-picked
//! screen point to center of the geometry
Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
protected:
Select3D_VectorOfHPoly myPlanarPolygons; //!< Vector of planar polygons
Handle_TColStd_HArray1OfInteger myPolygonsIdxs; //!< Indexes array for BVH calculation
gp_Pnt myCOG; //!< Center of the point set
Select3D_BndBox3d myBndBox; //!< Bounding box of the point set
};
#endif // _Select3D_InteriorSensitivePointSet_HeaderFile

View File

@@ -1,46 +0,0 @@
// 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.
#ifndef _Select3D_Pnt2d_HeaderFile
#define _Select3D_Pnt2d_HeaderFile
#include<gp_Pnt2d.hxx>
#include<Standard_ShortReal.hxx>
#include<Select3D_Macro.hxx>
struct Select3D_Pnt2d{
Standard_ShortReal x, y;
inline operator gp_Pnt2d() const
{
return gp_Pnt2d(x, y);
}
inline operator gp_XY() const
{
return gp_XY(x, y);
}
inline gp_Pnt2d operator = (const gp_Pnt2d& thePnt)
{
x = DToF(thePnt.X());
y = DToF(thePnt.Y());
return *this;
}
};
#endif

View File

@@ -15,14 +15,13 @@
#define _Select3D_PointData_HeaderFile
#include <Select3D_Pnt.hxx>
#include <Select3D_Pnt2d.hxx>
// A framework for safe management of Select3D_SensitivePoly polygons of 3D and 2D points
// A framework for safe management of Select3D_SensitivePoly polygons of 3D points
class Select3D_PointData {
public:
// Constructs internal arrays of 2D and 3D points defined
// Constructs internal array of 3D points defined
// by number of points theNbPoints
Select3D_PointData (const Standard_Integer theNbPoints)
: mynbpoints(theNbPoints)
@@ -31,14 +30,12 @@ public:
Standard_ConstructionError::Raise("Select3D_PointData");
mypolyg3d = new Select3D_Pnt[mynbpoints];
mypolyg2d = new Select3D_Pnt2d[mynbpoints];
}
// Destructor
~Select3D_PointData ()
{
delete [] mypolyg3d;
delete [] mypolyg2d;
}
// Sets Select3D_Pnt to internal array
@@ -61,26 +58,6 @@ public:
mypolyg3d[theIndex] = theValue;
}
// Sets Select3D_Pnt2d to internal array
// of 2D points if theIndex is valid
void SetPnt2d (const Standard_Integer theIndex,
const Select3D_Pnt2d& theValue)
{
if (theIndex < 0 || theIndex >= mynbpoints)
Standard_OutOfRange::Raise("Select3D_PointData::SetPnt2d");
mypolyg2d[theIndex] = theValue;
}
// Sets gp_Pnt2d to internal array
// of 2D points if theIndex is valid
void SetPnt2d (const Standard_Integer theIndex,
const gp_Pnt2d& theValue)
{
if (theIndex < 0 || theIndex >= mynbpoints)
Standard_OutOfRange::Raise("Select3D_PointData::SetPnt2d");
mypolyg2d[theIndex] = theValue;
}
// Returns 3D point from internal array
// if theIndex is valid
Select3D_Pnt Pnt (const Standard_Integer theIndex) const
@@ -90,13 +67,13 @@ public:
return mypolyg3d[theIndex];
}
// Returns 2D point from internal array
// Returns 3D point from internal array
// if theIndex is valid
Select3D_Pnt2d Pnt2d (const Standard_Integer theIndex) const
gp_Pnt Pnt3d (const Standard_Integer theIndex) const
{
if (theIndex < 0 || theIndex >= mynbpoints)
Standard_OutOfRange::Raise("Select3D_PointData::Pnt2d");
return mypolyg2d[theIndex];
Standard_OutOfRange::Raise("Select3D_PointData::Pnt");
return mypolyg3d[theIndex];
}
// Returns size of internal arrays
@@ -112,7 +89,6 @@ private:
private:
Select3D_Pnt* mypolyg3d;
Select3D_Pnt2d* mypolyg2d;
Standard_Integer mynbpoints;
};

View File

@@ -1,257 +0,0 @@
-- Created on: 1992-03-12
-- Created by: Christophe MARION
-- Copyright (c) 1992-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.
-- <cma@sdsun2> copie quasi exacte de HLRAlgo_Projector
class Projector from Select3D inherits Transient from Standard
---Purpose: A framework to define 3D projectors.
-- Projector provides services for projecting points from
-- world-coordinates to a viewing plane. Projection could be defined by
-- corresponding transformation, or coordinate system. The transformation
-- could be constructed for a view with transposed view transformation
-- matrix ( that represents view-orientation ), including, for perspective
-- view, focal distance ( distance from an eye to the view plane ) and
-- translational part that represents translation of focal point in
-- view-coordinate space. The Select3D_Projector class recognizes the
-- predefined set of popular projections: axonometric, top view, front
-- view and uses more efficient algorithm for projection computations.
-- User-defined transformation could be also defined in constructor.
-- Perspective projection consists of two separate parts, that are
-- composed together during computation: transformation component and
-- focale distance.
uses
Real from Standard,
Boolean from Standard,
Trsf from gp,
GTrsf from gp,
Lin from gp,
Pnt from gp,
Vec from gp,
Ax2 from gp,
Vec2d from gp,
Pnt2d from gp,
Box from Bnd,
View from V3d,
Mat4 from Graphic3d,
Mat4d from Graphic3d
raises
NoSuchObject from Standard
is
Create (theView : View from V3d) returns Projector from Select3D;
--- Purpose: Constructs the 3D projector object from the passed view.
-- The projector captures current model-view and projection transformation
-- of the passed view.
Create returns Projector from Select3D;
--- Purpose: Constructs identity projector.
Create (theCS : Ax2 from gp)
---Purpose: Builds the Projector from the model-view transformation specified
-- by the passed viewing coordinate system <theCS>. The Projector has
-- identity projection transformation, is orthogonal.
-- The viewing coordinate system could be constructed from x direction,
-- view plane normal direction, and view point location in
-- world-coordinate space.
returns Projector from Select3D;
Create (theCS : Ax2 from gp;
theFocus : Real from Standard)
---Purpose: Builds the Projector from the model-view transformation specified
-- by the passed view coordinate system <theCS> and simplified perspective
-- projection transformation defined by <theFocus> parameter.
-- The viewing coordinate system could be constructed from x direction,
-- view plane normal direction, and focal point location in world-coordinate
-- space. <theFocus> should represent distance of an eye from view plane
-- in world-coordinate space (focal distance).
returns Projector from Select3D;
Create (theViewTrsf : Trsf from gp;
theIsPersp : Boolean from Standard;
theFocus : Real from Standard)
---Purpose: Build the Projector from the model-view transformation passed
-- as <theViewTrsf> and simplified perspective projection transformation
-- parameters passed as <theIsPersp> and <theFocus>.
-- In case, when <theViewTrsf> transformation should represent custom view
-- projection, it could be constructed from two separate components:
-- transposed view orientation matrix and translation of focal point
-- in view-coordinate system.
-- <theViewTrsf> could be built up from x direction, up direction,
-- view plane normal direction vectors and translation with SetValues(...)
-- method, where first row arguments (a11, a12, a13, a14) are x, y, z
-- component of x direction vector, and x value of reversed translation
-- vector. Second row arguments, are x y z for up direction and y value of
-- reversed translation, and the third row defined in the same manner.
-- This also suits for simple perspective view, where <theFocus> is the focale
-- distance of an eye from view plane in world-space coordinates.
-- Note, that in that case amount of perspective distortion (perspective
-- angle) should be defined through focal distance.
returns Projector from Select3D;
Create (theViewTrsf : GTrsf from gp;
theIsPersp : Boolean from Standard;
theFocus : Real from Standard)
---Purpose: Builds the Projector from the model-view transformation passed
-- as <theViewTrsf> and projection transformation for <theIsPersp> and
-- <theFocus> parameters.
-- In case, when <theViewTrsf> transformation should represent custom view
-- projection, it could be constructed from two separate components:
-- transposed view orientation matrix and translation of a focal point
-- in view-coordinate system.
-- This also suits for perspective view, with <theFocus> that could be
-- equal to distance from an eye to a view plane in
-- world-coordinates (focal distance).
-- The 3x3 transformation matrix is built up from three vectors:
-- x direction, up direction and view plane normal vectors, where each
-- vector is a matrix row. Then <theViewTrsf> is constructed from matrix and
-- reversed translation with methods SetTranslationPart(..) and
-- SetVectorialPart(..).
-- Note, that in that case amount of perspective distortion (perspective
-- angle) should be defined through focal distance.
returns Projector from Select3D;
Create (theViewTrsf : Mat4d from Graphic3d;
theProjTrsf : Mat4d from Graphic3d;
theZNear : Real from Standard = 0.0;
theZFar : Real from Standard = 10.0)
---Purpose: Builds the Projector from the passed model-view <theViewTrsf>
-- and projection <theProjTrsf> transformation matrices. Parameters <theZNear>
-- and <theZFar> are passed to define view frustum depth for further projection
-- line computation using perspective projection.
returns Projector from Select3D;
Set (me : mutable;
theViewTrsf : Trsf from gp;
theIsPersp : Boolean from Standard;
theFocus : Real from Standard);
---Purpose: Sets new parameters for the Projector.
Set (me : mutable;
theViewTrsf : Mat4d from Graphic3d;
theProjTrsf : Mat4d from Graphic3d;
theZNear : Real from Standard;
theZFar : Real from Standard);
---Purpose: Sets new parameters for the Projector.
SetView (me : mutable;
theView : View from V3d);
---Purpose: Sets new parameters for the Projector
-- captured from the passed view.
Scaled (me : mutable; theToCheckOptimized : Boolean from Standard = Standard_False)
---Purpose: Pre-compute inverse transformation and ensure whether it is possible
-- to use optimized transformation for the common view-orientation type or not
-- if <theToCheckOptimized> is TRUE.
is virtual;
Perspective (me) returns Boolean
---Purpose: Returns True if there is simplified perspective
-- projection approach is used. Distortion defined by Focus.
---C++: inline
is virtual;
Focus (me) returns Real from Standard
---Purpose: Returns the focal length of simplified perspective
-- projection approach. Raises program error exception if the
-- the projection transformation is not specified as simplified
-- Perspective (for example, custom projection transformation is defined
-- or the orthogonal Projector is defined).
---C++: inline
is virtual;
Projection (me) returns Mat4d from Graphic3d;
---Purpose: Returns projection transformation. Please note that for
-- simplified perspective projection approach, defined by Focus, the
-- returned transformation is identity.
---C++: inline
---C++: return const &
Transformation (me) returns GTrsf from gp
---Purpose: Returns the view transformation.
---C++: inline
---C++: return const &
is virtual;
InvertedTransformation (me) returns GTrsf from gp
---Purpose: Returns the inverted view transformation.
---C++: inline
---C++: return const &
is virtual;
FullTransformation (me) returns Trsf from gp
---Purpose: Returns the uniform-scaled view transformation.
---C++: inline
---C++: return const &
is virtual;
Transform (me; theD : in out Vec from gp)
---Purpose: Transforms the vector into view-coordinate space.
---C++: inline
is virtual;
Transform (me; thePnt : in out Pnt from gp)
---Purpose: Transforms the point into view-coordinate space.
---C++: inline
is virtual;
Project (me; theP : Pnt from gp; thePout : out Pnt2d from gp)
---Purpose: Transforms the point into view-coordinate space
-- and applies projection transformation.
is virtual;
Project (me; theP : Pnt from gp; theX, theY, theZ : out Real from Standard)
---Purpose: Transforms the point into view-coordinate space
-- and applies projection transformation.
is static;
Project (me; theP : Pnt from gp;
theD1 : Vec from gp;
thePout : out Pnt2d from gp;
theD1out : out Vec2d from gp)
---Purpose: Transforms the point and vector passed from its location
-- into view-coordinate space and applies projection transformation.
is virtual;
Shoot (me; theX, theY : Real from Standard) returns Lin from gp
---Purpose: Return projection line going through the 2d point <theX, theY>
is virtual;
Transform(me; thePnt : in out Pnt from gp;
theTrsf : GTrsf from gp)
---C++: inline
is virtual;
Transform(me; theLin : in out Lin from gp;
theTrsf : GTrsf from gp)
---C++: inline
is virtual;
fields
myType : Integer from Standard;
myPersp : Boolean from Standard is protected;
myFocus : Real from Standard is protected;
myGTrsf : GTrsf from gp is protected;
myInvTrsf : GTrsf from gp is protected;
myScaledTrsf : Trsf from gp is protected;
myProjTrsf : Mat4d from Graphic3d is protected;
myZNear : Real from Standard is protected;
myZFar : Real from Standard is protected;
end Projector;

View File

@@ -1,492 +0,0 @@
// Created on: 1992-03-13
// Created by: Christophe MARION
// Copyright (c) 1992-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_Projector.ixx>
#include <Precision.hxx>
#include <gp_Ax3.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Mat.hxx>
#include <Graphic3d_Vec4.hxx>
namespace
{
//=======================================================================
//function : TrsfType
//purpose :
//=======================================================================
static Standard_Integer TrsfType(const gp_GTrsf& theTrsf)
{
const gp_Mat& aMat = theTrsf.VectorialPart();
if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
&& (Abs (aMat.Value (2, 2) - 1.0) < 1e-15)
&& (Abs (aMat.Value (3, 3) - 1.0) < 1e-15))
{
return 1; // top
}
else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
&& (Abs (aMat.Value (1, 2) + 0.5) < 1e-15)
&& (Abs (aMat.Value (1, 3) - 0.5) < 1e-15)
&& (Abs (aMat.Value (2, 1) - 0.7071067811865476) < 1e-15)
&& (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
&& (Abs (aMat.Value (2, 3) + 0.5) < 1e-15)
&& (Abs (aMat.Value (3, 1)) < 1e-15)
&& (Abs (aMat.Value (3, 2) - 0.7071067811865476) < 1e-15)
&& (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
{
return 0; // inverse axo
}
else if ((Abs (aMat.Value (1, 1) - 1.0) < 1e-15)
&& (Abs (aMat.Value (2, 3) - 1.0) < 1e-15)
&& (Abs (aMat.Value (3, 2) + 1.0) < 1e-15))
{
return 2; // front
}
else if ((Abs (aMat.Value (1, 1) - 0.7071067811865476) < 1e-15)
&& (Abs (aMat.Value (1, 2) - 0.7071067811865476) < 1e-15)
&& (Abs (aMat.Value (1, 3)) < 1e-15)
&& (Abs (aMat.Value (2, 1) + 0.5) < 1e-15)
&& (Abs (aMat.Value (2, 2) - 0.5) < 1e-15)
&& (Abs (aMat.Value (2, 3) - 0.7071067811865476) < 1e-15)
&& (Abs (aMat.Value (3, 1) - 0.5) < 1e-15)
&& (Abs (aMat.Value (3, 2) + 0.5) < 1e-15)
&& (Abs (aMat.Value (3, 3) - 0.7071067811865476) < 1e-15))
{
return 3; // axo
}
return -1;
}
//====== TYPE 0 (inverse axonometric)
// (0.7071067811865476, -0.5 , 0.4999999999999999)
// (0.7071067811865475, 0.5000000000000001, -0.5 )
// (0.0, 0.7071067811865475, 0.7071067811865476)
// ====== TYPE 1 (top)
// (1.0, 0.0, 0.0)
// (0.0, 1.0, 0.0)
// (0.0, 0.0, 1.0)
// ======= TYPE 2 (front)
// (1.0, 0.0 , 0.0)
// (0.0, 1.110223024625157e-16 , 1.0)
// (0.0, -1.0 , 1.110223024625157e-16)
// ======= TYPE 3 (axonometric)
// ( 0.7071067811865476, 0.7071067811865475, 0.0)
// (-0.5 , 0.5000000000000001, 0.7071067811865475)
// ( 0.4999999999999999, -0.5 , 0.7071067811865476)
}
// formula for derivating a perspective, from Mathematica
// X'[t] X[t] Z'[t]
// D1 = -------- + -------------
// Z[t] Z[t] 2
// 1 - ---- f (1 - ----)
// f f
//=======================================================================
//function : Select3D_Projector
//purpose :
//=======================================================================
Select3D_Projector::Select3D_Projector (const Handle(V3d_View)& theView)
: myPersp (Standard_False),
myFocus (0.0),
myZNear (0.0),
myZFar (10.0),
myType (-1)
{
SetView (theView);
}
//=======================================================================
//function : Select3D_Projector
//purpose :
//=======================================================================
Select3D_Projector::Select3D_Projector()
: myPersp (Standard_False),
myFocus (0.0),
myZNear (0.0),
myZFar (10.0),
myType (-1)
{
Scaled();
}
//=======================================================================
//function : Select3D_Projector
//purpose :
//=======================================================================
Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS)
: myPersp (Standard_False),
myFocus (0.0),
myZNear (0.0),
myZFar (10.0),
myType (-1)
{
myScaledTrsf.SetTransformation (theCS);
myGTrsf.SetTrsf (myScaledTrsf);
Scaled();
}
//=======================================================================
//function : Select3D_Projector
//purpose :
//=======================================================================
Select3D_Projector::Select3D_Projector (const gp_Ax2& theCS, const Standard_Real theFocus)
: myPersp (Standard_True),
myFocus (theFocus),
myZNear (0.0),
myZFar (10.0),
myType (-1)
{
myScaledTrsf.SetTransformation (theCS);
myGTrsf.SetTrsf (myScaledTrsf);
Scaled();
}
//=======================================================================
//function : Select3D_Projector
//purpose :
//=======================================================================
Select3D_Projector::Select3D_Projector (const gp_Trsf& theViewTrsf,
const Standard_Boolean theIsPersp,
const Standard_Real theFocus)
: myPersp (theIsPersp),
myFocus (theFocus),
myGTrsf (theViewTrsf),
myScaledTrsf (theViewTrsf),
myZNear (0.0),
myZFar (10.0),
myType (-1)
{
Scaled();
}
//=======================================================================
//function : Select3D_Projector
//purpose :
//=======================================================================
Select3D_Projector::Select3D_Projector (const gp_GTrsf& theViewTrsf,
const Standard_Boolean theIsPersp,
const Standard_Real theFocus)
: myPersp (theIsPersp),
myFocus (theFocus),
myGTrsf (theViewTrsf),
myScaledTrsf (theViewTrsf.Trsf()),
myZNear (0.0),
myZFar (10.0),
myType (-1)
{
Scaled();
}
//=======================================================================
//function : Select3D_Projector
//purpose :
//=======================================================================
Select3D_Projector::Select3D_Projector (const Graphic3d_Mat4d& theViewTrsf,
const Graphic3d_Mat4d& theProjTrsf,
const Standard_Real theZNear,
const Standard_Real theZFar)
: myPersp (Standard_False),
myFocus (0.0),
myType (-1)
{
Set (theViewTrsf, theProjTrsf, theZNear, theZFar);
}
//=======================================================================
//function : Set
//purpose :
//=======================================================================
void Select3D_Projector::Set (const gp_Trsf& theViewTrsf,
const Standard_Boolean theIsPersp,
const Standard_Real theFocus)
{
myPersp = theIsPersp;
myFocus = theFocus;
myScaledTrsf = theViewTrsf;
myProjTrsf.InitIdentity();
Scaled();
}
//=======================================================================
//function : Set
//purpose :
//=======================================================================
void Select3D_Projector::Set (const Graphic3d_Mat4d& theViewTrsf,
const Graphic3d_Mat4d& theProjTrsf,
const Standard_Real theZNear,
const Standard_Real theZFar)
{
// Copy elements corresponding to common view-transformation
for (Standard_Integer aRowIt = 0; aRowIt < 3; ++aRowIt)
{
for (Standard_Integer aColIt = 0; aColIt < 4; ++aColIt)
{
myGTrsf.SetValue (aRowIt + 1, aColIt + 1, theViewTrsf.GetValue (aRowIt, aColIt));
}
}
// Adapt scaled transformation for compatibilty
gp_Dir aViewY (theViewTrsf.GetValue (0, 1), theViewTrsf.GetValue (1, 1), theViewTrsf.GetValue (2, 1));
gp_Dir aViewZ (theViewTrsf.GetValue (0, 2), theViewTrsf.GetValue (1, 2), theViewTrsf.GetValue (2, 2));
gp_XYZ aViewT (theViewTrsf.GetValue (0, 3), theViewTrsf.GetValue (1, 3), theViewTrsf.GetValue (2, 3));
gp_Dir aViewX = aViewY ^ aViewZ;
gp_Ax3 aViewAx3 (gp_Pnt (aViewT), aViewZ, aViewX);
myScaledTrsf.SetTransformation (aViewAx3);
myPersp = Standard_False;
myFocus = 0.0;
myProjTrsf = theProjTrsf;
myZNear = theZNear;
myZFar = theZFar;
Scaled();
}
//=======================================================================
//function : SetView
//purpose :
//=======================================================================
void Select3D_Projector::SetView (const Handle(V3d_View)& theView)
{
const Graphic3d_Mat4d& aViewTrsf = theView->Camera()->OrientationMatrix();
const Graphic3d_Mat4d& aProjTrsf = theView->Camera()->ProjectionMatrix();
gp_XYZ aFrameScale = theView->Camera()->ViewDimensions();
Graphic3d_Mat4d aScale;
aScale.ChangeValue (0, 0) = aFrameScale.X();
aScale.ChangeValue (1, 1) = aFrameScale.Y();
aScale.ChangeValue (2, 2) = aFrameScale.Z();
Graphic3d_Mat4d aScaledProjTrsf = aScale * aProjTrsf;
Set (aViewTrsf,
aScaledProjTrsf,
theView->Camera()->ZNear(),
theView->Camera()->ZFar());
}
//=======================================================================
//function : Scaled
//purpose :
//=======================================================================
void Select3D_Projector::Scaled (const Standard_Boolean theToCheckOptimized)
{
myType = -1;
if (!theToCheckOptimized && !myPersp && myProjTrsf.IsIdentity())
{
myType = TrsfType (myGTrsf);
}
myInvTrsf = myGTrsf.Inverted();
}
//=======================================================================
//function : Project
//purpose :
//=======================================================================
void Select3D_Projector::Project (const gp_Pnt& theP, gp_Pnt2d& thePout) const
{
Standard_Real aXout = 0.0;
Standard_Real aYout = 0.0;
Standard_Real aZout = 0.0;
Project (theP, aXout, aYout, aZout);
thePout.SetCoord (aXout, aYout);
}
//=======================================================================
//function : Project
//purpose :
//=======================================================================
void Select3D_Projector::Project (const gp_Pnt& theP,
Standard_Real& theX,
Standard_Real& theY,
Standard_Real& theZ) const
{
Graphic3d_Vec4d aTransformed (0.0, 0.0, 0.0, 1.0);
// view transformation
switch (myType)
{
case 0 : // inverse axo
{
Standard_Real aX07 = theP.X() * 0.7071067811865475;
Standard_Real aY05 = theP.Y() * 0.5;
Standard_Real aZ05 = theP.Z() * 0.5;
aTransformed.x() = aX07 - aY05 + aZ05;
aTransformed.y() = aX07 + aY05 - aZ05;
aTransformed.z() = 0.7071067811865475 * (theP.Y() + theP.Z());
break;
}
case 1 : // top
{
aTransformed.x() = theP.X();
aTransformed.y() = theP.Y();
aTransformed.z() = theP.Z();
break;
}
case 2 : // front
{
aTransformed.x() = theP.X();
aTransformed.y() = theP.Z();
aTransformed.z() = -theP.Y();
break;
}
case 3 : // axo
{
Standard_Real aXmy05 = (theP.X() - theP.Y()) * 0.5;
Standard_Real aZ07 = theP.Z() * 0.7071067811865476;
aTransformed.x() = 0.7071067811865476 * (theP.X() + theP.Y());
aTransformed.y() = -aXmy05 + aZ07;
aTransformed.z() = aXmy05 + aZ07;
break;
}
default :
{
gp_Pnt aTransformPnt = theP;
Transform (aTransformPnt);
aTransformed.x() = aTransformPnt.X();
aTransformed.y() = aTransformPnt.Y();
aTransformed.z() = aTransformPnt.Z();
}
}
// projection transformation
if (myPersp)
{
// simplified perspective
Standard_Real aDistortion = 1.0 - aTransformed.z() / myFocus;
theX = aTransformed.x() / aDistortion;
theY = aTransformed.y() / aDistortion;
theZ = aTransformed.z();
return;
}
if (myProjTrsf.IsIdentity())
{
// no projection transformation
theX = aTransformed.x();
theY = aTransformed.y();
theZ = aTransformed.z();
return;
}
Graphic3d_Vec4d aProjected = myProjTrsf * aTransformed;
theX = aProjected.x() / aProjected.w();
theY = aProjected.y() / aProjected.w();
theZ = aProjected.z() / aProjected.w();
}
//=======================================================================
//function : Project
//purpose :
//=======================================================================
void Select3D_Projector::Project (const gp_Pnt& theP,
const gp_Vec& theD1,
gp_Pnt2d& thePout,
gp_Vec2d& theD1out) const
{
// view transformation
gp_Pnt aTP = theP;
Transform (aTP);
gp_Vec aTD1 = theD1;
Transform (aTD1);
// projection transformation
if (myPersp)
{
// simplified perspective
Standard_Real aDist = 1.0 - aTP.Z() / myFocus;
thePout.SetCoord (aTP.X() / aDist, aTP.Y() / aDist);
theD1out.SetCoord (aTD1.X() / aDist + aTP.X() * aTD1.Z() / (myFocus * aDist * aDist),
aTD1.Y() / aDist + aTP.Y() * aTD1.Z() / (myFocus * aDist * aDist));
return;
}
if (myProjTrsf.IsIdentity())
{
// no projection transformation
thePout.SetCoord (aTP.X(), aTP.Y());
theD1out.SetCoord (aTD1.X(), aTD1.Y());
}
Graphic3d_Vec4d aTransformedPnt1 (aTP.X(), aTP.Y(), aTP.Z(), 1.0);
Graphic3d_Vec4d aTransformedPnt2 (aTP.X() + aTD1.X(), aTP.Y() + aTD1.Y(), aTP.Z() + aTD1.Z(), 1.0);
Graphic3d_Vec4d aProjectedPnt1 = myProjTrsf * aTransformedPnt1;
Graphic3d_Vec4d aProjectedPnt2 = myProjTrsf * aTransformedPnt2;
aProjectedPnt1 /= aProjectedPnt1.w();
aProjectedPnt2 /= aProjectedPnt2.w();
Graphic3d_Vec4d aProjectedD1 = aProjectedPnt2 - aProjectedPnt1;
thePout.SetCoord (aProjectedPnt1.x(), aProjectedPnt1.y());
theD1out.SetCoord (aProjectedD1.x(), aProjectedD1.y());
}
//=======================================================================
//function : Shoot
//purpose :
//=======================================================================
gp_Lin Select3D_Projector::Shoot (const Standard_Real theX, const Standard_Real theY) const
{
gp_Lin aViewLin;
if (myPersp)
{
// simplified perspective
aViewLin = gp_Lin (gp_Pnt (0.0, 0.0, myFocus), gp_Dir (theX, theY, -myFocus));
}
else if (myProjTrsf.IsIdentity())
{
// no projection transformation
aViewLin = gp_Lin (gp_Pnt (theX, theY, 0.0), gp_Dir (0.0, 0.0, -1.0));
}
else
{
// get direction of projection over the point in view space
Graphic3d_Mat4d aProjInv;
if (!myProjTrsf.Inverted (aProjInv))
{
return gp_Lin();
}
Graphic3d_Vec4d aVPnt1 = aProjInv * Graphic3d_Vec4d (theX, theY, myZNear, 1.0);
Graphic3d_Vec4d aVPnt2 = aProjInv * Graphic3d_Vec4d (theX, theY, myZFar, 1.0);
aVPnt1 /= aVPnt1.w();
aVPnt2 /= aVPnt2.w();
gp_Vec aViewDir (aVPnt2.x() - aVPnt1.x(), aVPnt2.y() - aVPnt1.y(), aVPnt2.z() - aVPnt1.z());
aViewLin = gp_Lin (gp_Pnt (aVPnt1.x(), aVPnt1.y(), aVPnt1.z()), gp_Dir (aViewDir));
}
// view transformation
Transform (aViewLin, myInvTrsf);
return aViewLin;
}

View File

@@ -1,145 +0,0 @@
// Created on: 1992-07-09
// Created by: Christophe MARION
// Copyright (c) 1992-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 <Graphic3d_Mat4d.hxx>
#include <Standard_Assert.hxx>
#include <gp_Vec.hxx>
#include <gp_Pnt.hxx>
#include <gp_Lin.hxx>
//=======================================================================
//function : Perspective
//purpose :
//=======================================================================
inline Standard_Boolean Select3D_Projector::Perspective() const
{
return myPersp;
}
//=======================================================================
//function : ProjectionTransformation
//purpose :
//=======================================================================
inline const Graphic3d_Mat4d& Select3D_Projector::Projection() const
{
return myProjTrsf;
}
//=======================================================================
//function : Transformation
//purpose :
//=======================================================================
inline const gp_GTrsf& Select3D_Projector::Transformation() const
{
return myGTrsf;
}
//=======================================================================
//function : InvertedTransformation
//purpose :
//=======================================================================
inline const gp_GTrsf& Select3D_Projector::InvertedTransformation() const
{
return myInvTrsf;
}
//=======================================================================
//function : FullTransformation
//purpose :
//=======================================================================
inline const gp_Trsf& Select3D_Projector::FullTransformation() const
{
return myScaledTrsf;
}
//=======================================================================
//function : Focus
//purpose :
//=======================================================================
inline Standard_Real Select3D_Projector::Focus() const
{
Standard_ASSERT_RAISE (myPersp, "Not a simplified Perspective.");
return myFocus;
}
//=======================================================================
//function : Transform
//purpose :
//=======================================================================
inline void Select3D_Projector::Transform (gp_Vec& theD) const
{
gp_XYZ aXYZ = theD.XYZ();
if (myGTrsf.Form() == gp_PntMirror)
{
aXYZ.Reverse();
}
else if (myGTrsf.Form() != gp_Identity && myGTrsf.Form() != gp_Translation)
{
aXYZ.Multiply (myGTrsf.VectorialPart());
}
theD.SetXYZ (aXYZ);
}
//=======================================================================
//function : Transform
//purpose :
//=======================================================================
inline void Select3D_Projector::Transform (gp_Pnt& thePnt) const
{
Transform (thePnt, myGTrsf);
}
//=======================================================================
//function : Transform
//purpose :
//=======================================================================
inline void Select3D_Projector::Transform (gp_Lin& theLin, const gp_GTrsf& theTrsf) const
{
gp_Ax1 anAx1 = theLin.Position();
gp_XYZ aXYZ = anAx1.Location().XYZ();
theTrsf.Transforms (aXYZ);
anAx1.SetLocation (gp_Pnt (aXYZ));
gp_Dir aDir = anAx1.Direction();
gp_XYZ aDirXYZ = aDir.XYZ();
if (theTrsf.Form() == gp_PntMirror)
{
aDirXYZ.Reverse();
}
else if (theTrsf.Form() != gp_Identity && theTrsf.Form() != gp_Translation)
{
aDirXYZ.Multiply (theTrsf.VectorialPart());
Standard_Real aModulus = aDirXYZ.Modulus();
aDirXYZ.Divide (aModulus);
}
aDir.SetXYZ (aDirXYZ);
anAx1.SetDirection (aDir);
theLin.SetPosition (anAx1);
}
//=======================================================================
//function : Transform
//purpose :
//=======================================================================
inline void Select3D_Projector::Transform (gp_Pnt& thePnt, const gp_GTrsf& theTrsf) const
{
gp_XYZ aXYZ = thePnt.XYZ();
theTrsf.Transforms (aXYZ);
thePnt = gp_Pnt (aXYZ);
}

View File

@@ -1,121 +0,0 @@
-- Created on: 1995-04-13
-- 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.
class SensitiveBox from Select3D
inherits SensitiveEntity from Select3D
---Purpose: A framework to define selection by a sensitive box.
uses
Pnt from gp,
Pnt2d from gp,
Box from Bnd,
Box2d from Bnd,
Projector from Select3D,
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Location from TopLoc
is
Create (OwnerId : EntityOwner from SelectBasics;
BoundingBox : Box from Bnd)
returns SensitiveBox;
---Purpose: Constructs a sensitive box object defined by the
-- owner OwnerId, and the bounding box BoundingBox.
Create (OwnerId : EntityOwner from SelectBasics;
XMin,YMin,ZMin,
XMax,YMax,ZMax : Real)
returns SensitiveBox;
--- Purpose: Constructs a sensitive box object defined by the
-- owner OwnerId, and the coordinates Xmin, YMin, ZMin, XMax, YMax, ZMax.
-- Xmin, YMin and ZMin define the minimum point in
-- the front lower left hand corner of the box,
-- and XMax, YMax and ZMax define the maximum
-- point in the back upper right hand corner of the box.
Project (me:mutable;aProjector : Projector from Select3D)
is redefined static;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics)
is redefined static;
---Level: Public
---Purpose: gives the 2D boxes which represent the Box in the
-- selection process...
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean is redefined static;
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard;
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
Box(me) returns Box from Bnd;
---Purpose: Returns the sensitive 3D box used at the time of construction.
---C++: inline
---C++: return const &
ProjectBox(me:mutable;aPrj: Projector from Select3D;aBox:Box from Bnd)
is static private;
fields
mybox3d : Box from Bnd;
mybox2d : Box2d from Bnd;
end SensitiveBox;

View File

@@ -14,198 +14,126 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitiveBox.ixx>
#include <Select3D_SensitiveBox.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <Bnd_Box.hxx>
#include <ElCLib.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveBox, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveBox, Select3D_SensitiveEntity)
//==================================================
// Function: Constructor
// Function: Select3D_SensitiveBox
// Purpose :
//==================================================
Select3D_SensitiveBox::Select3D_SensitiveBox(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Bnd_Box& BBox):
Select3D_SensitiveEntity(OwnerId),
mybox3d(BBox){}
//==================================================
// Function: Constructor
// Purpose :
//==================================================
Select3D_SensitiveBox::
Select3D_SensitiveBox(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real ZMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real ZMax):
Select3D_SensitiveEntity(OwnerId)
Select3D_SensitiveBox::Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Bnd_Box& theBox)
: Select3D_SensitiveEntity (theOwnerId)
{
mybox3d.Update(XMin,YMin,ZMin,XMax,YMax,ZMax);
Standard_Real aXMax, aYMax, aZMax;
Standard_Real aXMin, aYMin, aZMin;
theBox.Get (aXMin, aYMin, aZMin, aXMax, aYMax, aZMax);
myBox = Select3D_BndBox3d (SelectMgr_Vec3 (aXMin, aYMin, aZMin),
SelectMgr_Vec3 (aXMax, aYMax, aZMax));
myCenter3d = (gp_XYZ (aXMin, aYMin, aZMin) + gp_XYZ (aXMax, aYMax, aZMax))
* (1.0 / 2.0);
}
//==================================================
// Function: Project
// Function: Select3D_SensitiveBox
// Purpose :
//==================================================
void Select3D_SensitiveBox::
Project(const Handle(Select3D_Projector)& aProj)
Select3D_SensitiveBox::Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Standard_Real theXMin,
const Standard_Real theYMin,
const Standard_Real theZMin,
const Standard_Real theXMax,
const Standard_Real theYMax,
const Standard_Real theZMax)
: Select3D_SensitiveEntity (theOwnerId)
{
if(HasLocation())
{
Bnd_Box B = mybox3d.Transformed(Location().Transformation());
ProjectBox(aProj,B);
}
else
ProjectBox(aProj,mybox3d);
myBox = Select3D_BndBox3d (SelectMgr_Vec3 (theXMin, theYMin, theZMin),
SelectMgr_Vec3 (theXMax, theYMax, theZMax));
myCenter3d = (gp_XYZ (theXMin, theYMin, theZMin) + gp_XYZ (theXMax, theYMax, theZMax))
* (1.0 / 2.0);
}
//==================================================
// Function: Areas
// Purpose :
//==================================================
void Select3D_SensitiveBox::
Areas(SelectBasics_ListOfBox2d& aSeq)
{ aSeq.Append(mybox2d);}
//=======================================================================
// function : NbSubElements
// purpose : Returns the amount of sub-entities in sensitive
//=======================================================================
Standard_Integer Select3D_SensitiveBox::NbSubElements()
{
return 1;
}
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveBox::GetConnected(const TopLoc_Location& aLoc)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveBox::GetConnected()
{
Handle(Select3D_SensitiveBox) NiouEnt = new Select3D_SensitiveBox(myOwnerId,mybox3d);
if(HasLocation()) NiouEnt->SetLocation(Location());
NiouEnt->UpdateLocation(aLoc);
return NiouEnt;
Bnd_Box aBox;
aBox.Update (myBox.CornerMin().x(), myBox.CornerMin().y(), myBox.CornerMin().z(),
myBox.CornerMax().x(), myBox.CornerMax().y(), myBox.CornerMax().z());
Handle(Select3D_SensitiveBox) aNewEntity = new Select3D_SensitiveBox (myOwnerId, aBox);
return aNewEntity;
}
//==================================================
// Function: Matches
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveBox::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
//=======================================================================
// function : Matches
// purpose : Checks whether the box overlaps current selecting volume
//=======================================================================
Standard_Boolean Select3D_SensitiveBox::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
// check that sensitive box passes by depth
Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
if (thePickArgs.IsClipped (aDepth))
Standard_Real aDepth = RealLast();
Standard_Real aDistToCOG = RealLast();
Standard_Boolean isMatched = theMgr.Overlaps (myBox, aDepth);
if (isMatched)
{
return Standard_False;
aDistToCOG = theMgr.DistToGeometryCenter (myCenter3d);
}
theMatchDMin = 0.0;
theMatchDepth = aDepth;
return Standard_True;
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
return isMatched;
}
//==================================================
// Function: Matches
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveBox::
Matches (const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real aTol)
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of the box. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_SensitiveBox::CenterOfGeometry() const
{
Bnd_Box2d BoundBox;
BoundBox.Update(XMin-aTol,YMin-aTol,XMax+aTol,YMax+aTol);
return(!BoundBox.IsOut(mybox2d));
return myCenter3d;
}
//=======================================================================
//function : Matches
//purpose :
// function : BoundingBox
// purpose : Returns coordinates of the box. If location transformation
// is set, it will be applied
//=======================================================================
Standard_Boolean Select3D_SensitiveBox::
Matches (const TColgp_Array1OfPnt2d& /*aPoly*/,
const Bnd_Box2d& aBox,
const Standard_Real /*aTol*/)
Select3D_BndBox3d Select3D_SensitiveBox::BoundingBox()
{
return(!aBox.IsOut(mybox2d));
return myBox;
}
//=======================================================================
//function : Dump
//purpose :
// function : Box
// purpose :
//=======================================================================
void Select3D_SensitiveBox::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
Bnd_Box Select3D_SensitiveBox::Box() const
{
S<<"\tSensitiveBox 3D :\n";
if(HasLocation())
S<<"\t\tExisting Location"<<endl;
Standard_Real XMin,YMin,ZMin,XMax,YMax,ZMax;
mybox3d.Get(XMin,YMin,ZMin,XMax,YMax,ZMax);
S<<"\t\t PMin [ "<<XMin<<" , "<<YMin<<" , "<<ZMin<<" ]";
S<<"\t\t PMax [ "<<XMax<<" , "<<YMax<<" , "<<ZMax<<" ]"<<endl;
Bnd_Box aBox;
aBox.Update (myBox.CornerMin().x(), myBox.CornerMin().y(), myBox.CornerMin().z(),
myBox.CornerMax().x(), myBox.CornerMax().y(), myBox.CornerMax().z());
if(FullDump)
{
// S<<"\t\t\tOwner:"<<myOwnerId<<endl;
Select3D_SensitiveEntity::DumpBox(S,mybox2d);
}
}
//=======================================================================
//function : ProjectBox
//purpose :
//=======================================================================
void Select3D_SensitiveBox::ProjectBox(const Handle(Select3D_Projector)& aPrj,
const Bnd_Box& aBox)
{
mybox2d.SetVoid();
gp_Pnt2d curp2d;
Standard_Real XMin,YMin,ZMin,XMax,YMax,ZMax;
aBox.Get(XMin,YMin,ZMin,XMax,YMax,ZMax);
aPrj->Project(gp_Pnt(XMin,YMin,ZMin),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
aPrj->Project(gp_Pnt(XMax,YMin,ZMin),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
aPrj->Project(gp_Pnt(XMax,YMax,ZMin),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
aPrj->Project(gp_Pnt(XMin,YMax,ZMin),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
aPrj->Project(gp_Pnt(XMin,YMin,ZMax),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
aPrj->Project(gp_Pnt(XMax,YMin,ZMax),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
aPrj->Project(gp_Pnt(XMax,YMax,ZMax),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
aPrj->Project(gp_Pnt(XMin,YMax,ZMax),curp2d);
mybox2d.Update(curp2d.X(),curp2d.Y());
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveBox::ComputeDepth(const gp_Lin& EyeLine) const
{
Standard_Real XMin,YMin,ZMin,XMax,YMax,ZMax;
mybox3d.Get(XMin,YMin,ZMin,XMax,YMax,ZMax);
gp_Pnt PMid((XMin+XMax)/2.,(YMin+YMax)/2.,(ZMin+ZMax)/2.);
return ElCLib::Parameter(EyeLine,PMid);
return aBox;
}

View File

@@ -0,0 +1,88 @@
// Created on: 1995-04-13
// 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.
#ifndef _Select3D_SensitiveBox_HeaderFile
#define _Select3D_SensitiveBox_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Bnd_Box.hxx>
#include <gp_Pnt.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Standard_OStream.hxx>
class SelectBasics_EntityOwner;
class Bnd_Box;
class TopLoc_Location;
//! A framework to define selection by a sensitive box.
class Select3D_SensitiveBox : public Select3D_SensitiveEntity
{
public:
//! Constructs a sensitive box object defined by the
//! owner theOwnerId, and the box theBox.
Standard_EXPORT Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId, const Bnd_Box& theBox);
//! Constructs a sensitive box object defined by the
//! owner theOwnerId, and the coordinates theXmin, theYMin, theZMin, theXMax, theYMax, theZMax.
//! theXmin, theYMin and theZMin define the minimum point in
//! the front lower left hand corner of the box,
//! and theXMax, theYMax and theZMax define the maximum
//! point in the back upper right hand corner of the box.
Standard_EXPORT Select3D_SensitiveBox (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Standard_Real theXMin,
const Standard_Real theYMin,
const Standard_Real theZMin,
const Standard_Real theXMax,
const Standard_Real theYMax,
const Standard_Real theZMax);
//! Returns the amount of sub-entities in sensitive
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Checks whether the box overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
Bnd_Box Box() const;
//! Returns center of the box. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Returns coordinates of the box. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveBox)
private:
Select3D_BndBox3d myBox; //!< 3d coordinates of box corners
gp_Pnt myCenter3d; //!< 3d coordinate of box's center
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveBox, Select3D_SensitiveEntity)
#endif // _Select3D_SensitiveBox_HeaderFile

View File

@@ -1,18 +0,0 @@
// Created on: 1997-07-16
// Created by: Robert COUBLANC
// Copyright (c) 1997-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.
inline const Bnd_Box& Select3D_SensitiveBox::Box() const
{return mybox3d;}

View File

@@ -1,155 +0,0 @@
-- Created on: 1996-02-06
-- Created by: Robert COUBLANC
-- Copyright (c) 1996-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.
class SensitiveCircle from Select3D
inherits SensitivePoly from Select3D
---Purpose: A framework to define sensitive 3D arcs and circles.
-- In some cases this class can raise Standard_ConstructionError and
-- Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
uses
Pnt from gp,
Pnt2d from gp,
Projector from Select3D,
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Circle from Geom,
Array1OfPnt from TColgp,
HArray1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
Location from TopLoc,
Pnt from Select3D,
Pnt2d from Select3D,
Projector from Select3D,
SensitiveEntity from Select3D,
Circle from Geom
raises
ConstructionError from Standard,
OutOfRange from Standard
is
Create (OwnerId : EntityOwner from SelectBasics;
TheCircle : Circle from Geom;
FilledCircle : Boolean = Standard_False;
NbOfPoints : Integer = 6)
returns SensitiveCircle;
---Level: Public
---Purpose: Constructs the sensitive circle object defined by the
-- owner OwnerId, the circle Circle, the Boolean
-- FilledCircle and the number of points NbOfPoints.
Create (OwnerId : EntityOwner from SelectBasics;
TheCircle : Circle from Geom;
u1 : Real ;
u2 : Real;
FilledCircle : Boolean = Standard_False;
NbOfPoints : Integer = 6)
returns SensitiveCircle;
---Level: Public
---Purpose: Constructs the sensitive arc object defined by the
-- owner OwnerId, the circle Circle, the parameters u1
-- and u2, the Boolean FilledCircle and the number of points NbOfPoints.
-- u1 and u2 define the first and last points of the arc on Circle.
Create(OwnerId : EntityOwner from SelectBasics;
apolyg3d : HArray1OfPnt from TColgp;
FilledCircle : Boolean from Standard = Standard_False)
returns SensitiveCircle;
---Level: Internal
---Purpose: Constructs the sensitive circle object defined by the
-- owner OwnerId, the array of triangles apolyg3d, and the Boolean FilledCircle.
-- apolyg3d is an array of consecutive triangles on the
-- circle. The triangle i+1 lies on the intersection of the
-- tangents to the circle of i and i+2. Note, that the first point of apolyg3d
-- must be equal to the last point of apolyg3d.
Create(OwnerId : EntityOwner from SelectBasics;
apolyg3d : Array1OfPnt from TColgp;
FilledCircle : Boolean from Standard = Standard_False)
returns SensitiveCircle;
---Purpose: Constructs the sensitive circle object defined by the
-- owner OwnerId, the array of points apolyg3d, and the Boolean FilledCircle.
-- If the length of apolyg3d is more then 1, the first point of apolyg3d
-- must be equal to the last point of apolyg3d.
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is redefined static;
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth (me;
thePickLine : Lin from gp;
theDetectedIndex : Integer from Standard)
returns Real from Standard;
---Level: Public
---Purpose: Compute depth of sensitive circle for the detected sub-part.
-- @param thePickLine [in] the picking line.
-- @param theDetectedIndex [in] index of the detected sub-part.
-- @return depth on the picking line.
ArrayBounds(me;Low,Up:in out Integer);
GetPoint3d(me;rank:Integer) returns Pnt from gp;
---Level: Internal
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
GetConnected(me: mutable; theLocation : Location from TopLoc)
returns SensitiveEntity from Select3D
is redefined virtual;
---Level: Public
---Purpose: Returns the copy of this.
Project(me: mutable;aProjector: Projector from Select3D) is redefined virtual;
ComputeCenter3D(me: mutable) is private;
---Level: Internal
---Purpose: Computes myCenter3D as the barycenter of points from mypolyg3d
fields
myFillStatus : Boolean;
myCenter2D : Pnt2d from Select3D; -- used for Matches()
myCenter3D : Pnt from Select3D; -- used for Matches()
myCircle : Circle from Geom;
mystart : Real from Standard; -- used for GetConnected()
myend : Real from Standard; -- used for GetConnected()
end SensitiveCircle;

View File

@@ -14,43 +14,41 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// Modified Tue Apr 14 1998 by rob : fix Bug : Case of Null Radius Circle...
#include <Geom_Circle.hxx>
#include <Select3D_SensitiveCircle.ixx>
#include <Precision.hxx>
#include <gp_Lin2d.hxx>
#include <CSLib_Class2d.hxx>
#include <Select3D_SensitiveTriangle.hxx>
#include <ElCLib.hxx>
#include <Select3D_Pnt.hxx>
#include <Select3D_Pnt2d.hxx>
#include <Select3D_Projector.hxx>
#include <Select3D_SensitiveTriangle.hxx>
#include <Precision.hxx>
#include <Select3D_SensitiveCircle.hxx>
static Standard_Integer S3D_GetCircleNBPoints(const Handle(Geom_Circle)& C,
const Standard_Integer anInputNumber)
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveCircle, Select3D_SensitivePoly)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle, Select3D_SensitivePoly)
static Standard_Integer GetCircleNbPoints (const Handle(Geom_Circle)& theCircle,
const Standard_Integer theNbPnts)
{
// Check if number of points is invalid.
// In this case mypolyg raises Standard_ConstructionError
// In this case myPolyg raises Standard_ConstructionError
// exception (look constructor bellow).
if (anInputNumber <= 0)
if (theNbPnts <= 0)
return 0;
if (C->Radius()>Precision::Confusion())
return 2*anInputNumber+1;
if (theCircle->Radius() > Precision::Confusion())
return 2 * theNbPnts + 1;
// The radius is too small and circle degenerates into point
return 1;
}
static Standard_Integer S3D_GetArcNBPoints(const Handle(Geom_Circle)& C,
const Standard_Integer anInputNumber)
static Standard_Integer GetArcNbPoints (const Handle(Geom_Circle)& theCircle,
const Standard_Integer theNbPnts)
{
// There is no need to check number of points here.
// In case of invalid number of points this method returns
// -1 or smaller value.
if (C->Radius()>Precision::Confusion())
return 2*anInputNumber-1;
if (theCircle->Radius() > Precision::Confusion())
return 2 * theNbPnts - 1;
// The radius is too small and circle degenerates into point
return 1;
@@ -60,53 +58,57 @@ static Standard_Integer S3D_GetArcNBPoints(const Handle(Geom_Circle)& C,
//function : Select3D_SensitiveCircle (constructor)
//purpose : Definition of a sensitive circle
//=======================================================================
Select3D_SensitiveCircle::
Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(Geom_Circle)& TheCircle,
const Standard_Boolean FilledCircle,
const Standard_Integer NbPoints):
Select3D_SensitivePoly(OwnerId, S3D_GetCircleNBPoints(TheCircle,NbPoints)),
myFillStatus(FilledCircle),
myCircle(TheCircle),
mystart(0),
myend(0)
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Geom_Circle)& theCircle,
const Standard_Boolean theIsFilled,
const Standard_Integer theNbPnts)
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)),
myCircle (theCircle),
myStart (0),
myEnd (0)
{
if (mypolyg.Size() != 1)
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (myPolyg.Size() != 1)
{
gp_Pnt p1,p2;
gp_Vec v1;
Standard_Real ustart = TheCircle->FirstParameter(),uend = TheCircle->LastParameter();
Standard_Real du = (uend-ustart)/NbPoints;
Standard_Real R = TheCircle->Radius();
Standard_Integer rank = 1;
Standard_Real curu =ustart;
for(Standard_Integer anIndex=1;anIndex<=NbPoints;anIndex++)
gp_Pnt aP1, aP2;
gp_Vec aV1;
Standard_Real anUStart = theCircle->FirstParameter();
Standard_Real anUEnd = theCircle->LastParameter();
Standard_Real aStep = (anUEnd - anUStart) / theNbPnts;
Standard_Real aRadius = theCircle->Radius();
Standard_Integer aPntIdx = 1;
Standard_Real aCurU = anUStart;
for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; anIndex++)
{
TheCircle->D1(curu,p1,v1);
theCircle->D1 (aCurU, aP1, aV1);
v1.Normalize();
mypolyg.SetPnt(rank-1, p1);
rank++;
p2 = gp_Pnt(p1.X()+v1.X()*tan(du/2.)*R,
p1.Y()+v1.Y()*tan(du/2.)*R,
p1.Z()+v1.Z()*tan(du/2.)*R);
mypolyg.SetPnt(rank-1, p2);
rank++;
curu+=du;
aV1.Normalize();
myPolyg.SetPnt (aPntIdx - 1, aP1);
aPntIdx++;
aP2 = gp_Pnt (aP1.X() + aV1.X() * tan (aStep / 2.0) * aRadius,
aP1.Y() + aV1.Y() * tan (aStep / 2.0) * aRadius,
aP1.Z() + aV1.Z() * tan (aStep / 2.0) * aRadius);
myPolyg.SetPnt (aPntIdx - 1, aP2);
aPntIdx++;
aCurU += aStep;
}
// Copy the first point to the last point of mypolyg
mypolyg.SetPnt(NbPoints*2, mypolyg.Pnt(0));
// Copy the first point to the last point of myPolyg
myPolyg.SetPnt (theNbPnts * 2, myPolyg.Pnt (0));
// Get myCenter3D
myCenter3D = TheCircle->Location();
myCenter3D = theCircle->Location();
}
// Radius = 0.0
else
{
mypolyg.SetPnt(0, TheCircle->Location());
myPolyg.SetPnt (0, theCircle->Location());
// Get myCenter3D
myCenter3D = mypolyg.Pnt(0);
myCenter3D = myPolyg.Pnt (0);
}
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6.0);
}
}
@@ -114,59 +116,81 @@ myend(0)
//function : Select3D_SensitiveCircle (constructor)
//purpose : Definition of a sensitive arc
//=======================================================================
Select3D_SensitiveCircle::
Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(Geom_Circle)& TheCircle,
const Standard_Real u1,
const Standard_Real u2,
const Standard_Boolean FilledCircle,
const Standard_Integer NbPoints):
Select3D_SensitivePoly(OwnerId, S3D_GetArcNBPoints(TheCircle,NbPoints)),
myFillStatus(FilledCircle),
myCircle(TheCircle),
mystart(u1),
myend(u2)
Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Geom_Circle)& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled,
const Standard_Integer theNbPnts)
: Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetArcNbPoints (theCircle, theNbPnts)),
myCircle (theCircle),
myStart (Min (theU1, theU2)),
myEnd (Max (theU1, theU2))
{
if (mypolyg.Size() != 1)
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (myPolyg.Size() != 1)
{
gp_Pnt p1,p2;
gp_Vec v1;
gp_Pnt aP1, aP2;
gp_Vec aV1;
if (u1 > u2)
Standard_Real aStep = (myEnd - myStart) / (theNbPnts - 1);
Standard_Real aRadius = theCircle->Radius();
Standard_Integer aPntIdx = 1;
Standard_Real aCurU = myStart;
for (Standard_Integer anIndex = 1; anIndex <= theNbPnts - 1; anIndex++)
{
mystart = u2;
myend = u1;
theCircle->D1 (aCurU, aP1, aV1);
aV1.Normalize();
myPolyg.SetPnt (aPntIdx - 1, aP1);
aPntIdx++;
aP2 = gp_Pnt (aP1.X() + aV1.X() * tan (aStep /2.0) * aRadius,
aP1.Y() + aV1.Y() * tan (aStep /2.0) * aRadius,
aP1.Z() + aV1.Z() * tan (aStep /2.0) * aRadius);
myPolyg.SetPnt (aPntIdx - 1, aP2);
aPntIdx++;
aCurU += aStep;
}
Standard_Real du = (myend-mystart)/(NbPoints-1);
Standard_Real R = TheCircle->Radius();
Standard_Integer rank = 1;
Standard_Real curu = mystart;
for(Standard_Integer anIndex=1;anIndex<=NbPoints-1;anIndex++)
{
TheCircle->D1(curu,p1,v1);
v1.Normalize();
mypolyg.SetPnt(rank-1, p1);
rank++;
p2 = gp_Pnt(p1.X()+v1.X()*tan(du/2.)*R,
p1.Y()+v1.Y()*tan(du/2.)*R,
p1.Z()+v1.Z()*tan(du/2.)*R);
mypolyg.SetPnt(rank-1, p2);
rank++;
curu+=du;
}
TheCircle->D0(myend,p1);
mypolyg.SetPnt(NbPoints*2-2, p1);
theCircle->D0 (myEnd, aP1);
myPolyg.SetPnt (theNbPnts * 2 - 2, aP1);
// Get myCenter3D
myCenter3D = TheCircle->Location();
myCenter3D = theCircle->Location();
}
else
{
mypolyg.SetPnt(0, TheCircle->Location());
myPolyg.SetPnt (0, theCircle->Location());
// Get myCenter3D
myCenter3D = mypolyg.Pnt(0);
myCenter3D = myPolyg.Pnt (0);
}
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6.0);
}
}
//=======================================================================
//function : Select3D_SensitiveCircle
//purpose :
//=======================================================================
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
const Standard_Boolean theIsFilled)
: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled),
myStart (0),
myEnd (0)
{
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (myPolyg.Size() != 1)
computeCenter3D();
else
myCenter3D = myPolyg.Pnt (0);
if (mySensType == Select3D_TOS_BOUNDARY)
{
SetSensitivityFactor (6.0);
}
}
@@ -175,338 +199,161 @@ myend(u2)
//purpose :
//=======================================================================
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(TColgp_HArray1OfPnt)& Thepolyg3d,
const Standard_Boolean FilledCircle):
Select3D_SensitivePoly(OwnerId, Thepolyg3d),
myFillStatus(FilledCircle),
mystart(0),
myend(0)
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePnts3d,
const Standard_Boolean theIsFilled)
: Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled),
myStart (0),
myEnd (0)
{
if (mypolyg.Size() != 1)
ComputeCenter3D();
mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
if (myPolyg.Size() != 1)
computeCenter3D();
else
myCenter3D = mypolyg.Pnt(0);
}
myCenter3D = myPolyg.Pnt (0);
//=======================================================================
//function : Select3D_SensitiveCircle
//purpose :
//=======================================================================
Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
const TColgp_Array1OfPnt& Thepolyg3d,
const Standard_Boolean FilledCircle):
Select3D_SensitivePoly(OwnerId, Thepolyg3d),
myFillStatus(FilledCircle),
mystart(0),
myend(0)
{
if (mypolyg.Size() != 1)
ComputeCenter3D();
else
myCenter3D = mypolyg.Pnt(0);
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveCircle::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
Standard_Integer aSize = mypolyg.Size();
Standard_Integer aDetectedIndex = -1;
gp_XY aPickXY (thePickArgs.X(), thePickArgs.Y());
if (aSize != 1)
if (mySensType == Select3D_TOS_BOUNDARY)
{
Standard_Boolean Found = Standard_False;
Standard_Integer anIndex = 0;
SetSensitivityFactor (6.0);
}
}
if(!myFillStatus)
{
while(anIndex < aSize-2 && !Found)
{
Standard_Integer TheStat =
Select3D_SensitiveTriangle::Status(mypolyg.Pnt2d(anIndex),
mypolyg.Pnt2d(anIndex+1),
mypolyg.Pnt2d(anIndex+2),
aPickXY, thePickArgs.Tolerance(),
theMatchDMin);
Found = (TheStat != 2);
if (Found)
{
aDetectedIndex = anIndex;
}
//=======================================================================
// function : BVH
// purpose : Builds BVH tree for a circle's edge segments if needed
//=======================================================================
void Select3D_SensitiveCircle::BVH()
{
if (mySensType == Select3D_TOS_BOUNDARY)
{
Select3D_SensitivePoly::BVH();
}
}
anIndex += 2;
}
}
else
{
Standard_Real Xmin,Ymin,Xmax,Ymax;
//=======================================================================
// function : Matches
// purpose : Checks whether the circle overlaps current selecting volume
//=======================================================================
Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
Standard_Real aDepth = RealLast();
Standard_Real aDistToCOG = RealLast();
// Get coordinates of the bounding box
Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax);
TColgp_Array1OfPnt2d anArrayOf2dPnt(1, aSize);
// Fill anArrayOf2dPnt with points from mypolig2d
Points2D(anArrayOf2dPnt);
CSLib_Class2d anInOutTool (anArrayOf2dPnt,
thePickArgs.Tolerance(),
thePickArgs.Tolerance(),
Xmin, Ymin, Xmax, Ymax);
// Method SiDans returns the status :
// 1 - the point is inside the circle
// 0 - the point is on the circle
// -1 - the point is outside the circle
Standard_Integer aStat = anInOutTool.SiDans (gp_Pnt2d (aPickXY));
if(aStat != -1)
{
// Compute DMin (a distance between the center and the point)
theMatchDMin = gp_XY (myCenter2D.x - aPickXY.X(), myCenter2D.y - aPickXY.Y()).Modulus();
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
}
if (Found)
{
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
Standard_Boolean isCollisionDetected = Standard_False;
if (mySensType == Select3D_TOS_BOUNDARY)
{
isCollisionDetected = Select3D_SensitivePoly::Matches (theMgr, thePickResult);
}
else if (mySensType == Select3D_TOS_INTERIOR)
{
Handle(TColgp_HArray1OfPnt) anArrayOfPnt;
Points3D (anArrayOfPnt);
isCollisionDetected = theMgr.Overlaps (anArrayOfPnt,
Select3D_TOS_INTERIOR,
aDepth);
}
// Circle degenerates into point
theMatchDMin = gp_Pnt2d(aPickXY).Distance(mypolyg.Pnt2d(0));
if (theMatchDMin <= thePickArgs.Tolerance() * SensitivityFactor())
if (isCollisionDetected)
{
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
return !thePickArgs.IsClipped (theMatchDepth);
aDistToCOG = theMgr.DistToGeometryCenter (myCenter3D);
}
return Standard_False;
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
return isCollisionDetected;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveCircle::
Matches(const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real aTol)
void Select3D_SensitiveCircle::ArrayBounds (Standard_Integer & theLow,
Standard_Integer & theUp) const
{
Bnd_Box2d abox;
abox.Update(Min(XMin,XMax),Min(YMin,YMax),Max(XMin,XMax),Max(YMin,YMax));
abox.Enlarge(aTol);
for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();anIndex++)
{
if(abox.IsOut(mypolyg.Pnt2d(anIndex)))
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveCircle::
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);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
{
Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
if(RES!=1)
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : ArrayBounds
//purpose :
//=======================================================================
void Select3D_SensitiveCircle::
ArrayBounds(Standard_Integer & Low,
Standard_Integer & Up) const
{
Low = 0;
Up = mypolyg.Size()-1;
theLow = 0;
theUp = myPolyg.Size() - 1;
}
//=======================================================================
//function : GetPoint3d
//purpose :
//=======================================================================
gp_Pnt Select3D_SensitiveCircle::
GetPoint3d(const Standard_Integer Rank) const
gp_Pnt Select3D_SensitiveCircle::GetPoint3d (const Standard_Integer thePntIdx) const
{
if(Rank>=0 && Rank<mypolyg.Size())
return mypolyg.Pnt(Rank);
if (thePntIdx >= 0 && thePntIdx < myPolyg.Size())
return myPolyg.Pnt (thePntIdx);
return gp_Pnt();
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Select3D_SensitiveCircle::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
{
Standard_Integer aSize = mypolyg.Size();
S<<"\tSensitiveCircle 3D :";
Standard_Boolean isclosed = 1== aSize;
if(isclosed)
S<<"(Closed Circle)"<<endl;
else
S<<"(Arc Of Circle)"<<endl;
if(HasLocation())
S<<"\t\tExisting Location"<<endl;
if(FullDump)
{
gp_XYZ aCenter = myCenter3D;
Standard_Real R = (aCenter-mypolyg.Pnt(0)).Modulus();
S<<"\t\t Center : ("<<aCenter.X()<<" , "<<aCenter.Y()<<" , "<<aCenter.Z()<<" )"<<endl;
S<<"\t\t Radius :"<<R<<endl;
}
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveCircle::ComputeDepth (const gp_Lin& thePickLine,
const Standard_Integer theDetectedIndex) const
{
gp_XYZ aCDG;
if (theDetectedIndex == -1)
{
aCDG = myCenter3D;
}
else
{
aCDG += mypolyg.Pnt (theDetectedIndex);
aCDG += mypolyg.Pnt (theDetectedIndex + 1);
aCDG += mypolyg.Pnt (theDetectedIndex + 2);
aCDG /= 3.;
}
return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
}
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected(const TopLoc_Location& theLocation)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected()
{
Standard_Boolean isFilled = mySensType == Select3D_TOS_INTERIOR;
// Create a copy of this
Handle(Select3D_SensitiveEntity) aNewEntity;
// this was constructed using Handle(Geom_Circle)
if(!myCircle.IsNull())
{
if((myend-mystart) > Precision::Confusion())
if ((myEnd - myStart) > Precision::Confusion())
{
// Arc
aNewEntity = new Select3D_SensitiveCircle(myOwnerId, myCircle, mystart, myend, myFillStatus);
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, myStart, myEnd, isFilled);
}
else
{
// Circle
aNewEntity = new Select3D_SensitiveCircle(myOwnerId, myCircle, myFillStatus);
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, isFilled);
}
}
// this was constructed using TColgp_Array1OfPnt
else
{
Standard_Integer aSize = mypolyg.Size();
TColgp_Array1OfPnt aPolyg(1, aSize);
Standard_Integer aSize = myPolyg.Size();
TColgp_Array1OfPnt aPolyg (1, aSize);
for(Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
{
aPolyg.SetValue(anIndex, mypolyg.Pnt(anIndex-1));
aPolyg.SetValue(anIndex, myPolyg.Pnt (anIndex-1));
}
aNewEntity = new Select3D_SensitiveCircle(myOwnerId, aPolyg, myFillStatus);
aNewEntity = new Select3D_SensitiveCircle (myOwnerId, aPolyg, isFilled);
}
if(HasLocation())
aNewEntity->SetLocation(Location());
aNewEntity->UpdateLocation(theLocation);
return aNewEntity;
}
//=======================================================================
//function : Project
//function : computeCenter3D
//purpose :
//=======================================================================
void Select3D_SensitiveCircle::Project(const Handle(Select3D_Projector) &aProjector)
{
Select3D_SensitivePoly::Project(aProjector);
gp_Pnt2d aCenter;
aProjector->Project(myCenter3D, aCenter);
myCenter2D = aCenter;
}
//=======================================================================
//function : ComputeCenter3D
//purpose :
//=======================================================================
void Select3D_SensitiveCircle::ComputeCenter3D()
void Select3D_SensitiveCircle::computeCenter3D()
{
gp_XYZ aCenter;
Standard_Integer nbpoints = mypolyg.Size();
if (nbpoints != 1)
Standard_Integer aNbPnts = myPolyg.Size();
if (aNbPnts != 1)
{
// The mass of points system
Standard_Integer aMass = nbpoints - 1;
Standard_Integer aMass = aNbPnts - 1;
// Find the circle barycenter
for (Standard_Integer anIndex = 0; anIndex < nbpoints-1; ++anIndex)
for (Standard_Integer anIndex = 0; anIndex < aNbPnts - 1; ++anIndex)
{
aCenter += mypolyg.Pnt(anIndex);
aCenter += myPolyg.Pnt(anIndex);
}
myCenter3D = aCenter / aMass;
}
else
{
myCenter3D = mypolyg.Pnt(0);
myCenter3D = myPolyg.Pnt(0);
}
}
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of the circle. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_SensitiveCircle::CenterOfGeometry() const
{
return myCenter3D;
}

View File

@@ -0,0 +1,124 @@
// Created on: 1996-02-06
// Created by: Robert COUBLANC
// Copyright (c) 1996-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.
// Modified Tue Apr 14 1998 by rob : fix Bug : Case of Null Radius Circle...
#ifndef _Select3D_SensitiveCircle_HeaderFile
#define _Select3D_SensitiveCircle_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Select3D_SensitivePoly.hxx>
#include <Select3D_Pnt.hxx>
#include <Handle_Geom_Circle.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Handle_TColgp_HArray1OfPnt.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Select3D_TypeOfSensitivity.hxx>
class Geom_Circle;
class Standard_ConstructionError;
class Standard_OutOfRange;
class SelectBasics_EntityOwner;
class TColgp_HArray1OfPnt;
class TColgp_Array1OfPnt;
class gp_Pnt;
class TopLoc_Location;
//! A framework to define sensitive 3D arcs and circles.
//! In some cases this class can raise Standard_ConstructionError and
//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
class Select3D_SensitiveCircle : public Select3D_SensitivePoly
{
public:
//! Constructs the sensitive circle object defined by the
//! owner theOwnerId, the circle theCircle, the boolean
//! theIsFilled and the number of points theNbPnts.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Geom_Circle)& theCircle,
const Standard_Boolean theIsFilled = Standard_False,
const Standard_Integer theNbPnts = 12);
//! Constructs the sensitive arc object defined by the
//! owner theOwnerId, the circle theCircle, the parameters theU1
//! and theU2, the boolean theIsFilled and the number of points theNbPnts.
//! theU1 and theU2 define the first and last points of the arc on theCircle.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Geom_Circle)& theCircle,
const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Boolean theIsFilled = Standard_False,
const Standard_Integer theNbPnts = 12);
//! Constructs the sensitive circle object defined by the
//! owner theOwnerId, the array of triangles thePnts3d, and the boolean theIsFilled.
//! thePnts3d is an array of consecutive triangles on the
//! circle. The triangle i+1 lies on the intersection of the
//! tangents to the circle of i and i+2. Note, that the first point of thePnts3d
//! must be equal to the last point of thePnts3d.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePnts3d,
const Standard_Boolean theIsFilled = Standard_False);
//! Constructs the sensitive circle object defined by the
//! owner theOwnerId, the array of points thePnts3d, and the boolean theIsFilled.
//! If the length of thePnts3d is more then 1, the first point of thePnts3d
//! must be equal to the last point of thePnts3d.
Standard_EXPORT Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePnts3d,
const Standard_Boolean theIsFilled = Standard_False);
//! Checks whether the circle overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
Standard_EXPORT void ArrayBounds (Standard_Integer & theLow, Standard_Integer & theUp) const;
Standard_EXPORT gp_Pnt GetPoint3d (const Standard_Integer thePntIdx) const;
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Returns center of the circle. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Builds BVH tree for a circle's edge segments if needed
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveCircle)
private:
//! Computes myCenter3D as the barycenter of points from mypolyg3d
void computeCenter3D();
private:
Select3D_TypeOfSensitivity mySensType; //!< True if type of selection is interior, false otherwise
gp_Pnt myCenter3D; //!< Center of a circle
Handle_Geom_Circle myCircle; //!< Points of the circle
Standard_Real myStart; //!< Sensitive arc parameter
Standard_Real myEnd; //!< Sensitive arc parameter
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveCircle, Select3D_SensitivePoly)
#endif // _Select3D_SensitiveCircle_HeaderFile

View File

@@ -1,139 +0,0 @@
-- Created on: 1995-03-10
-- Created by: Mister rmi
-- 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.
-- Modified on july 97 by ROB : Field HArray instead Of ArrayOfPnt3D
-- (connected entities)
class SensitiveCurve from Select3D
inherits SensitivePoly from Select3D
---Purpose: A framework to define a sensitive 3D curve.
-- In some cases this class can raise Standard_ConstructionError and
-- Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
uses
Pnt from gp,
Pnt2d from gp,
Projector from Select3D,
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Curve from Geom,
Array1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
HArray1OfPnt from TColgp,
Box2d from Bnd,
Location from TopLoc,
SensitiveEntity from Select3D,
XYZ from gp
raises
ConstructionError from Standard,
OutOfRange from Standard
is
Create (OwnerId : EntityOwner from SelectBasics;
TheCurve : Curve from Geom;
MaxPoints : Integer = 17)
returns SensitiveCurve;
---Level: Public
---Purpose: Constructs a sensitive curve object defined by the
-- owner OwnerId, the curve TheCurve, and the
-- maximum number of points on the curve: MaxPoints.
Create (OwnerId : EntityOwner from SelectBasics;
ThePoints : HArray1OfPnt from TColgp)
returns SensitiveCurve;
---Level: Public
---Purpose: Constructs a sensitive curve object defined by the
-- owner OwnerId and the set of points ThePoints.
Create (OwnerId : EntityOwner from SelectBasics;
ThePoints : Array1OfPnt from TColgp)
returns SensitiveCurve;
---Level: Public
---Purpose: Creation of Sensitive Curve from Points.
-- Warning : This Method should disappear in the next version...
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is static;
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth (me;
thePickLine : Lin from gp;
theDetectedIndex : Integer from Standard)
returns Real from Standard;
---Level: Public
---Purpose: Compute depth of sensitive circle for the detected sub-part.
-- @param thePickLine [in] the picking line.
-- @param theDetectedIndex [in] index of the detected sub-part.
-- @return depth on the picking line.
GetLastDetected(me) returns Integer from Standard;
---Purpose: Gets index of last detected segment
---C++: inline
---Category: Internal Methods
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
LoadPoints(me:mutable;aCurve:Curve from Geom;NbPoints: Integer) is static private;
GetConnected(me: mutable; theLocation : Location from TopLoc)
returns SensitiveEntity from Select3D
is redefined virtual;
---Level: Public
---Purpose: Returns the copy of this
ComputeDepth(me;
thePickLine : Lin from gp;
theP1 : XYZ from gp;
theP2 : XYZ from gp;
theDepth : out Real from Standard)
---Purpose: Computes the depth by means of intersection of
-- a segment of the curve defined by <theP1, theP2> and
-- the eye-line <thePickLine>.
returns Boolean from Standard
is protected;
fields
mylastseg : Integer from Standard;
myCurve : Curve from Geom;
end SensitiveCurve;

View File

@@ -14,300 +14,126 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitiveCurve.ixx>
#include <SelectBasics_BasicTool.hxx>
#include <gp_Lin2d.hxx>
#include <Select3D_SensitiveCurve.hxx>
#include <Precision.hxx>
#include <ElCLib.hxx>
#include <CSLib_Class2d.hxx>
#include <Extrema_ExtElC.hxx>
#include <TColgp_Array1OfPnt.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveCurve, Select3D_SensitivePoly)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCurve, Select3D_SensitivePoly)
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitiveCurve
::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(Geom_Curve)& C,
const Standard_Integer NbPoints):
Select3D_SensitivePoly(OwnerId, NbPoints),
mylastseg(0),
myCurve(C)
Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Geom_Curve)& theCurve,
const Standard_Integer theNbPnts)
: Select3D_SensitivePoly (theOwnerId, theNbPnts > 2, theNbPnts),
myCurve (theCurve)
{
LoadPoints(C,NbPoints);
loadPoints (theCurve, theNbPnts);
SetSensitivityFactor (3.0);
}
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints)
: Select3D_SensitivePoly (theOwnerId, thePoints, thePoints->Length() > 2)
Select3D_SensitiveCurve
::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(TColgp_HArray1OfPnt)& ThePoints):
Select3D_SensitivePoly(OwnerId, ThePoints),
mylastseg(0)
{
SetSensitivityFactor (3.0);
}
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitiveCurve
::Select3D_SensitiveCurve(const Handle(SelectBasics_EntityOwner)& OwnerId,
const TColgp_Array1OfPnt& ThePoints):
Select3D_SensitivePoly(OwnerId, ThePoints),
mylastseg(0)
Select3D_SensitiveCurve::Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints)
: Select3D_SensitivePoly (theOwnerId, thePoints, thePoints.Length() > 2)
{
SetSensitivityFactor (3.0);
}
//==================================================
// Function: Matches
// Function: loadPoints
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveCurve::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
void Select3D_SensitiveCurve::loadPoints (const Handle(Geom_Curve)& theCurve, const Standard_Integer theNbPnts)
{
Standard_Integer Rank;
TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size());
Points2D(aArrayOf2dPnt);
if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt,
thePickArgs.X(), thePickArgs.Y(),
thePickArgs.Tolerance(),
theMatchDMin,
Rank))
Standard_Real aStep = (theCurve->LastParameter() - theCurve->FirstParameter()) / (theNbPnts - 1);
Standard_Real aParam = theCurve->FirstParameter();
for (Standard_Integer aPntIdx = 0; aPntIdx < myPolyg.Size(); ++aPntIdx)
{
// remember detected segment (for GetLastDetected)
mylastseg = Rank;
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank);
return !thePickArgs.IsClipped (theMatchDepth);
myPolyg.SetPnt (aPntIdx, theCurve->Value (aParam));
aParam += aStep;
}
return Standard_False;
}
//==================================================
// Function: Matches
// Purpose : know if a box touches the projected polygon
// of the Curve.
//==================================================
Standard_Boolean Select3D_SensitiveCurve::
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 anIndex=0; anIndex<mypolyg.Size(); ++anIndex)
{
if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveCurve::
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);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
{
Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
if(RES!=1)
return Standard_False;
}
return Standard_True;
}
//==================================================
// Function: LoadPoints
// Purpose :
//==================================================
void Select3D_SensitiveCurve
::LoadPoints (const Handle(Geom_Curve)& aCurve,const Standard_Integer NbP)
{
/*this method is private and it used only inside of constructor.
That's why check !NbP==mypolyg3d->Length() was removed*/
Standard_Real Step = (aCurve->LastParameter()- aCurve->FirstParameter())/(NbP-1);
Standard_Real Curparam = aCurve->FirstParameter();
for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
{
mypolyg.SetPnt(anIndex, aCurve->Value(Curparam));
Curparam+=Step;
}
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
{
S<<"\tSensitiveCurve 3D :"<<endl;
if (HasLocation())
S<<"\t\tExisting Location"<<endl;
S<<"\t\tNumber Of Points :"<<mypolyg.Size()<<endl;
if(FullDump)
{
Select3D_SensitiveEntity::DumpBox(S,mybox2d);
}
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine,
const Standard_Integer theSegment) const
{
Standard_Real aDepth = Precision::Infinite();
if (theSegment == 0)
{
return aDepth;
}
// In case if theSegment and theSegment + 1 are not valid
// the depth will be infinite
if (theSegment >= mypolyg.Size())
{
return aDepth;
}
gp_XYZ aCDG = mypolyg.Pnt (theSegment);
// Check depth of a line forward within the curve.
if (theSegment + 1 < mypolyg.Size())
{
gp_XYZ aCDG1 = mypolyg.Pnt (theSegment + 1);
if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth))
{
return aDepth;
}
}
// Check depth of a line backward within the curve.
if (theSegment - 1 >= 0)
{
gp_XYZ aCDG1 = mypolyg.Pnt (theSegment - 1);
if (ComputeDepth(thePickLine, aCDG, aCDG1, aDepth))
{
return aDepth;
}
}
// Calculate the depth in the middle point of
// a next (forward) segment of the curve.
if (theSegment + 1 < mypolyg.Size())
{
aCDG += mypolyg.Pnt(theSegment + 1);
aCDG /= 2.;
}
return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
}
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected(const TopLoc_Location &theLocation)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveCurve::GetConnected()
{
// Create a copy of this
Handle(Select3D_SensitiveEntity) aNewEntity;
// this was constructed using Handle(Geom_Curve)
if (!myCurve.IsNull())
{
aNewEntity = new Select3D_SensitiveCurve(myOwnerId, myCurve);
aNewEntity = new Select3D_SensitiveCurve (myOwnerId, myCurve);
}
// this was constructed using TColgp_HArray1OfPnt
else
{
Standard_Integer aSize = mypolyg.Size();
Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt(1, aSize);
Standard_Integer aSize = myPolyg.Size();
Handle(TColgp_HArray1OfPnt) aPoints = new TColgp_HArray1OfPnt (1, aSize);
// Fill the array with points from mypolyg3d
for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
{
aPoints->SetValue(anIndex, mypolyg.Pnt(anIndex-1));
aPoints->SetValue (anIndex, myPolyg.Pnt (anIndex-1));
}
aNewEntity = new Select3D_SensitiveCurve(myOwnerId, aPoints);
aNewEntity = new Select3D_SensitiveCurve (myOwnerId, aPoints);
}
if (HasLocation())
aNewEntity->SetLocation(Location());
aNewEntity->UpdateLocation(theLocation);
return aNewEntity;
}
//=======================================================================
//function : ComputeDepth()
//purpose : Computes the depth by means of intersection of
// a segment of the curve defined by <theP1, theP2> and
// the eye-line <thePickLine>.
// function : Matches
// purpose : Checks whether the curve overlaps current selecting volume
//=======================================================================
Standard_Boolean Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& thePickLine,
const gp_XYZ& theP1,
const gp_XYZ& theP2,
Standard_Real& theDepth) const
Standard_Boolean Select3D_SensitiveCurve::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
// The segment may have null length.
gp_XYZ aVec = theP2 - theP1;
Standard_Real aLength = aVec.Modulus();
if (aLength <= gp::Resolution())
{
theDepth = ElCLib::Parameter(thePickLine, theP1);
return Standard_True;
}
if (myPolyg.Size() > 2)
return Select3D_SensitivePoly::Matches (theMgr, thePickResult);
// Compute an intersection point of the segment-line and the eye-line.
gp_Lin aLine (theP1, aVec);
Extrema_ExtElC anExtrema(aLine, thePickLine, Precision::Angular());
if (anExtrema.IsDone() && !anExtrema.IsParallel() )
const gp_Pnt aPnt1 = myPolyg.Pnt3d (0);
const gp_Pnt aPnt2 = myPolyg.Pnt3d (1);
Standard_Real aDepth = RealLast();
Standard_Boolean isMatched = theMgr.Overlaps (aPnt1, aPnt2, aDepth);
if (isMatched)
{
// Iterator on solutions (intersection points).
for (Standard_Integer i = 1; i <= anExtrema.NbExt(); i++)
Standard_Real aDistToCOG = RealLast();
if (myCOG.X() == RealLast() && myCOG.Y() == RealLast() && myCOG.Z() == RealLast())
{
// Get the intersection point.
Extrema_POnCurv aPointOnLine1, aPointOnLine2;
anExtrema.Points(i, aPointOnLine1, aPointOnLine2);
// Check bounds: the point of intersection should lie within the segment.
if (aPointOnLine1.Parameter() > 0.0 && aPointOnLine1.Parameter() < aLength)
gp_XYZ aCenter (0.0, 0.0, 0.0);
for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx)
{
theDepth = ElCLib::Parameter(thePickLine, aPointOnLine1.Value());
return Standard_True;
aCenter += myPolyg.Pnt (aIdx);
}
myCOG = aCenter / myPolyg.Size();
}
aDistToCOG = theMgr.DistToGeometryCenter (myCOG);
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
return Standard_True;
}
return Standard_False;

View File

@@ -0,0 +1,91 @@
// Created on: 1995-03-13
// 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.
#ifndef _Select3D_SensitiveCurve_HeaderFile
#define _Select3D_SensitiveCurve_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Geom_Curve.hxx>
#include <Handle_Geom_Curve.hxx>
#include <Select3D_SensitivePoly.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Handle_TColgp_HArray1OfPnt.hxx>
#include <Standard_Boolean.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Standard_Real.hxx>
#include <Standard_OStream.hxx>
class Geom_Curve;
class Standard_ConstructionError;
class Standard_OutOfRange;
class SelectBasics_EntityOwner;
class TColgp_HArray1OfPnt;
class TColgp_Array1OfPnt;
class Select3D_SensitiveEntity;
class TopLoc_Location;
//! A framework to define a sensitive 3D curve.
//! In some cases this class can raise Standard_ConstructionError and
//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
class Select3D_SensitiveCurve : public Select3D_SensitivePoly
{
public:
//! Constructs a sensitive curve object defined by the
//! owner theOwnerId, the curve theCurve, and the
//! maximum number of points on the curve: theNbPnts.
Standard_EXPORT Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Geom_Curve)& theCurve,
const Standard_Integer theNbPnts = 17);
//! Constructs a sensitive curve object defined by the
//! owner theOwnerId and the set of points ThePoints.
Standard_EXPORT Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints);
//! Creation of Sensitive Curve from Points.
//! Warning : This Method should disappear in the next version...
Standard_EXPORT Select3D_SensitiveCurve (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints);
//! Checks whether the curve overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns the copy of this
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
public:
DEFINE_STANDARD_RTTI(Select3D_SensitiveCurve)
private:
void loadPoints (const Handle(Geom_Curve)& aCurve,
const Standard_Integer NbPoints);
private:
Handle_Geom_Curve myCurve; //!< Curve points
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveCurve, Select3D_SensitivePoly)
#endif // _Select3D_SensitiveCurve_HeaderFile

View File

@@ -1,15 +0,0 @@
// 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.
inline Standard_Integer Select3D_SensitiveCurve::GetLastDetected() const
{return mylastseg;}

View File

@@ -1,135 +0,0 @@
-- Created on: 1995-01-24
-- Created by: Rob
-- 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.
-- modified by rob jul/ 21/ 97 : inserting locations ...
-- modified by rob jan/ 29/ 98 : Sort by deph-> add a field to be able
-- to compute a depth
-- -> Virtual methods rather than
-- Deferred for Project
-- WARNING : Must be redefined for
-- each kind of sensitive entity
deferred class SensitiveEntity from Select3D inherits
SensitiveEntity from SelectBasics
---Purpose: Abstract framework to define 3D sensitive entities.
-- As the selection process uses the principle of a
-- projection of 3D shapes onto a 2D view where
-- nearness to a rectangle determines whether a shape
-- is picked or not, all 3D shapes need to be converted
-- into 2D ones in order to be selected.
uses
Projector from Select3D,
EntityOwner from SelectBasics,
Location from TopLoc,
Lin from gp,
Box2d from Bnd,
Array1OfPnt2d from TColgp
is
Initialize(OwnerId : EntityOwner from SelectBasics);
NeedsConversion(me) returns Boolean is redefined static;
---Level: Public
---Purpose: Returns true if this framework needs conversion.
---C++: inline
Is3D(me) returns Boolean from Standard is redefined static;
---Purpose: Returns true if this framework provides 3D information.
Project (me:mutable;aProjector : Projector from Select3D) is deferred;
---Level: Public
---Purpose: In classes inheriting this framework, you must
-- redefine this function in order to get a sensitive 2D
-- rectangle from a 3D entity. This rectangle is the
-- sensitive zone which makes the 3D entity selectable.
MaxBoxes(me) returns Integer is redefined virtual;
---Level: Public
---Purpose: Returns the max number of sensitive areas returned
-- by this class is 1 by default.
-- Else on must redefine this method.
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is virtual;
---Purpose: Originally this method intended to return sensitive
-- entity with new location aLocation, but currently sensitive
-- entities do not hold a location, instead HasLocation() and
-- Location() methods call corresponding entity owner's methods.
-- Thus all entities returned by GetConnected() share the same
-- location propagated from corresponding selectable object.
-- You must redefine this function for any type of
-- sensitive entity which can accept another connected
-- sensitive entity.//can be connected to another sensitive entity.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean from Standard is redefined virtual;
---Purpose: Matches the box defined by the coordinates Xmin,
-- Ymin, Xmax, Ymax with the entity found at that point
-- within the tolerance aTol.
-- Xmin, YMin define the minimum point in the lower left
-- hand corner of the box, and XMax, YMax define the
-- maximum point in the upper right hand corner of the box.
-- You must redefine this function for every inheriting entity.
-- You will have to call this framework inside the redefined function.
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean from Standard is redefined virtual;
---Purpose: prevents from hiding virtual methods...
---Category: Location of sensitive entities...
-- Default implementations of HasLocation() and Location() rely on
-- location obtained from the entity owner, to minimize memory usage.
-- SetLocation() and ResetLocation() do nothing by default.
HasLocation(me) returns Boolean from Standard is virtual;
---Purpose: Returns true if this framework has a location defined.
Location(me) returns Location from TopLoc is virtual;
---C++: return const
ResetLocation(me:mutable) is virtual;
---Purpose: sets the location to Identity
SetLocation(me:mutable;aLoc :Location from TopLoc) is virtual;
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is virtual;
---Purpose: 2 options :
-- <FullDump> = False -> general information
-- <FullDump> = True -> whole informtion 3D +2d ...
DumpBox(myclass; S: in out OStream;abox:Box2d from Bnd) ;
UpdateLocation(me:mutable;aLoc:Location from TopLoc);
end SensitiveEntity;

View File

@@ -14,153 +14,60 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitiveEntity.ixx>
#include <Select3D_SensitiveEntity.hxx>
#include <Precision.hxx>
#include <SelectBasics_EntityOwner.hxx>
#include <Select3D_Macro.hxx>
#include <TopLoc_Location.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveEntity, SelectBasics_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveEntity, SelectBasics_SensitiveEntity)
//=======================================================================
//function : Select3D_SensitiveEntity
//purpose :
//=======================================================================
Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& OwnerId):
SelectBasics_SensitiveEntity(OwnerId)
{}
Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& theOwnerId)
: SelectBasics_SensitiveEntity (theOwnerId) {}
//=======================================================================
//function : Matches
//purpose :
// function : Matches
// purpose : Checks whether sensitive overlaps current selecting volume.
// Stores minimum depth, distance to center of geometry and
// closest point detected into thePickResult
//=======================================================================
Standard_Boolean Select3D_SensitiveEntity::Matches(const Standard_Real,
const Standard_Real,
const Standard_Real,
const Standard_Real,
const Standard_Real)
Standard_Boolean Select3D_SensitiveEntity::Matches (SelectBasics_SelectingVolumeManager& /*theMgr*/,
SelectBasics_PickResult& /*thePickResult*/)
{
return Standard_False;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveEntity::Matches(const TColgp_Array1OfPnt2d&,
const Bnd_Box2d&,
const Standard_Real)
{
return Standard_False;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::Dump(Standard_OStream& S, const Standard_Boolean) const
{
S<<"\tSensitive Entity 3D"<<endl;
}
//=======================================================================
//function : DumpBox
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::DumpBox(Standard_OStream& S,const Bnd_Box2d& b2d)
{
if(!b2d.IsVoid())
{
Standard_Real xmin,ymin,xmax,ymax;
b2d.Get(xmin,ymin,xmax,ymax);
S<<"\t\t\tBox2d: PMIN ["<<xmin<<" , "<<ymin<<"]"<<endl;
S<<"\t\t\t PMAX ["<<xmax<<" , "<<ymax<<"]"<<endl;
}
}
//=======================================================================
//function : ResetLocation
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::ResetLocation()
{
}
//=======================================================================
//function : SetLocation
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::SetLocation(const TopLoc_Location&)
{
}
//=======================================================================
//function : UpdateLocation
//purpose :
//=======================================================================
void Select3D_SensitiveEntity::UpdateLocation(const TopLoc_Location& aLoc)
{
if(aLoc.IsIdentity() || aLoc == Location()) return;
if(!HasLocation())
SetLocation(aLoc);
else
{
TopLoc_Location compLoc = aLoc * Location();
SetLocation(compLoc);
}
}
//=======================================================================
//function : Location
//purpose :
//=======================================================================
const TopLoc_Location Select3D_SensitiveEntity::Location() const
{
TopLoc_Location anIdentity;
Handle(SelectBasics_EntityOwner) anOwner = OwnerId();
return anOwner.IsNull() ? anIdentity : anOwner->Location();
}
//=======================================================================
//function : HasLocation
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveEntity::HasLocation() const
{
Handle(SelectBasics_EntityOwner) anOwner = OwnerId();
return (!anOwner.IsNull() && anOwner->HasLocation());
}
//=======================================================================
//function : Is3D
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveEntity::Is3D() const
{return Standard_True;}
//=======================================================================
//function : MaxBoxes
//purpose :
//=======================================================================
Standard_Integer Select3D_SensitiveEntity::MaxBoxes() const
{return 1;}
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected(const TopLoc_Location&)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected()
{
Handle(Select3D_SensitiveEntity) NiouEnt;
return NiouEnt;
Handle(Select3D_SensitiveEntity) aNewEntity;
return aNewEntity;
}
//=======================================================================
// function : BVH
// purpose : Builds BVH tree for a sensitive if needed
//=======================================================================
void Select3D_SensitiveEntity::BVH()
{
return;
}
//=======================================================================
// function : Clear
// purpose : Cleans up resources and memory
//=======================================================================
void Select3D_SensitiveEntity::Clear()
{
Set (NULL);
}

View File

@@ -0,0 +1,92 @@
// Created on: 1995-03-13
// 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.
#ifndef _Select3D_SensitiveEntity_HeaderFile
#define _Select3D_SensitiveEntity_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <SelectBasics_SensitiveEntity.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Standard_Real.hxx>
#include <Standard_OStream.hxx>
#include <TopLoc_Location.hxx>
class Select3D_SensitiveEntity;
class Handle(Select3D_SensitiveEntity);
class SelectBasics_EntityOwner;
//! Abstract framework to define 3D sensitive entities.
//! As the selection process uses the principle of a
//! projection of 3D shapes onto a 2D view where
//! nearness to a rectangle determines whether a shape
//! is picked or not, all 3D shapes need to be converted
//! into 2D ones in order to be selected.
class Select3D_SensitiveEntity : public SelectBasics_SensitiveEntity
{
public:
//! Originally this method intended to return sensitive
//! entity with new location aLocation, but currently sensitive
//! entities do not hold a location, instead HasLocation() and
//! Location() methods call corresponding entity owner's methods.
//! Thus all entities returned by GetConnected() share the same
//! location propagated from corresponding selectable object.
//! You must redefine this function for any type of
//! sensitive entity which can accept another connected
//! sensitive entity.//can be connected to another sensitive entity.
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected();
//! Checks whether sensitive overlaps current selecting volume.
//! Stores minimum depth, distance to center of geometry and
//! closest point detected into thePickResult
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns the number of sub-entities or elements in
//! sensitive entity. Is used to determine if entity is
//! complex and needs to pre-build BVH at the creation of
//! sensitive entity step or is light-weighted so the tree
//! can be build on demand with unnoticeable delay
virtual Standard_Integer NbSubElements() = 0;
//! Returns bounding box of a sensitive with transformation applied
virtual Select3D_BndBox3d BoundingBox() = 0;
//! Returns center of a sensitive with transformation applied
virtual gp_Pnt CenterOfGeometry() const = 0;
//! Builds BVH tree for a sensitive if needed
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
//! Clears up all resources and memory
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveEntity)
protected:
Standard_EXPORT Select3D_SensitiveEntity (const Handle(SelectBasics_EntityOwner)& theOwnerId);
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveEntity, SelectBasics_SensitiveEntity)
#endif // _Select3D_SensitiveEntity_HeaderFile

View File

@@ -1,118 +0,0 @@
-- Created on: 1995-03-24
-- 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.
class SensitiveFace from Select3D
inherits SensitivePoly from Select3D
---Purpose: Sensitive Entity to make a face selectable.
-- In some cases this class can raise Standard_ConstructionError and
-- Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
uses
EntityOwner from SelectBasics,
Projector from Select3D,
Lin from gp,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt from TColgp,
HArray1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
TypeOfSensitivity from Select3D,
Location from TopLoc,
SensitiveEntity from Select3D
raises
ConstructionError from Standard,
OutOfRange from Standard
is
Create (OwnerId : EntityOwner from SelectBasics;
ThePoints : Array1OfPnt from TColgp;
Sensitivity : TypeOfSensitivity = Select3D_TOS_INTERIOR)
returns SensitiveFace;
---Level: Public
---Purpose: Constructs a sensitive face object defined by the
-- owner OwnerId, the array of points ThePoints, and
-- the sensitivity type Sensitivity.
-- The array of points is the outer polygon of the geometric face.
Create (OwnerId : EntityOwner from SelectBasics;
ThePoints : HArray1OfPnt from TColgp;
Sensitivity : TypeOfSensitivity = Select3D_TOS_INTERIOR)
returns SensitiveFace;
---Level: Public
---Purpose: Constructs a sensitive face object defined by the
-- owner OwnerId, the array of points ThePoints, and
-- the sensitivity type Sensitivity.
-- The array of points is the outer polygon of the geometric face.
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined virtual;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth (me;
thePickLine : Lin from gp;
theDepthMin, theDepthMax : Real from Standard)
returns Real from Standard
is virtual;
---Level: Public
---Purpose: Computes the depth values for all 3D points defining this face and returns
-- the minimal value among them.
-- If the "minimal depth" approach is not suitable and gives wrong detection results
-- in some particular case, a custom sensitive face class can redefine this method.
ComputeDepth(me;EyeLine: Lin from gp)
is private;
---Level: Public
---Purpose: Warning: Obsolete.
-- Use newer version of the method with min, max limits passed as arguments.
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
GetConnected(me: mutable; theLocation : Location from TopLoc)
returns SensitiveEntity from Select3D
is redefined virtual;
---Level: Public
---Purpose: Returns the copy of this
fields
mytype : TypeOfSensitivity;
end SensitiveFace;

View File

@@ -18,261 +18,124 @@
// pour teste si on est dedans ou dehors...
//Modif on jul-21-97 : changement en harray1 pour eventuelles connexions ...
#include <Select3D_SensitiveFace.ixx>
#include <Select3D_Projector.hxx>
#include <SelectBasics_BasicTool.hxx>
#include <gp_Pnt2d.hxx>
#include <Select3D_SensitiveFace.hxx>
#include <gp_Pnt.hxx>
#include <Precision.hxx>
#include <ElCLib.hxx>
#include <CSLib_Class2d.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveFace, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveFace, Select3D_SensitiveEntity)
//==================================================
// 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 TColgp_Array1OfPnt& ThePoints,
const Select3D_TypeOfSensitivity aType):
Select3D_SensitivePoly(OwnerId, ThePoints),
mytype (aType)
Select3D_SensitiveFace::Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints,
const Select3D_TypeOfSensitivity theType)
: Select3D_SensitiveEntity (theOwnerId),
mySensType (theType)
{
if (mySensType == Select3D_TOS_INTERIOR)
{
myFacePoints = new Select3D_InteriorSensitivePointSet (theOwnerId, thePoints);
}
else
{
myFacePoints = new Select3D_BoundarySensitivePointSet (theOwnerId, thePoints);
}
}
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitiveFace::
Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(TColgp_HArray1OfPnt)& ThePoints,
const Select3D_TypeOfSensitivity aType):
Select3D_SensitivePoly(OwnerId, ThePoints),
mytype (aType)
Select3D_SensitiveFace::Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints,
const Select3D_TypeOfSensitivity theType)
: Select3D_SensitiveEntity (theOwnerId),
mySensType (theType)
{
}
//==================================================
// Function: Matches
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveFace::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
Standard_Real DMin2 = 0.;
Standard_Real Xmin = 0.,Ymin = 0.,Xmax = 0.,Ymax = 0.;
if(!Bnd_Box2d(mybox2d).IsVoid())
if (mySensType == Select3D_TOS_INTERIOR)
{
Bnd_Box2d(mybox2d).Get(Xmin,Ymin,Xmax,Ymax);
DMin2 = gp_XY(Xmax-Xmin,Ymax-Ymin).SquareModulus();
myFacePoints = new Select3D_InteriorSensitivePointSet (theOwnerId, thePoints);
}
// calculation of a criterion of minimum distance...
// from start Dmin = size of the bounding box 2D,
// then min. distance of the polyhedron or cdg...
Standard_Real aTol2 = thePickArgs.Tolerance() * thePickArgs.Tolerance();
Standard_Integer aSize = mypolyg.Size(), anIndex;
gp_XY CDG;
for(anIndex=0;anIndex<aSize;++anIndex)
else
{
CDG+=mypolyg.Pnt2d(anIndex);
}
if(aSize>1)
{
CDG/=(aSize-1);
}
DMin2 = Min (DMin2, gp_XY (CDG.X() - thePickArgs.X(), CDG.Y() - thePickArgs.Y()).SquareModulus());
theMatchDMin = Sqrt(DMin2);
Standard_Boolean isplane2d(Standard_True);
for(anIndex=1;anIndex<aSize;++anIndex)
{
gp_XY V1(mypolyg.Pnt2d(anIndex)),V(thePickArgs.X(), thePickArgs.Y());
V1-=mypolyg.Pnt2d(anIndex-1);
V-=mypolyg.Pnt2d(anIndex-1);
Standard_Real Vector = V1^V;
Standard_Real V1V1 = V1.SquareModulus();
DMin2 =
(V1V1 <=aTol2) ?
Min(DMin2,V.SquareModulus()): // if the segment is too small...
Min(DMin2,Vector*Vector/V1V1);
//cdg ...
gp_XY PlaneTest(CDG);
PlaneTest-=mypolyg.Pnt2d(anIndex-1);
Standard_Real valtst = PlaneTest^V1;
if(isplane2d && Abs(valtst) > thePickArgs.Tolerance()) isplane2d=Standard_False;
}
if (isplane2d)
{
theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
thePickArgs.DepthMin(),
thePickArgs.DepthMax());
return !thePickArgs.IsClipped (theMatchDepth);
}
//otherwise it is checked if the point is in the face...
TColgp_Array1OfPnt2d aArrayOf2dPnt(1, aSize);
Points2D(aArrayOf2dPnt);
CSLib_Class2d TheInOutTool (aArrayOf2dPnt,
thePickArgs.Tolerance(),
thePickArgs.Tolerance(),
Xmin, Ymin, Xmax, Ymax);
Standard_Integer TheStat = TheInOutTool.SiDans (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()));
Standard_Boolean res(Standard_False);
switch(TheStat)
{
case 0:
res = Standard_True;
case 1:
{
if(mytype!=Select3D_TOS_BOUNDARY)
res = Standard_True;
}
}
if (res)
{
theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
thePickArgs.DepthMin(),
thePickArgs.DepthMax());
return !thePickArgs.IsClipped (theMatchDepth);
}
return Standard_False;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
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 anIndex=0;anIndex<mypolyg.Size();++anIndex)
{
if(BoundBox.IsOut(mypolyg.Pnt2d(anIndex)))
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
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);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
gp_Pnt2d aPnt2d;
for(Standard_Integer anIndex=0;anIndex<mypolyg.Size();++anIndex)
{
Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
if(RES!=1)
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean FullDump) 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 :"<<mypolyg.Size()<<endl;
Select3D_SensitiveEntity::DumpBox(S,mybox2d);
myFacePoints = new Select3D_BoundarySensitivePointSet (theOwnerId, thePoints);
}
}
//=======================================================================
//function : ComputeDepth
//purpose :
// function : GetPoints
// purpose : Initializes the given array theHArrayOfPnt by 3d
// coordinates of vertices of the face
//=======================================================================
Standard_Real Select3D_SensitiveFace::ComputeDepth (const gp_Lin& thePickLine,
const Standard_Real theDepthMin,
const Standard_Real theDepthMax) const
void Select3D_SensitiveFace::GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt)
{
Standard_Real aDepth = Precision::Infinite();
Standard_Real aPointDepth;
for (Standard_Integer anIndex = 0; anIndex < mypolyg.Size()-1; ++anIndex)
{
aPointDepth = ElCLib::Parameter (thePickLine, mypolyg.Pnt(anIndex));
if (aPointDepth < aDepth && (aPointDepth > theDepthMin) && (aPointDepth < theDepthMax))
{
aDepth = aPointDepth;
}
}
return aDepth;
myFacePoints->GetPoints (theHArrayOfPnt);
}
//=======================================================================
//function : ComputeDepth
//purpose :
// function : BVH
// purpose : Builds BVH tree for the face
//=======================================================================
void Select3D_SensitiveFace::ComputeDepth(const gp_Lin& /*theEyeLine*/) const
void Select3D_SensitiveFace::BVH()
{
// this method is obsolete.
myFacePoints->BVH();
}
//=======================================================================
// 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 : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected(const TopLoc_Location &theLocation)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveFace::GetConnected()
{
// Create a copy of this
Standard_Integer aSize = mypolyg.Size();
TColgp_Array1OfPnt aPoints(1, aSize);
for (Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex)
{
aPoints.SetValue(anIndex, mypolyg.Pnt(anIndex-1));
}
Handle(TColgp_HArray1OfPnt) aPoints;
myFacePoints->GetPoints (aPoints);
Handle(Select3D_SensitiveEntity) aNewEntity =
new Select3D_SensitiveFace(myOwnerId, aPoints, mytype);
if (HasLocation())
aNewEntity->SetLocation(Location());
aNewEntity->UpdateLocation(theLocation);
new Select3D_SensitiveFace (myOwnerId, aPoints, mySensType);
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 : CenterOfGeometry
// purpose : Returns center of the face. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_SensitiveFace::CenterOfGeometry() const
{
return myFacePoints->CenterOfGeometry();
}
//=======================================================================
// function : NbSubElements
// purpose : Returns the amount of sub-entities (points or planar convex
// polygons)
//=======================================================================
Standard_Integer Select3D_SensitiveFace::NbSubElements()
{
return myFacePoints->NbSubElements();
}

View File

@@ -0,0 +1,108 @@
// 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.
//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 ...
#ifndef _Select3D_SensitiveFace_HeaderFile
#define _Select3D_SensitiveFace_HeaderFile
#include <NCollection_Handle.hxx>
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Select3D_TypeOfSensitivity.hxx>
#include <Select3D_SensitivePoly.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Handle_TColgp_HArray1OfPnt.hxx>
#include <Standard_Boolean.hxx>
#include <SelectBasics_SelectingVolumeManager.hxx>
#include <Standard_Real.hxx>
#include <Standard_OStream.hxx>
#include <Select3D_ISensitivePointSet.hxx>
#include <Select3D_BoundarySensitivePointSet.hxx>
#include <Select3D_InteriorSensitivePointSet.hxx>
class Standard_ConstructionError;
class Standard_OutOfRange;
class SelectBasics_EntityOwner;
class TColgp_Array1OfPnt;
class TColgp_HArray1OfPnt;
class TopLoc_Location;
//! Sensitive Entity to make a face selectable.
//! In some cases this class can raise Standard_ConstructionError and
//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
class Select3D_SensitiveFace : public Select3D_SensitiveEntity
{
public:
//! Constructs a sensitive face object defined by the
//! owner theOwnerId, the array of points thePoints, and
//! the sensitivity type theType.
//! The array of points is the outer polygon of the geometric face.
Standard_EXPORT Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints,
const Select3D_TypeOfSensitivity theType = Select3D_TOS_INTERIOR);
//! Constructs a sensitive face object defined by the
//! owner theOwnerId, the array of points thePoints, and
//! the sensitivity type theType.
//! The array of points is the outer polygon of the geometric face.
Standard_EXPORT Select3D_SensitiveFace (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints,
const Select3D_TypeOfSensitivity theType = Select3D_TOS_INTERIOR);
//! Initializes the given array theHArrayOfPnt by 3d
//! coordinates of vertices of the face
Standard_EXPORT void GetPoints (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt);
//! Checks whether the face overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Returns bounding box of the face. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of the face. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Builds BVH tree for the face
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
//! Returns the amount of sub-entities (points or planar convex polygons)
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveFace)
private:
Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: interior or boundary
NCollection_Handle<Select3D_ISensitivePointSet> myFacePoints; //!< Wrapper for overlap detection created depending on sensitivity type
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveFace, Select3D_SensitiveEntity)
#endif // _Select3D_SensitiveFace_HeaderFile

View File

@@ -1,150 +0,0 @@
-- Created on: 1998-04-16
-- Created by: Robert COUBLANC
-- Copyright (c) 1998-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.
class SensitiveGroup from Select3D inherits SensitiveEntity from Select3D
---Purpose: A framework to define selection of a sensitive group
-- by a sensitive entity which is a set of 3D sensitive entities.
-- Remark: 2 modes are possible for rectangle selection
-- the group is considered selected
-- 1) when all the entities inside are selected in the rectangle
-- 2) only one entity inside is selected by the rectangle
-- By default the "Match All entities" mode is set.
uses
Pnt from gp,
Projector from Select3D,
Lin from gp,
EntityOwner from SelectBasics,
SensitiveEntity from Select3D,
ListOfSensitive from Select3D,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
Location from TopLoc
is
Create (OwnerId : EntityOwner from SelectBasics;
MatchAll : Boolean from Standard = Standard_True)
returns SensitiveGroup from Select3D;
---Purpose: Constructs an empty sensitive group object.
-- This is a set of sensitive 3D entities. The sensitive
-- entities will be defined using the function Add to fill
-- the entity owner OwnerId. If MatchAll is false, nothing can be added.
Create(OwnerId : EntityOwner from SelectBasics;
TheList : in out ListOfSensitive from Select3D;
MatchAll : Boolean from Standard = Standard_True)
returns SensitiveGroup from Select3D;
---Purpose: Constructs a sensitive group object defined by the list
-- TheList and the entity owner OwnerId. If MatchAll is false, nothing is done.
Add (me :mutable; LL: in out ListOfSensitive from Select3D);
---Purpose: Adds the list of sensitive entities LL to the empty
-- sensitive group object created at construction time.
Add (me :mutable;aSensitive : SensitiveEntity from Select3D);
---Purpose: Adds the sensitive entity aSensitive to the non-empty
-- sensitive group object created at construction time.
Remove(me:mutable; aSensitive :SensitiveEntity from Select3D);
Clear(me:mutable) ;
---Purpose: Removes all sensitive entities from the list used at the
-- time of construction, or added using the function Add.
IsIn(me;aSensitive: SensitiveEntity from Select3D)
returns Boolean from Standard;
---Purpose: Returns true if the sensitive entity aSensitive is in
-- the list used at the time of construction, or added using the function Add.
Set(me:mutable; MustMatchAllEntities: Boolean from Standard);
---Purpose: Sets the requirement that all sensitive entities in the
-- list used at the time of construction, or added using
-- the function Add must be matched.
---C++: inline
MustMatchAll(me) returns Boolean from Standard;
---Purpose: Returns true if all sensitive entities in the list used
-- at the time of construction, or added using the function Add must be matched.
---C++: inline
Project (me:mutable;aProjector : Projector from Select3D)
is redefined static;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics)
is redefined static;
---Level: Public
---Purpose: gives the 2D boxes which represent the segment in the
-- selection process...
MaxBoxes(me) returns Integer from Standard is redefined static;
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
SetLocation(me:mutable;aLoc:Location from TopLoc) is redefined static;
---Purpose: propagation of location on all the sensitive inside...
ResetLocation(me:mutable) is redefined static;
---Purpose: propagation of location on all the sensitive inside...
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is static;
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static;
---Purpose: Sets the owner for all entities in group
GetEntities(me)
returns ListOfSensitive from Select3D;
---Purpose: Gets group content
---C++: inline
---C++: return const&
fields
myList : ListOfSensitive from Select3D;
myMustMatchAll : Boolean from Standard;
end SensitiveGroup;

View File

@@ -14,84 +14,129 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitiveGroup.ixx>
#include <Select3D_ListIteratorOfListOfSensitive.hxx>
#include <Precision.hxx>
#include <Select3D_SensitiveGroup.hxx>
#include <TopLoc_Location.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveGroup, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveGroup, Select3D_SensitiveEntity)
//=======================================================================
//function : Creation
//purpose :
//purpose :
//=======================================================================
Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Standard_Boolean MatchAll):
Select3D_SensitiveEntity(OwnerId),
myMustMatchAll(MatchAll)
{
}
Select3D_SensitiveGroup::Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Standard_Boolean theIsMustMatchAll)
: Select3D_SensitiveSet (theOwnerId),
myMustMatchAll (theIsMustMatchAll),
myCenter (0.0, 0.0, 0.0) {}
//=======================================================================
//function : Creation
//purpose :
//purpose :
//=======================================================================
Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
Select3D_ListOfSensitive& TheList,
const Standard_Boolean MatchAll):
Select3D_SensitiveEntity(OwnerId),
myMustMatchAll(MatchAll)
Select3D_SensitiveGroup::Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId,
Select3D_EntitySequence& theEntities,
const Standard_Boolean theIsMustMatchAll)
: Select3D_SensitiveSet (theOwnerId),
myMustMatchAll (theIsMustMatchAll)
{
myList.Append(TheList);
}
myCenter = gp_Pnt (0.0, 0.0, 0.0);
//=======================================================================
//function : Add
//purpose : No control of entities inside
//=======================================================================
void Select3D_SensitiveGroup::Add(Select3D_ListOfSensitive& LL)
{myList.Append(LL);}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::Add(const Handle(Select3D_SensitiveEntity)& aSensitive)
{
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next())
{
if(It.Value()==aSensitive) return;
const Handle(Select3D_SensitiveEntity)& anEntity = anIter.Value();
myEntities.Append (anEntity);
myBndBox.Combine (anEntity->BoundingBox());
myBVHPrimIndexes.Append (myEntities.Size());
myCenter.ChangeCoord() += anEntity->CenterOfGeometry().XYZ();
}
myCenter.ChangeCoord().Divide (static_cast<Standard_Real> (myEntities.Size()));
MarkDirty();
}
//=======================================================================
//function : Add
//purpose : No control of entities inside
//=======================================================================
void Select3D_SensitiveGroup::Add (Select3D_EntitySequence& theEntities)
{
gp_Pnt aCent (0.0, 0.0, 0.0);
for (Select3D_EntitySequenceIter anIter (theEntities); anIter.More(); anIter.Next())
{
myEntities.Append (anIter.Value());
myBndBox.Combine (anIter.Value()->BoundingBox());
myBVHPrimIndexes.Append (myEntities.Size());
aCent.ChangeCoord() += anIter.Value()->CenterOfGeometry().XYZ();
}
aCent.ChangeCoord().Divide (myEntities.Length());
myCenter = (myCenter.XYZ() + aCent.XYZ()).Multiplied (0.5);
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::Add (const Handle(Select3D_SensitiveEntity)& theSensitive)
{
for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next())
{
if (anIter.Value() == theSensitive)
return;
}
myEntities.Append (theSensitive);
myBVHPrimIndexes.Append (myEntities.Size());
myBndBox.Combine (theSensitive->BoundingBox());
myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ();
if (myEntities.First() != myEntities.Last())
{
myCenter.ChangeCoord().Multiply (0.5);
}
myList.Append(aSensitive);
}
//=======================================================================
//function : Remove
//purpose :
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::Remove(const Handle(Select3D_SensitiveEntity)& aSensitive)
void Select3D_SensitiveGroup::Remove (const Handle(Select3D_SensitiveEntity)& theSensitive)
{
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
Standard_Boolean isSensitiveRemoved = Standard_False;
for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next())
{
if(It.Value()==aSensitive)
if (anIter.Value() == theSensitive)
{
myList.Remove(It);
return;
myEntities.Remove (anIter);
isSensitiveRemoved = Standard_True;
break;
}
}
if (isSensitiveRemoved)
{
myBndBox.Clear();
myCenter = gp_Pnt (0.0, 0.0, 0.0);
myBVHPrimIndexes.Clear();
for (Standard_Integer anIdx = 1; anIdx <= myEntities.Size(); ++anIdx)
{
myBndBox.Combine (myEntities.Value (anIdx)->BoundingBox());
myCenter.ChangeCoord() += myEntities.Value (anIdx)->CenterOfGeometry().XYZ();
myBVHPrimIndexes.Append (anIdx);
}
myCenter.ChangeCoord().Divide (static_cast<Standard_Real> (myEntities.Size()));
}
}
//=======================================================================
//function : IsIn
//purpose :
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveGroup::IsIn(const Handle(Select3D_SensitiveEntity)& aSensitive) const
Standard_Boolean Select3D_SensitiveGroup::IsIn (const Handle(Select3D_SensitiveEntity)& theSensitive) const
{
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
for(Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next())
{
if(It.Value()==aSensitive)
if (anIter.Value() == theSensitive)
return Standard_True;
}
return Standard_False;
@@ -99,224 +144,192 @@ Standard_Boolean Select3D_SensitiveGroup::IsIn(const Handle(Select3D_SensitiveEn
//=======================================================================
//function : Clear
//purpose :
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::Clear()
{myList.Clear();}
//=======================================================================
//function : Project
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::Project(const Handle(Select3D_Projector)& aProjector)
{
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
It.Value()->Project(aProjector);
}
myEntities.Clear();
myBndBox.Clear();
myCenter = gp_Pnt (0.0, 0.0, 0.0);
myEntities.Clear();
}
//=======================================================================
//function : Areas
//purpose :
// function : NbSubElements
// purpose : Returns the amount of sub-entities
//=======================================================================
void Select3D_SensitiveGroup::Areas(SelectBasics_ListOfBox2d& boxes)
Standard_Integer Select3D_SensitiveGroup::NbSubElements()
{
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
It.Value()->Areas(boxes);
}
return myEntities.Size();
}
//=======================================================================
//function : GetConnected
//purpose :
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected(const TopLoc_Location& aLocation)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveGroup::GetConnected()
{
Handle(Select3D_SensitiveGroup) newgroup = new Select3D_SensitiveGroup(myOwnerId,myMustMatchAll);
Select3D_ListOfSensitive LL;
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
Handle(Select3D_SensitiveGroup) aNewEntity = new Select3D_SensitiveGroup (myOwnerId, myMustMatchAll);
Select3D_EntitySequence aConnectedEnt;
for (Select3D_EntitySequenceIter It (myEntities); It.More(); It.Next())
{
LL.Append(It.Value()->GetConnected(aLocation));
aConnectedEnt.Append (It.Value()->GetConnected());
}
newgroup->Add(LL);
return newgroup;
}
//=======================================================================
//function : SetLocation
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::SetLocation(const TopLoc_Location& aLoc)
{
if(aLoc.IsIdentity()) return;
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
It.Value()->SetLocation(aLoc);
}
if(HasLocation())
if(aLoc == Location()) return;
Select3D_SensitiveEntity::SetLocation(aLoc);
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
if(It.Value()->HasLocation())
{
if(It.Value()->Location()!=aLoc)
It.Value()->SetLocation(It.Value()->Location()*aLoc);
}
else
It.Value()->SetLocation(aLoc);
}
}
//=======================================================================
//function : ResetLocation
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::ResetLocation()
{
if(!HasLocation()) return;
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
if(It.Value()->HasLocation() && It.Value()->Location()!=Location())
It.Value()->SetLocation(It.Value()->Location()*Location().Inverted());
else
It.Value()->ResetLocation();
}
Select3D_SensitiveEntity::ResetLocation();
aNewEntity->Add (aConnectedEnt);
return aNewEntity;
}
//=======================================================================
//function : Matches
//purpose :
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveGroup::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
Standard_Boolean Select3D_SensitiveGroup::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
theMatchDMin = RealLast();
theMatchDepth = RealLast();
Standard_Real aChildDMin, aChildDepth;
Standard_Boolean isMatched = Standard_False;
if (!myMustMatchAll
|| theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Point)
return Select3D_SensitiveSet::Matches (theMgr, thePickResult);
Select3D_ListIteratorOfListOfSensitive anIt (myList);
for (; anIt.More(); anIt.Next())
Standard_Real aDepth = RealLast();
Standard_Real aDistToCOG = RealLast();
for (Select3D_EntitySequenceIter anIt (myEntities); anIt.More(); anIt.Next())
{
Handle(SelectBasics_SensitiveEntity)& aChild = anIt.Value();
if (!aChild->Matches (thePickArgs, aChildDMin, aChildDepth))
SelectBasics_PickResult aMatchResult;
Handle(SelectBasics_SensitiveEntity)& aChild = anIt.ChangeValue();
if (!aChild->Matches (theMgr, aMatchResult))
{
continue;
aMatchResult = SelectBasics_PickResult (RealLast(), RealLast());
return Standard_False;
}
if (!isMatched)
{
theMatchDMin = aChildDMin;
isMatched = Standard_True;
}
theMatchDepth = Min (aChildDepth, theMatchDepth);
aDepth = Min (aMatchResult.Depth(), aDepth);
}
return isMatched;
}
aDistToCOG = theMgr.DistToGeometryCenter (CenterOfGeometry());
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
//=======================================================================
//function : Matches
//purpose : si on doit tout matcher, on ne repond oui que si toutes
// les primitives repondent oui
//=======================================================================
Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real aTol)
{
Standard_Boolean result(Standard_True);
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
if(It.Value()->Matches(XMin,YMin,XMax,YMax,aTol))
{
if(!myMustMatchAll)
return Standard_True;
}
// ca ne matches pas..
else
{
if(myMustMatchAll)
return Standard_False;
else
result = Standard_False;
}
}
return result;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveGroup::
Matches (const TColgp_Array1OfPnt2d& aPoly,
const Bnd_Box2d& aBox,
const Standard_Real aTol)
{
Standard_Boolean result(Standard_True);
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
{
if(It.Value()->Matches(aPoly, aBox, aTol))
{
if(!myMustMatchAll)
return Standard_True;
}
else
{
if(myMustMatchAll)
return Standard_False;
else
result = Standard_False;
}
}
return result;
}
//=======================================================================
//function : MaxBoxes
//purpose :
//=======================================================================
Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const
{
Standard_Integer nbboxes(0);
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
nbboxes+=It.Value()->MaxBoxes();
}
return nbboxes;
return Standard_True;
}
//=======================================================================
//function : Set
//purpose :
//purpose :
//=======================================================================
void Select3D_SensitiveGroup::Set
(const Handle(SelectBasics_EntityOwner)& TheOwnerId)
void Select3D_SensitiveGroup::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId)
{
Select3D_SensitiveEntity::Set(TheOwnerId);
Select3D_SensitiveEntity::Set (theOwnerId);
// set TheOwnerId for each element of sensitive group
for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
It.Value()->Set(TheOwnerId);
for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next())
anIter.Value()->Set (theOwnerId);
}
//=======================================================================
// function : BoundingBox
// purpose : Returns bounding box of the group. If location
// transformation is set, it will be applied
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveGroup::BoundingBox()
{
if (myBndBox.IsValid())
return myBndBox;
// do not apply the transformation because sensitives AABBs
// are already transformed
for (Select3D_EntitySequenceIter anIter (myEntities); anIter.More(); anIter.Next())
{
myBndBox.Combine (anIter.Value()->BoundingBox());
}
return myBndBox;
}
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of group. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_SensitiveGroup::CenterOfGeometry() const
{
return myCenter;
}
//=======================================================================
// function : Box
// purpose : Returns bounding box of sensitive entity with index theIdx
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveGroup::Box (const Standard_Integer theIdx) const
{
const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx);
return myEntities.Value (anElemIdx)->BoundingBox();
}
//=======================================================================
// function : Center
// purpose : Returns geometry center of sensitive entity with index
// theIdx in the vector along the given axis theAxis
//=======================================================================
Standard_Real Select3D_SensitiveGroup::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
{
const Standard_Integer anElemIdx = myBVHPrimIndexes.Value (theIdx);
const gp_Pnt aCenter = myEntities.Value (anElemIdx)->CenterOfGeometry();
return theAxis == 0 ? aCenter.X() : (theAxis == 1 ? aCenter.Y() : aCenter.Z());
}
//=======================================================================
// function : Swap
// purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector
//=======================================================================
void Select3D_SensitiveGroup::Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2)
{
const Standard_Integer anEntIdx1 = myBVHPrimIndexes.Value (theIdx1);
const Standard_Integer anEntIdx2 = myBVHPrimIndexes.Value (theIdx2);
myBVHPrimIndexes.ChangeValue (theIdx1) = anEntIdx2;
myBVHPrimIndexes.ChangeValue (theIdx2) = anEntIdx1;
}
//=======================================================================
// function : Size
// purpose : Returns the length of vector of sensitive entities
//=======================================================================
Standard_Integer Select3D_SensitiveGroup::Size() const
{
return myBVHPrimIndexes.Size();
}
// =======================================================================
// function : overlapsElement
// purpose : Checks whether the entity with index theIdx overlaps the
// current selecting volume
// =======================================================================
Standard_Boolean Select3D_SensitiveGroup::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth)
{
theMatchDepth = RealLast();
const Standard_Integer aSensitiveIdx = myBVHPrimIndexes.Value (theElemIdx);
SelectBasics_PickResult aResult;
Standard_Boolean isMatching = myEntities.Value (aSensitiveIdx)->Matches (theMgr, aResult);
if (isMatching)
{
theMatchDepth = aResult.Depth();
return Standard_True;
}
return Standard_False;
}
// =======================================================================
// function : distanceToCOG
// purpose : Calculates distance from the 3d projection of used-picked
// screen point to center of the geometry
// =======================================================================
Standard_Real Select3D_SensitiveGroup::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
{
return theMgr.DistToGeometryCenter (CenterOfGeometry());
}

View File

@@ -0,0 +1,149 @@
// Created on: 1998-04-16
// Created by: Robert COUBLANC
// Copyright (c) 1998-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.
#ifndef _Select3D_SensitiveGroup_HeaderFile
#define _Select3D_SensitiveGroup_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Select3D_EntitySequence.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <Select3D_SensitiveSet.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
class SelectBasics_EntityOwner;
class TopLoc_Location;
//! A framework to define selection of a sensitive group
//! by a sensitive entity which is a set of 3D sensitive entities.
//! Remark: 2 modes are possible for rectangle selection
//! the group is considered selected
//! 1) when all the entities inside are selected in the rectangle
//! 2) only one entity inside is selected by the rectangle
//! By default the "Match All entities" mode is set.
class Select3D_SensitiveGroup : public Select3D_SensitiveSet
{
public:
//! Constructs an empty sensitive group object.
//! This is a set of sensitive 3D entities. The sensitive
//! entities will be defined using the function Add to fill
//! the entity owner OwnerId. If MatchAll is false, nothing can be added.
Standard_EXPORT Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Standard_Boolean theIsMustMatchAll = Standard_True);
//! Constructs a sensitive group object defined by the list
//! TheList and the entity owner OwnerId. If MatchAll is false, nothing is done.
Standard_EXPORT Select3D_SensitiveGroup (const Handle(SelectBasics_EntityOwner)& theOwnerId,
Select3D_EntitySequence& theEntities,
const Standard_Boolean theIsMustMatchAll = Standard_True);
//! Adds the list of sensitive entities LL to the empty
//! sensitive group object created at construction time.
Standard_EXPORT void Add (Select3D_EntitySequence& theEntities);
//! Adds the sensitive entity aSensitive to the non-empty
//! sensitive group object created at construction time.
Standard_EXPORT void Add (const Handle(Select3D_SensitiveEntity)& theSensitive);
Standard_EXPORT void Remove (const Handle(Select3D_SensitiveEntity)& theSensitive);
//! Removes all sensitive entities from the list used at the
//! time of construction, or added using the function Add.
Standard_EXPORT void Clear();
//! Returns true if the sensitive entity aSensitive is in
//! the list used at the time of construction, or added using the function Add.
Standard_EXPORT Standard_Boolean IsIn (const Handle(Select3D_SensitiveEntity)& theSensitive) const;
//! Sets the requirement that all sensitive entities in the
//! list used at the time of construction, or added using
//! the function Add must be matched.
void SetMatchType (const Standard_Boolean theIsMustMatchAll);
//! Returns true if all sensitive entities in the list used
//! at the time of construction, or added using the function Add must be matched.
Standard_Boolean MustMatchAll() const;
//! Checks whether the group overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns the amount of sub-entities
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Sets the owner for all entities in group
Standard_EXPORT void Set (const Handle(SelectBasics_EntityOwner)& theOwnerId);
//! Gets group content
const Select3D_EntitySequence& GetEntities() const;
//! Returns bounding box of the group. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of entity set. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Returns bounding box of sensitive entity with index theIdx
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
//! Returns geometry center of sensitive entity index theIdx in
//! the vector along the given axis theAxis
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIdx1 and theIdx2 in the vector
Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2) Standard_OVERRIDE;
//! Returns the length of vector of sensitive entities
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveGroup)
private:
//! Checks whether the entity with index theIdx overlaps the current selecting volume
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth) Standard_OVERRIDE;
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
private:
Select3D_EntitySequence myEntities; //!< Grouped sensitive entities
Standard_Boolean myMustMatchAll; //!< Determines whether all entities in the group should be overlapped or not
gp_Pnt myCenter; //!< Center of geometry of the group
mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the group
NCollection_Vector<Standard_Integer> myBVHPrimIndexes; //!< Vector of sub-entities indexes for BVH tree build
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveGroup, Select3D_SensitiveEntity)
#include <Select3D_SensitiveGroup.lxx>
#endif // _Select3D_SensitiveGroup_HeaderFile

View File

@@ -14,14 +14,29 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
inline void Select3D_SensitiveGroup::Set(const Standard_Boolean MustMatchAllEntities)
{myMustMatchAll = MustMatchAllEntities;}
//=======================================================================
//function : SetMatchType
//purpose :
//=======================================================================
inline void Select3D_SensitiveGroup::SetMatchType (const Standard_Boolean theIsMustMatchAll)
{
myMustMatchAll = theIsMustMatchAll;
}
inline Standard_Boolean Select3D_SensitiveGroup::MustMatchAll() const
{return myMustMatchAll;}
//=======================================================================
//function : MustMatchAll
//purpose :
//=======================================================================
inline Standard_Boolean Select3D_SensitiveGroup::MustMatchAll() const
{
return myMustMatchAll;
}
inline const Select3D_ListOfSensitive& Select3D_SensitiveGroup::GetEntities() const
{return myList;}
//=======================================================================
//function : GetEntities
//purpose :
//=======================================================================
inline const Select3D_EntitySequence& Select3D_SensitiveGroup::GetEntities() const
{
return myEntities;
}

View File

@@ -1,104 +0,0 @@
-- Created on: 1995-02-23
-- Created by: Mister rmi
-- 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.
class SensitivePoint from Select3D
inherits SensitiveEntity from Select3D
---Purpose: A framework to define sensitive 3D points.
uses
Pnt from gp,
Pnt2d from gp,
Projector from Select3D,
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Location from TopLoc,
Box2d from Bnd,
Array1OfPnt2d from TColgp,
Pnt from Select3D,
Pnt2d from Select3D
is
Create (OwnerId : EntityOwner from SelectBasics;
Point : Pnt from gp)
returns SensitivePoint;
---Purpose: Constructs a sensitive point object defined by the
-- owner OwnerId and the point Point.
Project (me:mutable;aProjector : Projector from Select3D)
is redefined static;
---Level: Public
---Purpose:Converts the stored 3D point into a 2D point according
-- to <aProjector> ; this method is called by the selection Manager.
Areas(me:mutable; aresult : in out ListOfBox2d from SelectBasics)
is redefined static;
---Level: Public
---Purpose: stores in <aresult> the 2D sensitive box which represents
-- the point area in the selection process.
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is static;
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard;
Point(me) returns Pnt from gp;
---Purpose: Returns the point used at the time of construction.
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
fields
mypoint : Pnt from Select3D;
myprojpt : Pnt2d from Select3D;
end SensitivePoint;

View File

@@ -14,166 +14,88 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitivePoint.ixx>
#include <Select3D_SensitivePoint.hxx>
#include <Select3D_Projector.hxx>
#include <Bnd_Box2d.hxx>
#include <ElCLib.hxx>
#include <CSLib_Class2d.hxx>
#include <TopLoc_Location.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitivePoint, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoint, Select3D_SensitiveEntity)
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitivePoint
::Select3D_SensitivePoint(const Handle(SelectBasics_EntityOwner)& anOwner,
const gp_Pnt& aPoint):
Select3D_SensitiveEntity(anOwner)
Select3D_SensitivePoint::Select3D_SensitivePoint (const Handle(SelectBasics_EntityOwner)& theOwner,
const gp_Pnt& thePoint)
: Select3D_SensitiveEntity (theOwner)
{
SetSensitivityFactor(4.);
mypoint = aPoint;
}
//==================================================
// Function: Project
// Purpose :
//==================================================
void Select3D_SensitivePoint
::Project (const Handle(Select3D_Projector)& aProj)
{
gp_Pnt2d aPoint2d;
if(!HasLocation())
aProj->Project(mypoint, aPoint2d);
else
{
gp_Pnt aP(mypoint.x, mypoint.y, mypoint.z);
aProj->Project(aP.Transformed(Location().Transformation()), aPoint2d);
}
myprojpt = aPoint2d;
}
//==================================================
// Function: Areas
// Purpose :
//==================================================
void Select3D_SensitivePoint
::Areas(SelectBasics_ListOfBox2d& boxes)
{
Bnd_Box2d abox;
abox.Set(myprojpt);
boxes.Append(abox);
SetSensitivityFactor (12.0);
myPoint = thePoint;
}
//==================================================
// Function: Matches
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitivePoint::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
Standard_Boolean Select3D_SensitivePoint::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
// check coordinate matching
Standard_Real aDist = gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()).Distance (myprojpt);
if (aDist > thePickArgs.Tolerance() * SensitivityFactor())
{
return Standard_False;
}
Standard_Real aDepth = RealLast();
Standard_Real aDistToCOG = RealLast();
Standard_Boolean isMatched = theMgr.Overlaps (myPoint, aDepth);
if (isMatched)
aDistToCOG = aDepth;
Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
if (thePickArgs.IsClipped (aDepth))
{
return Standard_False;
}
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
theMatchDMin = aDist;
theMatchDepth = aDepth;
return Standard_True;
}
//==================================================
// Function: Matches
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitivePoint::
Matches (const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real aTol)
{
Bnd_Box2d B;
B.Update(Min(XMin,XMax),Min(YMin,YMax),Max(XMin,XMax),Max(YMin,YMax));
B.Enlarge(aTol);
return !B.IsOut(myprojpt);
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitivePoint::
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);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
Standard_Integer RES = aClassifier2d.SiDans(myprojpt);
if(RES==1) return Standard_True;
return Standard_False;
return isMatched;
}
//=======================================================================
//function : Point
//purpose :
//=======================================================================
gp_Pnt Select3D_SensitivePoint::Point() const
{return mypoint;}
{
return myPoint;
}
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitivePoint::GetConnected(const TopLoc_Location& aLoc)
Handle(Select3D_SensitiveEntity) Select3D_SensitivePoint::GetConnected()
{
Handle(Select3D_SensitivePoint) NiouEnt = new Select3D_SensitivePoint(myOwnerId,mypoint);
if(HasLocation()) NiouEnt->SetLocation(Location());
NiouEnt->UpdateLocation(aLoc);
return NiouEnt;
Handle(Select3D_SensitivePoint) aNewEntity = new Select3D_SensitivePoint (myOwnerId, myPoint);
return aNewEntity;
}
//=======================================================================
//function : Dump
//purpose :
// function : CenterOfGeometry
// purpose : Returns center of point. If location transformation
// is set, it will be applied
//=======================================================================
void Select3D_SensitivePoint::Dump(Standard_OStream& S,const Standard_Boolean /*FullDump*/) const
gp_Pnt Select3D_SensitivePoint::CenterOfGeometry() const
{
S<<"\tSensitivePoint 3D :";
if(HasLocation())
S<<"\t\tExisting Location"<<endl;
S<<"\t\t P3d [ "<<mypoint.x<<" , "<<mypoint.y<<" , "<<mypoint.z<<" ]"<<endl;
S<<"\t\t P2d [ "<<myprojpt.x<<" , "<<myprojpt.y<<" ]"<<endl;
return myPoint;
}
//=======================================================================
//function : ComputeDepth
//purpose :
// function : BoundingBox
// purpose : Returns bounding box of the point. If location
// transformation is set, it will be applied
//=======================================================================
Standard_Real Select3D_SensitivePoint::ComputeDepth(const gp_Lin& EyeLine) const
Select3D_BndBox3d Select3D_SensitivePoint::BoundingBox()
{
return ElCLib::Parameter(EyeLine,mypoint);
return Select3D_BndBox3d (SelectMgr_Vec3 (myPoint.X(), myPoint.Y(), myPoint.Z()),
SelectMgr_Vec3 (myPoint.X(), myPoint.Y(), myPoint.Z()));
}
//=======================================================================
// function : NbSubElements
// purpose : Returns the amount of sub-entities in sensitive
//=======================================================================
Standard_Integer Select3D_SensitivePoint::NbSubElements()
{
return 1;
}

View File

@@ -0,0 +1,74 @@
// Created on: 1995-03-10
// Created by: Mister rmi
// 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.
#ifndef _Select3D_SensitivePoint_HeaderFile
#define _Select3D_SensitivePoint_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Select3D_Pnt.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Standard_Boolean.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Standard_Real.hxx>
#include <Standard_OStream.hxx>
class SelectBasics_EntityOwner;
class gp_Pnt;
class TopLoc_Location;
//! A framework to define sensitive 3D points.
class Select3D_SensitivePoint : public Select3D_SensitiveEntity
{
public:
//! Constructs a sensitive point object defined by the
//! owner OwnerId and the point Point.
Standard_EXPORT Select3D_SensitivePoint (const Handle(SelectBasics_EntityOwner)& theOwnerId, const gp_Pnt& thePoint);
//! Returns the amount of sub-entities in sensitive
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Checks whether the point overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns the point used at the time of construction.
Standard_EXPORT gp_Pnt Point() const;
//! Returns center of point. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Returns bounding box of the point. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitivePoint)
private:
gp_Pnt myPoint; //!< 3d coordinates of the point
};
DEFINE_STANDARD_HANDLE(Select3D_SensitivePoint, Select3D_SensitiveEntity)
#endif // _Select3D_SensitivePoint_HeaderFile

View File

@@ -1,86 +0,0 @@
-- 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.
deferred class SensitivePoly from Select3D
inherits SensitiveEntity from Select3D
---Purpose: Sensitive Entity to make a face selectable.
-- In some cases this class can raise Standard_ConstructionError and
-- Standard_OutOfRange exceptions from its member Select3D_PointData
-- mypolyg.
uses
EntityOwner from SelectBasics,
Projector from Select3D,
ListOfBox2d from SelectBasics,
Array1OfPnt from TColgp,
HArray1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
Box2d from Select3D,
PointData from Select3D
raises
ConstructionError from Standard,
OutOfRange from Standard
is
Initialize (OwnerId : EntityOwner from SelectBasics;
ThePoints : Array1OfPnt from TColgp)
returns SensitivePoly;
---Level: Public
---Purpose: Constructs a sensitive face object defined by the
-- owner OwnerId, the array of points ThePoints, and
-- the sensitivity type Sensitivity.
-- The array of points is the outer polygon of the geometric face.
Initialize (OwnerId : EntityOwner from SelectBasics;
ThePoints : HArray1OfPnt from TColgp)
returns SensitivePoly;
---Level: Public
---Purpose: Constructs a sensitive face object defined by the
-- owner OwnerId, the array of points ThePoints, and
-- the sensitivity type Sensitivity.
-- The array of points is the outer polygon of the geometric face.
Initialize(OwnerId : EntityOwner from SelectBasics;
NbOfPoints : Integer = 6)
returns SensitivePoly;
---Level: Public
---Purpose: Constructs the sensitive circle object defined by the
-- owner OwnerId, the circle Circle, the Boolean
-- FilledCircle and the number of points NbOfPoints.
Project (me:mutable;aProjector : Projector from Select3D) is redefined virtual;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) is redefined static;
---Level: Public
---Purpose: stores in <boxes> the 2D Boxes which represent the sensitive face
-- in the selection algorithm.
Points3D(me:mutable; theHArrayOfPnt : in out HArray1OfPnt from TColgp);
---Purpose: Returns the 3D points of the array used at construction time.
---C++: inline
Points2D(me:mutable; theArrayOfPnt2d : in out Array1OfPnt2d from TColgp);
---Purpose: Returns the 2D points of the array used at construction time.
---C++: inline
fields
mybox2d : Box2d from Select3D is protected;
mypolyg : PointData from Select3D is protected;
end SensitivePoly;

View File

@@ -11,93 +11,268 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitivePoly.ixx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <Select3D_Pnt.hxx>
#include <Select3D_Pnt2d.hxx>
#include <Select3D_Box2d.hxx>
#include <TopLoc_Location.hxx>
#include <Select3D_Pnt.hxx>
#include <Select3D_SensitivePoly.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitivePoly, Select3D_SensitiveSet)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoly, Select3D_SensitiveSet)
//==================================================
// Function: faire disparaitre ce constructeur a la prochaine version...
// Purpose : simplement garde pour ne pas perturber la version update
//==================================================
Select3D_SensitivePoly::
Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId,
const TColgp_Array1OfPnt& ThePoints):
Select3D_SensitiveEntity(OwnerId),
mypolyg(ThePoints.Upper()-ThePoints.Lower()+1)
{
for (Standard_Integer theIndex = 0 ; theIndex < mypolyg.Size(); ++theIndex)
mypolyg.SetPnt(theIndex, ThePoints.Value(ThePoints.Lower()+theIndex));
}
//==================================================
// Function: Creation
// Function: Select3D_SensitivePoly
// Purpose :
//==================================================
Select3D_SensitivePoly::
Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(TColgp_HArray1OfPnt)& ThePoints):
Select3D_SensitiveEntity(OwnerId),
mypolyg(ThePoints->Upper()-ThePoints->Lower()+1)
Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints,
const Standard_Boolean theIsBVHEnabled)
: Select3D_SensitiveSet (theOwnerId),
myPolyg (thePoints.Upper() - thePoints.Lower() + 1)
{
for (Standard_Integer theIndex = 0; theIndex < mypolyg.Size(); theIndex++)
mypolyg.SetPnt(theIndex, ThePoints->Value(ThePoints->Lower()+theIndex));
}
Standard_Integer aLowerIdx = thePoints.Lower();
Standard_Integer anUpperIdx = thePoints.Upper();
gp_XYZ aPntSum (0.0, 0.0, 0.0);
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitivePoly::
Select3D_SensitivePoly(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Standard_Integer NbPoints):
Select3D_SensitiveEntity(OwnerId),
mypolyg(NbPoints)
{
}
//==================================================
// Function: Project
// Purpose :
//==================================================
void Select3D_SensitivePoly::Project(const Handle(Select3D_Projector)& aProj)
{
mybox2d.SetVoid();
Standard_Boolean hasloc = HasLocation();
gp_Pnt2d aPnt2d;
gp_Pnt aPnt;
for (Standard_Integer theIndex = 0; theIndex < mypolyg.Size(); ++theIndex)
Select3D_BndBox3d aBndBox;
for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx)
{
aPnt = mypolyg.Pnt(theIndex);
if (hasloc)
aPntSum += thePoints.Value (aIdx).XYZ();
const SelectMgr_Vec3 aPnt (thePoints.Value (aIdx).X(),
thePoints.Value (aIdx).Y(),
thePoints.Value (aIdx).Z());
aBndBox.Add (aPnt);
myPolyg.SetPnt (aIdx - aLowerIdx, thePoints.Value (aIdx));
}
myBndBox = aBndBox;
myCOG = aPntSum / myPolyg.Size();
if (theIsBVHEnabled)
{
const Standard_Integer aPntsNum = myPolyg.Size();
mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2);
for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter)
{
aProj->Project(aPnt.Transformed(Location().Transformation()), aPnt2d);
mySegmentIndexes->SetValue (aSegmIter, aSegmIter);
}
else
{
aProj->Project(aPnt, aPnt2d);
}
mybox2d.Update(aPnt2d);
mypolyg.SetPnt2d(theIndex, aPnt2d);
}
}
//==================================================
// Function: Areas
// Function: Select3D_SensitivePoly
// Purpose :
//==================================================
void Select3D_SensitivePoly
::Areas(SelectBasics_ListOfBox2d& aSeq)
Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints,
const Standard_Boolean theIsBVHEnabled)
: Select3D_SensitiveSet (theOwnerId),
myPolyg (thePoints->Upper() - thePoints->Lower() + 1)
{
aSeq.Append(mybox2d);
Standard_Integer aLowerIdx = thePoints->Lower();
Standard_Integer anUpperIdx = thePoints->Upper();
gp_XYZ aPntSum (0.0, 0.0, 0.0);
Select3D_BndBox3d aBndBox;
for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx)
{
aPntSum += thePoints->Value (aIdx).XYZ();
const SelectMgr_Vec3 aPnt (thePoints->Value (aIdx).X(),
thePoints->Value (aIdx).Y(),
thePoints->Value (aIdx).Z());
aBndBox.Add (aPnt);
myPolyg.SetPnt (aIdx - aLowerIdx, thePoints->Value (aIdx));
}
myBndBox = aBndBox;
myCOG = aPntSum / myPolyg.Size();
if (theIsBVHEnabled)
{
const Standard_Integer aPntsNum = myPolyg.Size();
mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2);
for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter)
{
mySegmentIndexes->SetValue (aSegmIter, aSegmIter);
}
}
}
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Standard_Boolean theIsBVHEnabled,
const Standard_Integer theNbPnts)
: Select3D_SensitiveSet (theOwnerId),
myPolyg (theNbPnts)
{
if (theIsBVHEnabled)
{
mySegmentIndexes = new TColStd_HArray1OfInteger (0, theNbPnts - 2);
for (Standard_Integer aIdx = 0; aIdx < theNbPnts - 1; ++aIdx)
{
mySegmentIndexes->SetValue (aIdx, aIdx);
}
}
myCOG = gp_Pnt (RealLast(), RealLast(), RealLast());
}
//==================================================
// function : BoundingBox
// purpose : Returns bounding box of a polygon. If location
// transformation is set, it will be applied
//==================================================
Select3D_BndBox3d Select3D_SensitivePoly::BoundingBox()
{
if (myBndBox.IsValid())
return myBndBox;
Select3D_BndBox3d aBndBox;
for (Standard_Integer aPntIter = 0; aPntIter < myPolyg.Size(); ++aPntIter)
{
SelectMgr_Vec3 aPnt (myPolyg.Pnt (aPntIter).x,
myPolyg.Pnt (aPntIter).y,
myPolyg.Pnt (aPntIter).z);
aBndBox.Add (aPnt);
}
myBndBox = aBndBox;
return myBndBox;
}
//==================================================
// Function: Size
// Purpose : Returns the amount of segments of
// the poly
//==================================================
Standard_Integer Select3D_SensitivePoly::Size() const
{
if (!mySegmentIndexes.IsNull())
return mySegmentIndexes->Length();
return -1;
}
//==================================================
// Function: Box
// Purpose : Returns bounding box of segment with
// index theIdx
//==================================================
Select3D_BndBox3d Select3D_SensitivePoly::Box (const Standard_Integer theIdx) const
{
if (mySegmentIndexes.IsNull())
return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast()));
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theIdx);
gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx);
gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1);
const SelectMgr_Vec3 aMinPnt (Min (aPnt1.X(), aPnt2.X()),
Min (aPnt1.Y(), aPnt2.Y()),
Min (aPnt1.Z(), aPnt2.Z()));
const SelectMgr_Vec3 aMaxPnt (Max (aPnt1.X(), aPnt2.X()),
Max (aPnt1.Y(), aPnt2.Y()),
Max (aPnt1.Z(), aPnt2.Z()));
return Select3D_BndBox3d (aMinPnt, aMaxPnt);
}
//==================================================
// Function: Center
// Purpose : Returns geometry center of sensitive
// entity index theIdx in the vector along
// the given axis theAxis
//==================================================
Standard_Real Select3D_SensitivePoly::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
{
if (mySegmentIndexes.IsNull())
return RealLast();
const Select3D_BndBox3d aBndBox = Box (theIdx);
const SelectMgr_Vec3& aCenter = (aBndBox.CornerMin() + aBndBox.CornerMax()) * 0.5;
return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
}
//==================================================
// Function: Swap
// Purpose : Swaps items with indexes theIdx1 and
// theIdx2 in the vector
//==================================================
void Select3D_SensitivePoly::Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2)
{
if (mySegmentIndexes.IsNull())
return;
const Standard_Integer aSegmentIdx1 = mySegmentIndexes->Value (theIdx1);
const Standard_Integer aSegmentIdx2 = mySegmentIndexes->Value (theIdx2);
mySegmentIndexes->ChangeValue (theIdx1) = aSegmentIdx2;
mySegmentIndexes->ChangeValue (theIdx2) = aSegmentIdx1;
return;
}
//==================================================
// Function: overlapsElement
// Purpose : Checks whether the segment with index
// theIdx overlaps the current selecting
// volume
//==================================================
Standard_Boolean Select3D_SensitivePoly::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth)
{
if (mySegmentIndexes.IsNull())
return Standard_False;
const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx);
gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx);
gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1);
return theMgr.Overlaps (aPnt1, aPnt2, theMatchDepth);
}
//==================================================
// Function: distanceToCOG
// Purpose : Calculates distance from the 3d
// projection of used-picked screen point
// to center of the geometry
//==================================================
Standard_Real Select3D_SensitivePoly::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
{
if (myCOG.X() == RealLast() && myCOG.Y() == RealLast() && myCOG.Z() == RealLast())
{
gp_XYZ aCenter (0.0, 0.0, 0.0);
for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx)
{
aCenter += myPolyg.Pnt (aIdx);
}
myCOG = aCenter / myPolyg.Size();
}
return theMgr.DistToGeometryCenter (myCOG);
}
//==================================================
// Function: NbSubElements
// Purpose : Returns the amount of segments in poly
//==================================================
Standard_Integer Select3D_SensitivePoly::NbSubElements()
{
return myPolyg.Size();
}
//==================================================
// Function: CenterOfGeometry
// Purpose : Returns center of the point set. If
// location transformation is set, it will
// be applied
//==================================================
gp_Pnt Select3D_SensitivePoly::CenterOfGeometry() const
{
return myCOG;
}

View File

@@ -0,0 +1,125 @@
// 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.
#ifndef _Select3D_SensitivePoly_HeaderFile
#define _Select3D_SensitivePoly_HeaderFile
#include <NCollection_Handle.hxx>
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <Handle_TColgp_HArray1OfPnt.hxx>
#include <Handle_TColStd_HArray1OfInteger.hxx>
#include <Select3D_PointData.hxx>
#include <Select3D_Pnt.hxx>
#include <Select3D_SensitiveSet.hxx>
#include <Select3D_TypeOfSensitivity.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
class Standard_ConstructionError;
class Standard_OutOfRange;
class SelectBasics_EntityOwner;
class TColgp_Array1OfPnt;
class TColgp_HArray1OfPnt;
//! Sensitive Entity to make a face selectable.
//! In some cases this class can raise Standard_ConstructionError and
//! Standard_OutOfRange exceptions from its member Select3D_PointData
//! myPolyg.
class Select3D_SensitivePoly : public Select3D_SensitiveSet
{
public:
//! Constructs a sensitive face object defined by the
//! owner OwnerId, the array of points ThePoints, and
//! the sensitivity type Sensitivity.
//! The array of points is the outer polygon of the geometric face.
Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const TColgp_Array1OfPnt& thePoints,
const Standard_Boolean theIsBVHEnabled);
//! Constructs a sensitive face object defined by the
//! owner OwnerId, the array of points ThePoints, and
//! the sensitivity type Sensitivity.
//! The array of points is the outer polygon of the geometric face.
Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(TColgp_HArray1OfPnt)& thePoints,
const Standard_Boolean theIsBVHEnabled);
//! Constructs the sensitive circle object defined by the
//! owner OwnerId, the circle Circle, the Boolean
//! FilledCircle and the number of points NbOfPoints.
Standard_EXPORT Select3D_SensitivePoly (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Standard_Boolean theIsBVHEnabled,
const Standard_Integer theNbPnts = 6);
//! Returns the amount of segments in poly
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
//! Returns the 3D points of the array used at construction time.
Standard_EXPORT void Points3D (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt);
//! Returns bounding box of a polygon. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of the point set. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Returns the amount of segments of the poly
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns bounding box of segment with index theIdx
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
//! Returns geometry center of sensitive entity index theIdx in the vector along
//! the given axis theAxis
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIdx1 and theIdx2 in the vector
Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2) Standard_OVERRIDE;
DEFINE_STANDARD_RTTI (Select3D_SensitivePoly)
private:
//! Checks whether the segment with index theIdx overlaps the current selecting volume
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth) Standard_OVERRIDE;
//! Calculates distance from the 3d projection of used-picked screen point
//! to center of the geometry
virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
protected:
Select3D_PointData myPolyg; //!< Points of the poly
mutable gp_Pnt myCOG; //!< Center of the poly
Handle_TColStd_HArray1OfInteger mySegmentIndexes; //!< Segment indexes for BVH tree build
Select3D_BndBox3d myBndBox; //!< Bounding box of the poly
};
DEFINE_STANDARD_HANDLE(Select3D_SensitivePoly, Select3D_SensitiveSet)
#include <Select3D_SensitivePoly.lxx>
#endif // _Select3D_SensitivePoly_HeaderFile

View File

@@ -12,28 +12,19 @@
// commercial license or contractual agreement.
#include<Select3D_Pnt.hxx>
#include<Select3D_Pnt2d.hxx>
#include<TColgp_HArray1OfPnt.hxx>
#include<TColgp_Array1OfPnt2d.hxx>
inline void Select3D_SensitivePoly
::Points3D( Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt )
//==================================================
// Function: Points3D
// Purpose :
//==================================================
inline void Select3D_SensitivePoly::Points3D (Handle(TColgp_HArray1OfPnt)& theHArrayOfPnt)
{
Standard_Integer aSize = mypolyg.Size();
theHArrayOfPnt = new TColgp_HArray1OfPnt(1,aSize);
Standard_Integer aSize = myPolyg.Size();
theHArrayOfPnt = new TColgp_HArray1OfPnt (1,aSize);
for(Standard_Integer anIndex = 1; anIndex <= aSize; anIndex++)
{
theHArrayOfPnt->SetValue(anIndex, mypolyg.Pnt(anIndex-1));
theHArrayOfPnt->SetValue (anIndex, myPolyg.Pnt (anIndex-1));
}
}
inline void Select3D_SensitivePoly
::Points2D( TColgp_Array1OfPnt2d& aArrayOf2dPnt)
{
for(Standard_Integer anIndex = 1; anIndex <= mypolyg.Size(); anIndex++)
{
aArrayOf2dPnt.SetValue(anIndex, mypolyg.Pnt2d(anIndex-1));
}
}

View File

@@ -1,162 +0,0 @@
-- Created on: 1995-01-24
-- Created by: Mister rmi
-- 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.
class SensitiveSegment from Select3D
inherits SensitiveEntity from Select3D
---Purpose: A framework to define sensitive zones along a segment
-- One gives the 3D start and end point;
-- the maximum number of 2D boxes given
-- by this entity may be set by the user
-- if the projected segment is
-- vertical or horizontal, one needs only 1 box.
-- for a pi/4 angle -> MaxNumber 2D boxes
uses
Pnt from gp,
Pnt2d from gp,
Projector from Select3D,
Lin from gp,
EntityOwner from SelectBasics,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
Location from TopLoc,
Pnt from Select3D,
Pnt2d from Select3D
is
Create (OwnerId : EntityOwner from SelectBasics;
FirstP,LastP : Pnt from gp;
MaxRect : Integer = 1)
returns SensitiveSegment;
---Purpose: Constructs the sensitive segment object defined by
-- the owner OwnerId, the points FirstP, LastP and the
-- maximum number of sensitive bounding boxes MaxRect.
Set (me:mutable; MaxRect : Integer) is static;
---Purpose: Sets the maximum number of sensitive rectangles MaxRect.
---C++: inline
StartPoint (me : mutable ; aPt : Pnt from gp) is static;
---Level: Public
---Purpose: changes the start Point of the Segment;
---C++: inline
EndPoint (me : mutable ; aPt : Pnt from gp) is static;
---Level: Public
---Purpose: changes the end point of the segment
---C++: inline
StartPoint (me) returns Pnt from gp is static;
---Level: Public
---Purpose: gives the 3D start Point of the Segment
---C++: inline
EndPoint(me) returns Pnt from gp is static;
---Level: Public
---Purpose: gives the 3D End Point of the Segment
---C++: inline
StartPoint2d (me) returns Pnt2d from gp is static;
---Level: Public
---Purpose: gives the 3D start Point of the Segment
---C++: inline
EndPoint2d(me) returns Pnt2d from gp is static;
---Level: Public
---Purpose: gives the 3D End Point of the Segment
---C++: inline
Project (me:mutable;aProjector : Projector from Select3D)
is redefined virtual;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics)
is redefined static;
---Level: Public
---Purpose: gives the 2D boxes which represent the segment in the
-- selection process...
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is static;
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard;
MaxBoxes(me) returns Integer is redefined static;
---Level: Public
---Purpose:returns <mymaxrect>
---C++: inline
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
fields
mymaxrect : Integer;
mystart : Pnt from Select3D;
myend : Pnt from Select3D;
myprojstart : Pnt2d from Select3D; -- computed at convert time
myprojend : Pnt2d from Select3D; -- computed at convert time
end SensitiveSegment;

View File

@@ -14,248 +14,94 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitiveSegment.ixx>
#include <SelectBasics_BasicTool.hxx>
#include <Select3D_SensitiveSegment.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <Bnd_Box2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin2d.hxx>
#include <ElCLib.hxx>
#include <Extrema_ExtElC.hxx>
#include <Extrema_POnCurv.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TopLoc_Location.hxx>
#include <Precision.hxx>
#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
#include <CSLib_Class2d.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveSegment, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveSegment, Select3D_SensitiveEntity)
//=====================================================
// Function : Create
// Purpose :Constructor
// Purpose : Constructor
//=====================================================
Select3D_SensitiveSegment::
Select3D_SensitiveSegment(const Handle(SelectBasics_EntityOwner)& OwnerId,
const gp_Pnt& FirstP,
const gp_Pnt& LastP,
const Standard_Integer MaxRect):
Select3D_SensitiveEntity(OwnerId),
mymaxrect(MaxRect)
Select3D_SensitiveSegment::Select3D_SensitiveSegment (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const gp_Pnt& theFirstPnt,
const gp_Pnt& theLastPnt)
: Select3D_SensitiveEntity (theOwnerId)
{
mystart = FirstP;
myend = LastP;
myStart = theFirstPnt;
myEnd = theLastPnt;
}
//=====================================================
// Function :
// Purpose :
//=====================================================
void Select3D_SensitiveSegment
::Project(const Handle(Select3D_Projector)& aProj)
// =======================================================================
// function : Matches
// purpose : Checks whether the segment overlaps current selecting volume
// =======================================================================
Standard_Boolean Select3D_SensitiveSegment::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
gp_Pnt2d aPoint2dStart;
gp_Pnt2d aPoint2dEnd;
Standard_Real aDepth = RealLast();
Standard_Real aDistToCOG = RealLast();
Standard_Boolean isMatched = theMgr.Overlaps (myStart,
myEnd,
aDepth);
if(HasLocation())
if (isMatched)
{
gp_Pnt aStart(mystart.x, mystart.y, mystart.z);
gp_Pnt aEnd(myend.x, myend.y, myend.z);
aProj->Project(aStart.Transformed(Location().Transformation()),aPoint2dStart);
aProj->Project(aEnd.Transformed(Location().Transformation()),aPoint2dEnd);
}
else
{
aProj->Project(mystart,aPoint2dStart);
aProj->Project(myend,aPoint2dEnd);
}
myprojstart = aPoint2dStart;
myprojend = aPoint2dEnd;
}
//=====================================================
// Function : Areas
// Purpose :
//=====================================================
void Select3D_SensitiveSegment
::Areas(SelectBasics_ListOfBox2d& theareas)
{
// gp_Dir2d dy (0.,1.);
gp_Pnt2d aPStart(myprojstart.x,myprojstart.y);
if(aPStart.Distance(myprojend)<=Precision::Confusion())
{
Bnd_Box2d curbox;
curbox.Set(myprojstart);
theareas.Append(curbox);
}
else
{
gp_Vec2d MyVec(myprojstart,myprojend);//,VAxx(gp_Dir2d(0.,1.));
Standard_Real theangle = Abs(gp_Dir2d(0.,1.).Angle(gp_Vec2d(myprojstart,myprojend)));
if(theangle>=M_PI/2.) theangle-=M_PI/2;
if(theangle>=M_PI/12. && theangle <=5*M_PI/12.)
{
TColgp_Array1OfPnt2d BoxPoint (1,mymaxrect+1);
BoxPoint (1) = myprojstart;
BoxPoint(mymaxrect+1)=myprojend;
gp_Vec2d Vtr = MyVec/mymaxrect;
Standard_Integer i;
for ( i=2;i<=mymaxrect;i++)
{
BoxPoint (i) = BoxPoint (i-1).Translated(Vtr);
}
for (i=2;i<=mymaxrect+1;i++)
{
Bnd_Box2d curbox;
curbox.Set(BoxPoint(i-1));
curbox.Add(BoxPoint(i));
theareas.Append(curbox);
}
}
else
{
Bnd_Box2d curbox;
curbox.Set(myprojstart);
curbox.Add(myprojend);
theareas.Append(curbox);
}
}
}
//=====================================================
// Function : Matches
// Purpose :
//=====================================================
Standard_Boolean Select3D_SensitiveSegment::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
gp_Pnt2d aPStart (myprojstart.x,myprojstart.y);
gp_Pnt2d aPEnd (myprojend.x,myprojend.y);
if (!SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd,
thePickArgs.X(),
thePickArgs.Y(),
thePickArgs.Tolerance(),
theMatchDMin))
{
return Standard_False;
gp_Pnt aCenter = CenterOfGeometry();
aDistToCOG = theMgr.DistToGeometryCenter (aCenter);
}
theMatchDepth = ComputeDepth (thePickArgs.PickLine());
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
return !thePickArgs.IsClipped (theMatchDepth);
return isMatched;
}
//=====================================================
// Function : Matches
// Purpose :
//=====================================================
Standard_Boolean Select3D_SensitiveSegment::
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);
if(BoundBox.IsOut(myprojstart)) return Standard_False;
if( BoundBox.IsOut(myprojend)) return Standard_False;
return Standard_True;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveSegment::
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);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
Standard_Integer RES = aClassifier2d.SiDans(myprojstart);
if (RES!=1) return Standard_False;
RES = aClassifier2d.SiDans(myprojend);
if (RES!=1) return Standard_False;
return Standard_True;
}
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveSegment::
GetConnected(const TopLoc_Location& aLoc)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveSegment::GetConnected()
{
Handle(Select3D_SensitiveSegment) NiouEnt =
new Select3D_SensitiveSegment(myOwnerId,mystart,myend,mymaxrect);
Handle(Select3D_SensitiveSegment) aNewEntity =
new Select3D_SensitiveSegment (myOwnerId, myStart, myEnd);
if(HasLocation()) NiouEnt->SetLocation(Location());
NiouEnt->UpdateLocation(aLoc);
return NiouEnt;
return aNewEntity;
}
//=======================================================================
//function : Dump
//purpose :
// function : CenterOfGeometry
// purpose : Returns center of the segment. If location transformation
// is set, it will be applied
//=======================================================================
void Select3D_SensitiveSegment::Dump(Standard_OStream& S,const Standard_Boolean /*FullDump*/) const
gp_Pnt Select3D_SensitiveSegment::CenterOfGeometry() const
{
S<<"\tSensitivePoint 3D :"<<endl;
if(HasLocation())
S<<"\t\tExisting Location"<<endl;
S<<"\t\t P1 [ "<<mystart.x<<" , "<<mystart.y <<" , "<<mystart.z <<" ]"<<endl;
S<<"\t\t P2 [ "<<myend.x<<" , "<<myend.y <<" , "<<myend.z <<" ]"<<endl;
S<<"\t\t maxrect ="<<mymaxrect<<endl;
return (myStart.XYZ() + myEnd.XYZ()) * 0.5;
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveSegment::ComputeDepth(const gp_Lin& EyeLine) const
//=======================================================================
// function : BoundingBox
// purpose : Returns bounding box of the segment. If location
// transformation is set, it will be applied
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveSegment::BoundingBox()
{
gp_Pnt aP0 = mystart;
gp_Pnt aP1 = myend;
// if segment is degenerated (zero length), just use depth of the end
gp_XYZ aV = aP1.XYZ() - aP0.XYZ();
Standard_Real aNorm = aV.Modulus();
if ( aNorm <= gp::Resolution() )
return ElCLib::Parameter (EyeLine, aP0);
// else compute point on segment closest to the line
gp_Lin aLine (aP0, aV);
Extrema_ExtElC aTool (aLine, EyeLine, Precision::Angular());
if ( aTool.IsDone() && ! aTool.IsParallel() )
{
for (Standard_Integer i=1; i <= aTool.NbExt(); i++)
{
Extrema_POnCurv POL1, POL2;
aTool.Points (i, POL1, POL2);
// use point found by extrema only if it is inside segment
if ( POL1.Parameter() > 0. && POL1.Parameter() < aNorm )
return ElCLib::Parameter (EyeLine, POL1.Value());
}
}
// if extrema failed or lines are parallel, return closest of the segment ends
return Min (ElCLib::Parameter (EyeLine, aP0),
ElCLib::Parameter (EyeLine, aP1));
const SelectMgr_Vec3 aMinPnt (Min (myStart.X(), myEnd.X()),
Min (myStart.Y(), myEnd.Y()),
Min (myStart.Z(), myEnd.Z()));
const SelectMgr_Vec3 aMaxPnt (Max (myStart.X(), myEnd.X()),
Max (myStart.Y(), myEnd.Y()),
Max (myStart.Z(), myEnd.Z()));
return Select3D_BndBox3d (aMinPnt, aMaxPnt);
}
//=======================================================================
// function : NbSubElements
// purpose : Returns the amount of points
//=======================================================================
Standard_Integer Select3D_SensitiveSegment::NbSubElements()
{
return 2;
}

View File

@@ -0,0 +1,91 @@
// Created on: 1995-01-25
// Created by: Mister rmi
// 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.
#ifndef _Select3D_SensitiveSegment_HeaderFile
#define _Select3D_SensitiveSegment_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Standard_Integer.hxx>
#include <Select3D_Pnt.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <gp_Pnt.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Standard_OStream.hxx>
class SelectBasics_EntityOwner;
class gp_Pnt;
class TopLoc_Location;
class TColgp_Array1OfPnt2d;
//! A framework to define sensitive zones along a segment
//! One gives the 3D start and end point
class Select3D_SensitiveSegment : public Select3D_SensitiveEntity
{
public:
//! Constructs the sensitive segment object defined by
//! the owner theOwnerId, the points theFirstPnt, theLastPnt
Standard_EXPORT Select3D_SensitiveSegment (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const gp_Pnt& theFirstPnt,
const gp_Pnt& theLastPnt);
//! changes the start Point of the Segment;
void StartPoint (const gp_Pnt& thePnt);
//! changes the end point of the segment
void EndPoint (const gp_Pnt& thePnt);
//! gives the 3D start Point of the Segment
gp_Pnt StartPoint() const;
//! gives the 3D End Point of the Segment
gp_Pnt EndPoint() const;
//! Returns the amount of points
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Checks whether the segment overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns center of the segment. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Returns bounding box of the segment. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveSegment)
private:
gp_Pnt myStart; //!< Start point
gp_Pnt myEnd; //!< End point
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveSegment, Select3D_SensitiveEntity)
#include <Select3D_SensitiveSegment.lxx>
#endif // _Select3D_SensitiveSegment_HeaderFile

View File

@@ -14,30 +14,38 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
inline void Select3D_SensitiveSegment::Set(const Standard_Integer MaxRect)
{mymaxrect = MaxRect;}
inline void Select3D_SensitiveSegment::StartPoint (const gp_Pnt& start)
//=======================================================================
//function : StartPoint
//purpose :
//=======================================================================
inline void Select3D_SensitiveSegment::StartPoint (const gp_Pnt& thePnt)
{
mystart = start;
myStart = thePnt;
}
inline void Select3D_SensitiveSegment::EndPoint (const gp_Pnt& end)
//=======================================================================
//function : EndPoint
//purpose :
//=======================================================================
inline void Select3D_SensitiveSegment::EndPoint (const gp_Pnt& thePnt)
{
myend = end;
myEnd = thePnt;
}
inline gp_Pnt Select3D_SensitiveSegment::StartPoint () const
{return mystart;}
//=======================================================================
//function : StartPoint
//purpose :
//=======================================================================
inline gp_Pnt Select3D_SensitiveSegment::StartPoint() const
{
return myStart;
}
inline gp_Pnt Select3D_SensitiveSegment::EndPoint () const
{return myend;}
inline gp_Pnt2d Select3D_SensitiveSegment::StartPoint2d () const
{return myprojstart;}
inline gp_Pnt2d Select3D_SensitiveSegment::EndPoint2d () const
{return myprojend;}
inline Standard_Integer Select3D_SensitiveSegment::MaxBoxes()
const {return mymaxrect;}
//=======================================================================
//function : EndPoint
//purpose :
//=======================================================================
inline gp_Pnt Select3D_SensitiveSegment::EndPoint() const
{
return myEnd;
}

View File

@@ -0,0 +1,178 @@
// Created on: 2014-05-29
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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_SensitiveSet.hxx>
#include <Select3D_BVHPrimitiveContent.hxx>
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveSet, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveSet, Select3D_SensitiveEntity)
//=======================================================================
// function : Select3D_SensitiveSet
// purpose : Creates new empty sensitive set and its content
//=======================================================================
Select3D_SensitiveSet::Select3D_SensitiveSet (const Handle(SelectBasics_EntityOwner)& theOwnerId)
: Select3D_SensitiveEntity (theOwnerId)
{
myDetectedIdx = -1;
myIsLeftChildQueuedFirst = Standard_False;
myContent = new Select3D_BVHPrimitiveContent (this);
}
//=======================================================================
// function : BVH
// purpose : Builds BVH tree for sensitive set
//=======================================================================
void Select3D_SensitiveSet::BVH()
{
myContent->GetBVH();
}
//=======================================================================
// function : Matches
// purpose : Checks whether one or more entities of the set overlap
// current selecting volume. Implements the traverse of BVH
// tree built for the set
//=======================================================================
Standard_Boolean Select3D_SensitiveSet::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
const NCollection_Handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = myContent->GetBVH();
Standard_Integer aNode = 0; // a root node
if (!theMgr.Overlaps (aBVHTree->MinPoint (0),
aBVHTree->MaxPoint (0)))
{
return Standard_False;
}
Standard_Integer aStack[32];
Standard_Integer aHead = -1;
Standard_Real aDepth = RealLast();
Standard_Real aDistToCOG = RealLast();
SelectMgr_Vec3 aClosestPnt (RealLast());
Standard_Integer aMatchesNb = -1;
for (;;)
{
if (!aBVHTree->IsOuter (aNode))
{
const Standard_Integer aLeftChildIdx = aBVHTree->LeftChild (aNode);
const Standard_Integer aRightChildIdx = aBVHTree->RightChild (aNode);
const Standard_Boolean isLeftChildIn = theMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx),
aBVHTree->MaxPoint (aLeftChildIdx));
const Standard_Boolean isRightChildIn = theMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx),
aBVHTree->MaxPoint (aRightChildIdx));
if (isLeftChildIn
&& isRightChildIn)
{
aNode = aLeftChildIdx;
++aHead;
aStack[aHead] = aRightChildIdx;
}
else if (isLeftChildIn
|| isRightChildIn)
{
aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
}
else
{
if (aHead < 0)
{
break;
}
aNode = aStack[aHead];
--aHead;
}
}
else
{
Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode);
Standard_Boolean isMatched = Standard_False;
for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
{
Standard_Real anElementDepth = 0.0;
isMatched = overlapsElement (theMgr, anIdx, anElementDepth);
if (isMatched)
{
if (aDepth > anElementDepth)
{
aDepth = anElementDepth;
myDetectedIdx = anIdx;
}
aMatchesNb++;
}
}
if (aHead < 0)
{
break;
}
aNode = aStack[aHead];
--aHead;
}
}
if (aMatchesNb != -1)
{
aDistToCOG = distanceToCOG (theMgr);
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
return Standard_True;
}
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
return Standard_False;
}
//=======================================================================
// function : BoundingBox
// purpose : This method should be redefined in Select3D_SensitiveSet
// descendants
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveSet::BoundingBox()
{
return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast()),
SelectMgr_Vec3 (RealFirst()));
}
//=======================================================================
// function : CenterOfGeometry
// purpose : This method should be redefined in Select3D_SensitiveSet
// descendants
//=======================================================================
gp_Pnt Select3D_SensitiveSet::CenterOfGeometry() const
{
return gp_Pnt (RealLast(), RealLast(), RealLast());
}
//=======================================================================
// function : MarkDirty
// purpose : Marks BVH tree of the set as outdated. It will be rebuild
// at the next call of BVH()
//=======================================================================
void Select3D_SensitiveSet::MarkDirty()
{
myContent->MarkDirty();
}
//=======================================================================
// function : Clear
// purpose : Destroys cross-reference to avoid memory leak
//=======================================================================
void Select3D_SensitiveSet::Clear()
{
myContent.Nullify();
}

View File

@@ -0,0 +1,114 @@
// Created on: 2014-05-29
// Created by: Varvara POSKONINA
// Copyright (c) 2005-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.
#ifndef _Select3D_SensitiveSet_Header
#define _Select3D_SensitiveSet_Header
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <NCollection_Handle.hxx>
#include <Select3D_BndBox3d.hxx>
#include <SelectBasics_EntityOwner.hxx>
#include <Select3D_SensitiveEntity.hxx>
class Select3D_BVHPrimitiveContent;
//! This class is base class for handling overlap detection of complex sensitive
//! entities. It provides an interface for building BVH tree for some set of entities.
//! Thereby, each iteration of overlap detection is a traverse of BVH tree in fact.
//! To use speed-up heirarchical structure in a custom complex sensitive entity, it is
//! necessary to make that custom entity a descendant of this class and organize sub-entities
//! in some container which allows referencing to elements by index. Note that methods taking
//! index as a parameter are used for BVH build and the range of given index is [0; Size() - 1].
//! For example of usage see Select3D_SensitiveTriangulation.
class Select3D_SensitiveSet : public Select3D_SensitiveEntity
{
public:
//! Creates new empty sensitive set and its content
Standard_EXPORT Select3D_SensitiveSet (const Handle(SelectBasics_EntityOwner)& theOwnerId);
Standard_EXPORT ~Select3D_SensitiveSet() {};
public:
//! Returns the amount of sub-entities of the complex entity
virtual Standard_Integer Size() const = 0;
//! Returns bounding box of sub-entity with index theIdx in sub-entity list
virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const = 0;
//! Returns geometry center of sensitive entity index theIdx along the given axis theAxis
virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const = 0;
//! Swaps items with indexes theIdx1 and theIdx2
virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2) = 0;
//! Checks whether one or more entities of the set overlap current selecting volume.
//! Implements the traverse of BVH tree built for the set
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Builds BVH tree for sensitive set.
//! Must be called manually to build BVH tree for any sensitive set
//! in case if its content was initialized not in a constructor,
//! but element by element
Standard_EXPORT void BVH();
//! Marks BVH tree of the set as outdated. It will be rebuild
//! at the next call of BVH()
Standard_EXPORT void MarkDirty();
//! Returns bounding box of the whole set.
//! This method should be redefined in Select3D_SensitiveSet descendants
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of the whole set.
//! This method should be redefined in Select3D_SensitiveSet descendants
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Destroys cross-reference to avoid memory leak
Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
public:
DEFINE_STANDARD_RTTI(Select3D_SensitiveSet)
protected:
//! Checks whether the entity with index theIdx overlaps the current selecting volume
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth) = 0;
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) = 0;
protected:
Standard_Integer myDetectedIdx; //!< Index of detected primitive in BVH sorted primitive array, for debug purposes
private:
Standard_Boolean myIsLeftChildQueuedFirst; //!< Flag for slight randomization of BVH traverse
NCollection_Handle<Select3D_BVHPrimitiveContent> myContent; //!< A link between sensitive entity and BVH_PrimitiveSet
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveSet, Select3D_SensitiveEntity)
#endif // _Select3D_SensitiveSet_Header

View File

@@ -1,118 +0,0 @@
-- Created on: 1997-05-14
-- Created by: Robert COUBLANC
-- Copyright (c) 1997-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.
class SensitiveTriangle from Select3D
inherits SensitivePoly from Select3D
---Purpose: A framework to define selection of triangles in a view.
-- This comes into play in the detection of meshing and triangulation in surfaces.
-- In some cases this class can raise Standard_ConstructionError and
-- Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
uses
EntityOwner from SelectBasics,
Projector from Select3D,
Lin from gp,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
XY from gp,
Pnt from gp,
TypeOfSensitivity from Select3D,
Location from TopLoc,
SensitiveEntity from Select3D
raises
ConstructionError from Standard,
OutOfRange from Standard
is
Create (OwnerId : EntityOwner from SelectBasics;
P1,P2,P3 : Pnt from gp;
Sensitivity : TypeOfSensitivity = Select3D_TOS_INTERIOR)
returns SensitiveTriangle;
---Level: Public
---Purpose: Constructs a sensitive triangle object defined by the
-- owner OwnerId, the points P1, P2, P3, and the type of sensitivity Sensitivity.
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth(me;EyeLine: Lin from gp)
returns Real from Standard;
Points3D(me; P1,P2,P3 : out Pnt from gp) ;
---Purpose: Returns the 3D points P1, P2, P3 used at the time of construction.
Center3D (me) returns Pnt from gp;
---Purpose: Returns the center point of the sensitive triangle created at construction time.
Center2D (me) returns XY from gp;
---Purpose: WARNING : the returned Values are the original values
-- without the stored location (if there's one).
-- To get the genuine value, One must apply this location
-- (Method Location() )
Status(me;
X,Y : Real from Standard;
aTol : Real from Standard ;
Dmin : out Real from Standard)
returns Integer from Standard;
Status (myclass;
p0,p1,p2: XY from gp ;
aPoint : XY from gp ;
aTol : Real from Standard;
Dmin : out Real from Standard) returns Integer from Standard;
---Purpose: Dmin gives the distance between the cdg and aPoint return
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
GetConnected(me: mutable; theLocation : Location from TopLoc)
returns SensitiveEntity from Select3D
is redefined virtual;
---Level: Public
---Purpose: Returns the copy of this
fields
mytype : TypeOfSensitivity from Select3D;
end SensitiveTriangle;

View File

@@ -14,405 +14,121 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitiveTriangle.ixx>
#include <Select3D_SensitiveTriangle.hxx>
#include <SelectBasics_BasicTool.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pnt.hxx>
#include <gp_Dir2d.hxx>
#include <Precision.hxx>
#include <Bnd_Box.hxx>
#include <ElCLib.hxx>
#include <TopLoc_Location.hxx>
#include <CSLib_Class2d.hxx>
static Standard_Boolean S3D_Str_NearSegment (const gp_XY& p0, const gp_XY& p1, const gp_XY& TheP,
const Standard_Real aTol, Standard_Real& aDMin)
{
gp_XY V01(p1);
V01 -= p0;
gp_XY Vec(TheP);
Vec -= p0;
Standard_Real u = Vec*V01.Normalized();
if(u<-aTol) return Standard_False;
Standard_Real u1 = u-aTol;
Standard_Real modmod = V01.SquareModulus();
if(u1*u1> modmod) return Standard_False;
gp_XY N01 (-V01.Y(),V01.X());
N01.Normalize();
aDMin = Abs (Vec * N01);
return aDMin <= aTol;
}
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveTriangle, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveTriangle, Select3D_SensitiveEntity)
//==================================================
// Function: Creation
// Purpose :
//==================================================
Select3D_SensitiveTriangle::
Select3D_SensitiveTriangle(const Handle(SelectBasics_EntityOwner)& OwnerId,
const gp_Pnt& P0,
const gp_Pnt& P1,
const gp_Pnt& P2,
const Select3D_TypeOfSensitivity aType):
Select3D_SensitivePoly(OwnerId,3),
mytype (aType)
Select3D_SensitiveTriangle::Select3D_SensitiveTriangle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const gp_Pnt& thePnt0,
const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
const Select3D_TypeOfSensitivity theType)
: Select3D_SensitivePoly (theOwnerId, Standard_False, 3),
mySensType (theType)
{
mypolyg.SetPnt(0, P0);
mypolyg.SetPnt(1, P1);
mypolyg.SetPnt(2, P2);
myPolyg.SetPnt (0, thePnt0);
myPolyg.SetPnt (1, thePnt1);
myPolyg.SetPnt (2, thePnt2);
myCentroid = (gp_XYZ (myPolyg.Pnt (0)) + gp_XYZ (myPolyg.Pnt (1)) + gp_XYZ (myPolyg.Pnt (2)))
* (0.3);
}
//==================================================
// Function: Matches
// Purpose :
// Purpose : Checks whether the triangle overlaps
// current selecting volume
//==================================================
Standard_Boolean Select3D_SensitiveTriangle::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
Standard_Boolean Select3D_SensitiveTriangle::Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult)
{
Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
if (thePickArgs.IsClipped (aDepth))
Standard_Real aDepth = RealLast();
Standard_Real aDistToCOG = RealLast();
gp_Pnt aPnt1 = myPolyg.Pnt3d (0);
gp_Pnt aPnt2 = myPolyg.Pnt3d (1);
gp_Pnt aPnt3 = myPolyg.Pnt3d (2);
Standard_Boolean isMatched = theMgr.Overlaps (aPnt1, aPnt2, aPnt3, mySensType, aDepth);
if (isMatched)
{
return Standard_False;
aDistToCOG = theMgr.DistToGeometryCenter (myCentroid);
}
theMatchDepth = aDepth;
thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG);
if (Bnd_Box2d (mybox2d).IsOut (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y())))
{
return Standard_False;
}
Standard_Integer Res;
switch (mytype)
{
case Select3D_TOS_BOUNDARY:
Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
return Res== 1;
break;
case Select3D_TOS_INTERIOR:
Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
return (Res==0 || Res == 1);
default:
break;
}
return Standard_True;
}
//==================================================
// Function: Matches
// Purpose :
//==================================================
Standard_Boolean Select3D_SensitiveTriangle::
Matches (const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real aTol)
{
Bnd_Box2d B;
B.Update(Min(XMin,XMax)-aTol,
Min(YMin,YMax)-aTol,
Max(XMin,XMax)+aTol,
Max(YMin,YMax)+aTol);
for(Standard_Integer anIndex=0;anIndex<=2;++anIndex)
{
if(B.IsOut(mypolyg.Pnt2d(anIndex)))
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangle::
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);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
for(Standard_Integer anIndex=0;anIndex<=2;++anIndex)
{
Standard_Integer RES = aClassifier2d.SiDans(mypolyg.Pnt2d(anIndex));
if(RES!=1)
return Standard_False;
}
return Standard_True;
return isMatched;
}
//==================================================
// Function: Points3D
// Purpose :
//==================================================
void Select3D_SensitiveTriangle::Points3D(gp_Pnt& P0,gp_Pnt& P1,gp_Pnt& P2) const
void Select3D_SensitiveTriangle::Points3D (gp_Pnt& thePnt0, gp_Pnt& thePnt1, gp_Pnt& thePnt2) const
{
P0 = mypolyg.Pnt(0);
P1 = mypolyg.Pnt(1);
P2 = mypolyg.Pnt(2);
thePnt0 = myPolyg.Pnt (0);
thePnt1 = myPolyg.Pnt (1);
thePnt2 = myPolyg.Pnt (2);
}
//==================================================
// Function: Center3D
// Purpose :
//==================================================
gp_Pnt Select3D_SensitiveTriangle::Center3D() const
{
gp_XYZ aPnt1, aPnt2, aPnt3;
aPnt1 = mypolyg.Pnt(0);
aPnt2 = mypolyg.Pnt(1);
aPnt3 = mypolyg.Pnt(2);
return gp_Pnt((aPnt1+aPnt2+aPnt3)/3.);
}
//==================================================
// Function: Center2D
// Purpose :
//==================================================
gp_XY Select3D_SensitiveTriangle::Center2D() const
{
gp_XY aPnt1, aPnt2, aPnt3;
aPnt1 = mypolyg.Pnt2d(0);
aPnt2 = mypolyg.Pnt2d(1);
aPnt3 = mypolyg.Pnt2d(2);
return (aPnt1+aPnt2+aPnt3)/3.;
}
//=======================================================================
//function : Status
//purpose : 0 = inside /1 = Boundary/ 2 = outside
//=======================================================================
Standard_Integer Select3D_SensitiveTriangle::Status(const Standard_Real X,
const Standard_Real Y,
const Standard_Real aTol,
Standard_Real& DMin) const
{
return Status(mypolyg.Pnt2d(0), mypolyg.Pnt2d(1), mypolyg.Pnt2d(2),
gp_XY(X,Y), aTol, DMin);
}
//=======================================================================
//function : Status
//purpose :
//=======================================================================
Standard_Integer Select3D_SensitiveTriangle::Status(const gp_XY& p0,
const gp_XY& p1,
const gp_XY& p2,
const gp_XY& TheP,
const Standard_Real aTol,
Standard_Real& DMin)
{
Bnd_Box2d B;
B.Update(p0.X(),p0.Y());B.Update(p1.X(),p1.Y());B.Update(p2.X(),p2.Y());
B.Enlarge(aTol);
if(B.IsOut(TheP)) return 2;
// the point is classified corresponding to demi-spaces limited
// by each side of the triangle (with tolerance)
gp_XY V01(p1);V01-=p0;
gp_XY V02(p2);V02-=p0;
gp_XY V12(p2);V12-=p1;
// check these particular cases...
// if one of vectors is almost null (2 points are mixed),
// leave at once (it is already in the bounding box, which is good...)
DMin = aTol;
if ( V01.SquareModulus() <= gp::Resolution() )
{
Standard_Real LV = V02.SquareModulus();
if ( LV <= gp::Resolution())
return 0; // 3 points are mixed, and TheP is in the bounding box B...
if ( S3D_Str_NearSegment (p0, p2, TheP, aTol, DMin) )
return 0;
return 2;
}
if ( V02.SquareModulus() <= gp::Resolution() )
{
if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) )
return 0;
return 2;
}
if ( V12.SquareModulus() <= gp::Resolution() )
{
if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) )
return 0;
return 2;
}
if ( V01.CrossMagnitude(V02) <= gp::Resolution() )
{
if ( S3D_Str_NearSegment (p0, p1, TheP, aTol, DMin) )
return 0;
return 2;
}
// oriented normal to p0p1...
gp_Dir2d N (-V01.Y(), V01.X());
Standard_Boolean Neg = (N * V02 < 0.);
if ( Neg )
N.Reverse();
gp_XY Vec(TheP);
Vec -= p0;
Standard_Real aD1 = Vec * N.XY();
if ( aD1 < -aTol )
return 2;
// oriented normal to p1p2...
if(Neg)
N.SetCoord(p2.Y()-p1.Y(),p1.X()-p2.X());
else
N.SetCoord(p1.Y()-p2.Y(),p2.X()-p1.X());
Vec.SetCoord(TheP.X()-p1.X(),TheP.Y()-p1.Y());
Standard_Real aD2 = Vec * N.XY();
if ( aD2 < -aTol )
return 2; // outside
// oriented normal to p2p0...
// attention v20 (x0-x2) => N y2-y0 => -N y0-y2
// (y0-y2) x0-x2 x2-x0
if(Neg)
N.SetCoord(p0.Y()-p2.Y(),p2.X()-p0.X());
else
N.SetCoord(p2.Y()-p0.Y(),p0.X()-p2.X());
Vec.SetCoord(TheP.X()-p2.X(),TheP.Y()-p2.Y());
Standard_Real aD3 = Vec * N.XY();
if ( aD3 < -aTol )
return 2; // outside
// compute 2d distance to triangle
Standard_Real aD = Min (aD1, Min (aD2, aD3));
DMin = ( aD < 0 ? -aD : 0. );
return 0;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Select3D_SensitiveTriangle::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
{
// general information....
S<<"\tSensitiveTriangle 3D :\n";
if(HasLocation())
S<<"\t\tExisting Location"<<endl;
gp_Pnt aPnt1, aPnt2, aPnt3;
aPnt1 = mypolyg.Pnt(0);
aPnt2 = mypolyg.Pnt(1);
aPnt3 = mypolyg.Pnt(2);
S<<"\t\t P0 [ "<<aPnt1.X()<<" , "<<aPnt1.Y()<<" , "<<aPnt1.Z()<<" ]"<<endl;
S<<"\t\t P1 [ "<<aPnt2.X()<<" , "<<aPnt2.Y()<<" , "<<aPnt2.Z()<<" ]"<<endl;
S<<"\t\t P2 [ "<<aPnt3.X()<<" , "<<aPnt3.Y()<<" , "<<aPnt3.Z()<<" ]"<<endl;
if(FullDump)
{
S<<"\t\tProjected Points"<<endl;
gp_Pnt2d aPnt1, aPnt2, aPnt3;
aPnt1 = mypolyg.Pnt2d(0);
aPnt2 = mypolyg.Pnt2d(1);
aPnt3 = mypolyg.Pnt2d(2);
S<<"\t\t 0.[ "<<aPnt1.X()<<" , "<<aPnt1.Y()<<" ]"<<endl;
S<<"\t\t 1.[ "<<aPnt2.X()<<" , "<<aPnt2.Y()<<" ]"<<endl;
S<<"\t\t 2.[ "<<aPnt3.X()<<" , "<<aPnt3.Y()<<" ]"<<endl;
Select3D_SensitiveEntity::DumpBox(S,mybox2d);
}
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveTriangle::ComputeDepth(const gp_Lin& EyeLine) const
{
Standard_Real prof(Precision::Infinite());
gp_Pnt P1, P2, P3;
P1 = mypolyg.Pnt(0);
P2 = mypolyg.Pnt(1);
P3 = mypolyg.Pnt(2);
gp_Trsf TheTrsf ;
if(HasLocation())
TheTrsf = Location().Transformation();
if(TheTrsf.Form()!=gp_Identity)
{
P1.Transform(TheTrsf);
P2.Transform(TheTrsf);
P3.Transform(TheTrsf);
}
// formula calculation of the point parameters on intersection
// t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir)
gp_Pnt Oye = EyeLine.Location(); // origin of the target line eye/point...
gp_Dir Dir = EyeLine.Direction();
gp_Vec P1P2 (P1,P2), P1P3(P1,P3);
P1P2.Normalize();
P1P3.Normalize();
gp_Vec oP1(Oye,P1);
Standard_Real val1 = oP1.DotCross(P1P2,P1P3);
Standard_Real val2 = Dir.DotCross(P1P2,P1P3);
if(Abs(val2)>Precision::Confusion())
prof =val1/val2;
if (prof==Precision::Infinite())
{
prof= ElCLib::Parameter(EyeLine,P1);
prof = Min (prof, ElCLib::Parameter(EyeLine,P2));
prof = Min (prof, ElCLib::Parameter(EyeLine,P3));
}
return prof;
aPnt1 = myPolyg.Pnt (0);
aPnt2 = myPolyg.Pnt (1);
aPnt3 = myPolyg.Pnt (2);
return gp_Pnt ((aPnt1 + aPnt2 + aPnt3) / 3.0);
}
//==================================================
// Function: GetConnected
// Purpose :
//==================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangle::
GetConnected(const TopLoc_Location &theLocation)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangle::GetConnected()
{
// Create a copy of this
Handle(Select3D_SensitiveEntity) aNewEntity =
new Select3D_SensitiveTriangle(myOwnerId, mypolyg.Pnt(0), mypolyg.Pnt(1), mypolyg.Pnt(2), mytype);
if (HasLocation())
aNewEntity->SetLocation(Location());
aNewEntity->UpdateLocation(theLocation);
new Select3D_SensitiveTriangle (myOwnerId, myPolyg.Pnt(0), myPolyg.Pnt(1), myPolyg.Pnt(2), mySensType);
return aNewEntity;
}
//==================================================
// Function: BoundingBox
// Purpose : Returns bounding box of the triangle.
// If location transformation is set, it
// will be applied
//==================================================
Select3D_BndBox3d Select3D_SensitiveTriangle::BoundingBox()
{
gp_Pnt aPnt1 = myPolyg.Pnt3d (0);
gp_Pnt aPnt2 = myPolyg.Pnt3d (1);
gp_Pnt aPnt3 = myPolyg.Pnt3d (2);
const SelectMgr_Vec3 aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())),
Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())),
Min (aPnt1.Z(), Min (aPnt2.Z(), aPnt3.Z())));
const SelectMgr_Vec3 aMaxPnt = SelectMgr_Vec3 (Max (aPnt1.X(), Max (aPnt2.X(), aPnt3.X())),
Max (aPnt1.Y(), Max (aPnt2.Y(), aPnt3.Y())),
Max (aPnt1.Z(), Max (aPnt2.Z(), aPnt3.Z())));
return Select3D_BndBox3d (aMinPnt, aMaxPnt);
}
//==================================================
// Function: NbSubElements
// Purpose : Returns the amount of points
//==================================================
Standard_Integer Select3D_SensitiveTriangle::NbSubElements()
{
return 3;
}

View File

@@ -0,0 +1,86 @@
// Created on: 1997-05-14
// Created by: Robert COUBLANC
// Copyright (c) 1997-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.
#ifndef _Select3D_SensitiveTriangle_HeaderFile
#define _Select3D_SensitiveTriangle_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Select3D_TypeOfSensitivity.hxx>
#include <Select3D_Pnt.hxx>
#include <Select3D_SensitivePoly.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Standard_OStream.hxx>
class Standard_ConstructionError;
class Standard_OutOfRange;
class SelectBasics_EntityOwner;
class gp_Pnt;
class TColgp_Array1OfPnt2d;
class Select3D_SensitiveEntity;
class TopLoc_Location;
//! A framework to define selection of triangles in a view.
//! This comes into play in the detection of meshing and triangulation in surfaces.
//! In some cases this class can raise Standard_ConstructionError and
//! Standard_OutOfRange exceptions. For more details see Select3D_SensitivePoly.
class Select3D_SensitiveTriangle : public Select3D_SensitivePoly
{
public:
//! Constructs a sensitive triangle object defined by the
//! owner theOwnerId, the points P1, P2, P3, and the type of sensitivity Sensitivity.
Standard_EXPORT Select3D_SensitiveTriangle (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const gp_Pnt& thePnt0,
const gp_Pnt& thePnt1,
const gp_Pnt& thePnt2,
const Select3D_TypeOfSensitivity theType = Select3D_TOS_INTERIOR);
//! Checks whether the triangle overlaps current selecting volume
Standard_EXPORT virtual Standard_Boolean Matches (SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) Standard_OVERRIDE;
//! Returns the 3D points P1, P2, P3 used at the time of construction.
Standard_EXPORT void Points3D (gp_Pnt& thePnt0, gp_Pnt& thePnt1, gp_Pnt& thePnt2) const;
//! Returns the center point of the sensitive triangle created at construction time.
Standard_EXPORT gp_Pnt Center3D() const;
//! Returns the copy of this
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! Returns bounding box of the triangle. If location transformation is set, it
//! will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns the amount of points
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangle)
private:
Select3D_TypeOfSensitivity mySensType; //!< Type of sensitivity: boundary or interior
gp_Pnt myCentroid; //!< Center of triangle
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveTriangle, Select3D_SensitiveEntity)
#endif

View File

@@ -1,201 +0,0 @@
-- Created on: 1997-05-15
-- Created by: Robert COUBLANC
-- Copyright (c) 1997-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.
class SensitiveTriangulation from Select3D
inherits SensitiveEntity from Select3D
---Purpose: A framework to define selection of a sensitive entity made of a set of triangles.
uses
EntityOwner from SelectBasics,
Projector from Select3D,
Lin from gp,
Trsf from gp,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt from TColgp,
Array1OfPnt2d from TColgp,
HArray1OfInteger from TColStd,
Box2d from Bnd,
SensitiveTriangle from Select3D,
ListOfSensitiveTriangle from Select3D,
XYZ from gp,
XY from gp,
Pnt from gp,
Pnt2d from gp,
Triangulation from Poly,
Location from TopLoc
is
Create(OwnerId : EntityOwner from SelectBasics;
aTriangulation: Triangulation from Poly;
aLoc : Location from TopLoc;
InteriorFlag : Boolean from Standard = Standard_True)
returns SensitiveTriangulation from Select3D;
---Purpose: Constructs a sensitive triangulation object defined by
-- the owner OwnerId, the triangulation aTriangulation,
-- the location aLoc, and the flag InteriorFlag.
Create(OwnerId : EntityOwner from SelectBasics;
aTriangulation: Triangulation from Poly;
aLoc : Location from TopLoc;
thefreeedges : HArray1OfInteger from TColStd;
theCDG : Pnt from gp;
InteriorFlag : Boolean from Standard)
returns SensitiveTriangulation from Select3D;
---Purpose: Constructs a sensitive triangulation object defined by
-- the owner OwnerId, the triangulation aTriangulation,
-- the location aLoc, the array of free edges
-- thefreeedges, the center of gravity theCDG, and the flag InteriorFlag.
-- As free edges and the center of gravity do not have
-- to be computed later, this syntax reduces computation time.
Project (me:mutable;aProjector : Projector from Select3D) is redefined static;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics) is redefined static;
---Level: Public
---Purpose: stores in <boxes> the 2D Boxes which represent the sensitive face
-- in the selection algorithm.
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
ComputeDepth (me;
thePickLine : Lin from gp;
theTriangle : Integer from Standard)
returns Real from Standard;
---Level: Public
---Purpose: Compute precise depth of detected triangle.
-- @param thePickLine [in] the picking line.
-- @param theTriangle [in] the index of detected triangle.
-- @return depth on the picking line.
DetectedTriangle(me) returns Integer from Standard;
---Purpose: Returns the detected three nodes P1, P2, P3 constituting a triangle.
-- This triangle is a component of the overall sensitive
-- triangulation created at construction time.
---C++: inline
Triangulation(me) returns any Triangulation from Poly;
---Purpose: Returns the triangulation used at the time of construction.
---C++: inline
---C++: return const &
CDG3D(me) returns Pnt from gp;
---Purpose: Returns the 3D center of gravity used at the time of construction.
---C++: inline
---C++: return const &
CDG2D(me) returns Pnt2d from gp;
---Purpose: Returns the 2D center of gravity used at the time of construction.
---C++: inline
---C++: return const &
IsFree(me;
IndexOfTriangle : Integer from Standard;
IndexinFree : out Integer from Standard)
returns Boolean is static private;
Status (me;
p0,p1,p2: XY from gp ;
aPoint : XY from gp ;
aTol : Real from Standard;
Dmin : out Real from Standard) returns Integer from Standard;
---Purpose: Dmin gives the distance between the cdg and aPoint
---Category: TheLocations....
HasInitLocation(me) returns Boolean from Standard;
---C++: inline
GetInitLocation(me) returns Location from TopLoc;
---C++: inline
---C++: return const &
ResetLocation(me:mutable) is redefined virtual;
SetLocation(me:mutable;aLoc :Location from TopLoc) is redefined virtual;
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
DetectedTriangle(me;P1,P2,P3 : out Pnt from gp)
returns Boolean from Standard;
---Purpose: gives the vertices of detected triangle...
DetectedTriangle2d(me;P1,P2,P3 : out Pnt2d from gp)
returns Boolean from Standard;
---Purpose: Gets 2D nodes computed by entity using 3D nodes and viewer
-- parameters (see Project() method)
ComputeTotalTrsf(me:mutable) is static private;
fields
myTriangul : Triangulation from Poly;
myiniloc : Location from TopLoc;
myTrsf : Trsf from gp;
myCDG3D : Pnt from gp;
myFreeEdges: HArray1OfInteger from TColStd;
myIntFlag : Boolean from Standard;
myNodes2d : Array1OfPnt2d from TColgp;
myCDG2D : Pnt2d from gp;
mybox2d : Box2d from Bnd;
myDetectedTr: Integer from Standard;
end SensitiveTriangulation;

View File

@@ -14,691 +14,382 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//Modified Thur Apr 09 98 by rob : No more computation of free edges.
// fix bug on Compute Depth (don't forget
// Location...)
#include <algorithm>
#include <Select3D_SensitiveTriangulation.ixx>
#include <gp_Pnt2d.hxx>
#include <Poly.hxx>
#include <Poly_Connect.hxx>
#include <CSLib_Class2d.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Select3D_SensitiveTriangle.hxx>
#include <Precision.hxx>
#include <ElCLib.hxx>
#include <CSLib_Class2d.hxx>
#include <Select3D_TypeOfSensitivity.hxx>
#include <Select3D_SensitiveTriangulation.hxx>
static Standard_Integer S3D_NumberOfFreeEdges(const Handle(Poly_Triangulation)& Trg)
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
static Standard_Integer NbOfFreeEdges (const Handle(Poly_Triangulation)& theTriangulation)
{
Standard_Integer nFree = 0;
Poly_Connect pc(Trg);
Standard_Integer t[3];
Standard_Integer i,j;
for (i = 1; i <= Trg->NbTriangles(); i++) {
pc.Triangles(i,t[0],t[1],t[2]);
for (j = 0; j < 3; j++)
if (t[j] == 0) nFree++;
Standard_Integer aNbFree = 0;
Poly_Connect aPoly (theTriangulation);
Standard_Integer aTriangleNodes[3];
for (Standard_Integer aTrgIdx = 1; aTrgIdx <= theTriangulation->NbTriangles(); aTrgIdx++)
{
aPoly.Triangles (aTrgIdx, aTriangleNodes[0], aTriangleNodes[1], aTriangleNodes[2]);
for (Standard_Integer aNodeIdx = 0; aNodeIdx < 3; aNodeIdx++)
if (aTriangleNodes[aNodeIdx] == 0)
aNbFree++;
}
return nFree;
}
static Standard_Boolean S3D_STriangul_NearSegment (const gp_XY& p0, const gp_XY& p1, const gp_XY& TheP,
const Standard_Real aTol, Standard_Real& aDMin)
{
Bnd_Box2d B;
B.SetVoid();
B.Set(p0);
B.Update(p1.X(),p1.Y());
B.Enlarge(aTol*3);
if(B.IsOut(TheP)) return Standard_False;
gp_XY V01(p1);V01-=p0;
gp_XY Vec(TheP);Vec -= p0;
if (V01.SquareModulus() < Precision::SquareConfusion())
return Standard_False;
Standard_Real u = Vec*V01.Normalized();
if(u<-aTol) return Standard_False;
Standard_Real u1 = u-aTol;
Standard_Real modmod = V01.SquareModulus();
if(u1*u1> modmod) return Standard_False;
gp_XY N01 (-V01.Y(),V01.X());
N01.Normalize();
aDMin = Abs (Vec * N01);
return aDMin <= aTol;
}
// static Standard_Real S3D_SquareDistanceFromEdge(gp_Pnt2d PCur,
// gp_Pnt2d PEdg1,
// gp_Pnt2d PEdg2,
// const Standard_Real TolTol)
// {
// gp_XY VEdg (PEdg1.XY());
// gp_XY VCur (PEdg1.XY());
// VEdg-= PEdg2.XY();
// VCur-=PCur.XY();
// Standard_Real long1 = VEdg.SquareModulus();
// if(long1<=TolTol)
// return VCur.SquareModulus();
// Standard_Real Val = VEdg^VCur;
// return Val*Val/long1;
// }
static Standard_Boolean S3D_IsEdgeIn(const Standard_Integer e1,
const Standard_Integer e2,
const Standard_Integer N1,
const Standard_Integer N2,
const Standard_Integer N3)
{
Standard_Integer bid1 = (e1 == N1) ? N1 : ((e1 == N2) ? N2 : ( e1==N3 ? N3 : 0));
if(bid1==0) return Standard_False;
Standard_Integer bid2 = (e2 == N1) ? N1 : ((e2 == N2) ? N2 : ( e2==N3 ? N3 : 0));
if(bid2==0 || bid2 ==bid1) return Standard_False;
return Standard_True;
return aNbFree;
}
//=======================================================================
//function : Select3D_SensitiveTriangulation
//purpose :
//=======================================================================
Select3D_SensitiveTriangulation::
Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(Poly_Triangulation)& Trg,
const TopLoc_Location& Loc,
const Standard_Boolean InteriorFlag):
Select3D_SensitiveEntity(OwnerId),
myTriangul(Trg),
myiniloc(Loc),
myIntFlag(InteriorFlag),
myNodes2d(1,Trg->NbNodes()),
myDetectedTr(-1)
Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Poly_Triangulation)& theTrg,
const TopLoc_Location& theInitLoc,
const Standard_Boolean theIsInterior)
: Select3D_SensitiveSet (theOwnerId),
myTriangul (theTrg),
myInitLocation (theInitLoc),
myDetectedTr (-1)
{
// calculate free edges and cdg 3d of the triangulation:
// This code should have been integrated in poly_triangulation...
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& aNodes = myTriangul->Nodes();
Standard_Integer aNbTriangles (myTriangul->NbTriangles());
gp_XYZ aCenter (0.0, 0.0, 0.0);
Standard_Integer fr = 1;
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
Standard_Integer nbTriangles (myTriangul->NbTriangles());
gp_XYZ cdg(0,0,0);
Standard_Integer n[3];
myPrimitivesNb = theIsInterior ? aNbTriangles : NbOfFreeEdges (theTrg);
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
TColStd_Array1OfInteger& aBVHPrimIdxs = myBVHPrimIndexes->ChangeArray1();
// to find connections in case when the border is not concerned...
if(!myIntFlag)
if (!theIsInterior)
{
myFreeEdges = new TColStd_HArray1OfInteger(1,2*S3D_NumberOfFreeEdges(Trg));
TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
Poly_Connect pc(myTriangul);
Standard_Integer t[3];
Standard_Integer i,j;
for ( i = 1; i <= nbTriangles; i++)
Standard_Integer anEdgeIdx = 1;
myFreeEdges = new TColStd_HArray1OfInteger (1, 2 * myPrimitivesNb);
TColStd_Array1OfInteger& aFreeEdges = myFreeEdges->ChangeArray1();
Poly_Connect aPoly (myTriangul);
Standard_Integer aTriangle[3];
Standard_Integer aTrNodeIdx[3];
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; aTriangleIdx++)
{
pc.Triangles(i,t[0],t[1],t[2]);
triangles(i).Get(n[0],n[1],n[2]);
cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.;
for (j = 0; j < 3; j++)
aPoly.Triangles (aTriangleIdx, aTriangle[0], aTriangle[1], aTriangle[2]);
aTriangles (aTriangleIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]);
aCenter += (aNodes (aTrNodeIdx[0]).XYZ() + aNodes (aTrNodeIdx[1]).XYZ()+ aNodes (aTrNodeIdx[2]).XYZ()) / 3.0;
for (Standard_Integer aVertIdx = 0; aVertIdx < 3; aVertIdx++)
{
Standard_Integer k = (j+1) % 3;
if (t[j] == 0)
Standard_Integer aNextVert = (aVertIdx + 1) % 3;
if (aTriangle[aVertIdx] == 0)
{
FreeE(fr) = n[j];
FreeE(fr+1)= n[k];
fr += 2;
aFreeEdges (anEdgeIdx) = aTrNodeIdx[aVertIdx];
aFreeEdges (anEdgeIdx+1) = aTrNodeIdx[aNextVert];
anEdgeIdx += 2;
}
}
}
}
else{
for (Standard_Integer i = 1; i <= nbTriangles; i++)
{
triangles(i).Get(n[0],n[1],n[2]);
cdg += (Nodes(n[0]).XYZ() + Nodes(n[1]).XYZ()+ Nodes(n[2]).XYZ())/3.;
}
}
if(nbTriangles!=0) cdg /= nbTriangles;
myCDG3D = gp_Pnt(cdg);
ComputeTotalTrsf();
if(myTrsf.Form()!=gp_Identity)
myCDG3D.Transform(myTrsf);
}
//=======================================================================
//function : Select3D_SensitiveTriangulation
//purpose :
//=======================================================================
Select3D_SensitiveTriangulation::
Select3D_SensitiveTriangulation(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Handle(Poly_Triangulation)& Trg,
const TopLoc_Location& Loc,
const Handle(TColStd_HArray1OfInteger)& FreeEdges,
const gp_Pnt& TheCDG,
const Standard_Boolean InteriorFlag):
Select3D_SensitiveEntity(OwnerId),
myTriangul(Trg),
myiniloc(Loc),
myCDG3D(TheCDG),
myFreeEdges(FreeEdges),
myIntFlag(InteriorFlag),
myNodes2d(1,Trg->NbNodes()),
myDetectedTr(-1)
{
}
//=======================================================================
//function : Project
//purpose :
//=======================================================================
void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj)
{
mybox2d.SetVoid();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
gp_Pnt2d ProjPT;
for(Standard_Integer I=1;I<=myTriangul->NbNodes();I++){
if(myTrsf.Form()!=gp_Identity)
aPrj->Project(Nodes(I).Transformed(myTrsf),ProjPT);
else
aPrj->Project(Nodes(I),ProjPT);
myNodes2d.SetValue(I,ProjPT);
mybox2d.Add(ProjPT);
}
aPrj->Project(myCDG3D,myCDG2D);
}
//=======================================================================
//function : Areas
//purpose :
//=======================================================================
void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes)
{
boxes.Append(mybox2d);
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
theMatchDMin = Precision::Infinite();
gp_XY BidPoint (thePickArgs.X(), thePickArgs.Y());
myDetectedTr = -1;
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
// it is checked if we are inside the triangle 2d.
if(myIntFlag)
{
gp_Lin aPickingLine = thePickArgs.PickLine();
if (myTrsf.Form() != gp_Identity)
{
aPickingLine.Transform (myTrsf.Inverted());
}
Standard_Real aMinDepth = Precision::Infinite();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
for (Standard_Integer itr=1; itr<=myTriangul->NbTriangles(); itr++)
{
Standard_Integer n1,n2,n3;
triangles(itr).Get(n1,n2,n3);
const gp_XY& aPnt2d1 = myNodes2d(n1).XY();
const gp_XY& aPnt2d2 = myNodes2d(n2).XY();
const gp_XY& aPnt2d3 = myNodes2d(n3).XY();
gp_XY aUV;
Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV);
if (aDistSquare > thePickArgs.Tolerance() * thePickArgs.Tolerance())
continue;
// get interpolated depth of the triangle nodes
Standard_Real aDepth1 = ElCLib::Parameter (aPickingLine, Nodes(n1));
Standard_Real aDepth2 = ElCLib::Parameter (aPickingLine, Nodes(n2));
Standard_Real aDepth3 = ElCLib::Parameter (aPickingLine, Nodes(n3));
Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) +
aUV.Y() * (aDepth3 - aDepth1);
// accept triangle with lowest depth and within defined depth interval
if (aDepth < aMinDepth && !thePickArgs.IsClipped(aDepth))
{
aMinDepth = aDepth;
myDetectedTr = itr;
theMatchDMin = Sqrt (aDistSquare);
}
}
}
// Case only Test on Border of the triangulation...
//
else
{
//Standard_Integer ifirst;
TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
Standard_Integer nn = FreeE.Length(), Node1,Node2;
//Standard_Real LEdg;
//Standard_Real DMinDMin,TolTol = aTol*aTol;
for (Standard_Integer ifri =1; ifri <= nn && myDetectedTr < 0; ifri+=2)
Standard_Integer aTrNodeIdx[3];
for (Standard_Integer aTrIdx = 1; aTrIdx <= aNbTriangles; aTrIdx++)
{
Node1 = FreeE(ifri);
Node2 = FreeE(ifri+1);
if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(),
myNodes2d(Node2).XY(),
BidPoint, thePickArgs.Tolerance(), theMatchDMin))
{
for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++)
{
Standard_Integer n1,n2,n3;
triangles(itr).Get(n1,n2,n3);
if(S3D_IsEdgeIn(Node1,Node2,n1,n2,n3))
{
myDetectedTr = itr;
break; // return first found; selection of closest is not implemented yet
}
}
}
aTriangles (aTrIdx).Get (aTrNodeIdx[0], aTrNodeIdx[1], aTrNodeIdx[2]);
aCenter += (aNodes (aTrNodeIdx[0]).XYZ() + aNodes (aTrNodeIdx[1]).XYZ()+ aNodes (aTrNodeIdx[2]).XYZ()) / 3.0;
}
}
if ( myDetectedTr <= 0 )
return Standard_False;
if (aNbTriangles != 0)
aCenter /= aNbTriangles;
myCDG3D = gp_Pnt (aCenter);
// get precise depth for the detected triangle
theMatchDepth = ComputeDepth (thePickArgs.PickLine(), myDetectedTr);
// this test should not fail if the topmost triangle is taken from the
// first if-case block (for other cases this test make sense?)
return !thePickArgs.IsClipped (theMatchDepth);
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::
Matches(const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real aTol)
{
Bnd_Box2d B;
B.Update(Min(XMin,XMax)-aTol,
Min(YMin,YMax)-aTol,
Max(XMin,XMax)+aTol,
Max(YMin,YMax)+aTol);
for(Standard_Integer i=myNodes2d.Lower();i<=myNodes2d.Upper();i++)
myBndBox.Clear();
for (Standard_Integer aNodeIdx = 1; aNodeIdx <= myTriangul->NbNodes(); ++aNodeIdx)
{
if(B.IsOut(myNodes2d(i)))
return Standard_False;
myBndBox.Add (SelectMgr_Vec3 (aNodes (aNodeIdx).X(),
aNodes (aNodeIdx).Y(),
aNodes (aNodeIdx).Z()));
}
return Standard_True;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::
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);
CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
for(Standard_Integer j=1;j<=myNodes2d.Length();j++)
if (theIsInterior)
{
Standard_Integer RES = aClassifier2d.SiDans(myNodes2d(j));
if(RES!=1) return Standard_False;
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= aNbTriangles; ++aTriangleIdx)
{
aBVHPrimIdxs (aTriangleIdx - 1) = aTriangleIdx - 1;
}
}
return Standard_True;
}
//=======================================================================
//function : Status
//purpose :
//=======================================================================
Standard_Integer Select3D_SensitiveTriangulation::
Status (const gp_XY& TheP,
const gp_XY& Proj0,
const gp_XY& Proj1,
const gp_XY& Proj2,
const Standard_Real aTol,
Standard_Real& DD) const
{
return Select3D_SensitiveTriangle::Status(Proj0,Proj1,Proj2,TheP,aTol,DD);
}
//=======================================================================
//function : IsFree
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::IsFree(const Standard_Integer IndexOfTriangle,
Standard_Integer& FoundIndex) const
{
FoundIndex=-1;
Standard_Integer n[3];
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
triangles(IndexOfTriangle).Get(n[0],n[1],n[2]);
TColStd_Array1OfInteger& FreeE = myFreeEdges->ChangeArray1();
for(Standard_Integer I=1;I<=FreeE.Length() && FoundIndex==-1;I+=2)
else
{
if(FreeE(I) == n[0])
Standard_Integer aStartIdx = myFreeEdges->Lower();
Standard_Integer anEndIdx = myFreeEdges->Upper();
for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
{
if(FreeE(I+1)== n[1] || FreeE(I+1)== n[2])
FoundIndex=I;
}
else if(FreeE(I) == n[1])
{
if(FreeE(I+1)== n[0] || FreeE(I+1)== n[2])
FoundIndex=I;
}
else if(FreeE(I) == n[2])
{
if(FreeE(I+1)== n[0] || FreeE(I+1)== n[1])
FoundIndex=I;
aBVHPrimIdxs ((aFreeEdgesIdx - aStartIdx) / 2) = (aFreeEdgesIdx - aStartIdx) / 2;
}
}
return FoundIndex!=-1;
}
//=======================================================================
//function : Select3D_SensitiveTriangulation
//purpose :
//=======================================================================
Select3D_SensitiveTriangulation::Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Poly_Triangulation)& theTrg,
const TopLoc_Location& theInitLoc,
const Handle(TColStd_HArray1OfInteger)& theFreeEdges,
const gp_Pnt& theCOG,
const Standard_Boolean theIsInterior)
: Select3D_SensitiveSet (theOwnerId),
myTriangul (theTrg),
myInitLocation (theInitLoc),
myCDG3D (theCOG),
myFreeEdges (theFreeEdges),
myDetectedTr (-1)
{
mySensType = theIsInterior ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY;
myPrimitivesNb = theIsInterior ? theTrg->Triangles().Length() : theFreeEdges->Length() / 2;
myBVHPrimIndexes = new TColStd_HArray1OfInteger(0, myPrimitivesNb - 1);
if (theIsInterior)
{
for (Standard_Integer aTriangleIdx = 1; aTriangleIdx <= myPrimitivesNb; ++aTriangleIdx)
{
myBVHPrimIndexes->SetValue (aTriangleIdx - 1, aTriangleIdx - 1);
}
}
else
{
Standard_Integer aStartIdx = myFreeEdges->Lower();
Standard_Integer anEndIdx = myFreeEdges->Upper();
for (Standard_Integer aFreeEdgesIdx = aStartIdx; aFreeEdgesIdx <= anEndIdx; aFreeEdgesIdx += 2)
{
myBVHPrimIndexes->SetValue ((aFreeEdgesIdx - aStartIdx) / 2, (aFreeEdgesIdx - aStartIdx) / 2);
}
}
}
//=======================================================================
// function : Size
// purpose : Returns the length of array of triangles or edges
//=======================================================================
Standard_Integer Select3D_SensitiveTriangulation::Size() const
{
return myPrimitivesNb;
}
//=======================================================================
// function : Box
// purpose : Returns bounding box of triangle/edge with index theIdx
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveTriangulation::Box (const Standard_Integer theIdx) const
{
Standard_Integer aPrimIdx = myBVHPrimIndexes->Value (theIdx);
SelectMgr_Vec3 aMinPnt (RealLast());
SelectMgr_Vec3 aMaxPnt (RealFirst());
Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_INTERIOR)
{
Standard_Integer aNode1, aNode2, aNode3;
myTriangul->Triangles() (aPrimIdx + 1).Get (aNode1, aNode2, aNode3);
gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode1);
gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode3);
aMinPnt = SelectMgr_Vec3 (Min (aPnt1.X(), Min (aPnt2.X(), aPnt3.X())),
Min (aPnt1.Y(), Min (aPnt2.Y(), aPnt3.Y())),
Min (aPnt1.Z(), Min (aPnt2.Z(), aPnt3.Z())));
aMaxPnt = SelectMgr_Vec3 (Max (aPnt1.X(), Max (aPnt2.X(), aPnt3.X())),
Max (aPnt1.Y(), Max (aPnt2.Y(), aPnt3.Y())),
Max (aPnt1.Z(), Max (aPnt2.Z(), aPnt3.Z())));
}
else
{
Standard_Integer aNodeIdx1 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx);
Standard_Integer aNodeIdx2 = myFreeEdges->Value (myFreeEdges->Lower() + aPrimIdx + 1);
gp_Pnt aNode1 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx1).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNodeIdx1);
gp_Pnt aNode2 = hasInitLoc ? myTriangul->Nodes().Value (aNodeIdx2).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNodeIdx2);
aMinPnt = SelectMgr_Vec3 (Min (aNode1.X(), aNode2.X()),
Min (aNode1.Y(), aNode2.Y()),
Min (aNode1.Z(), aNode2.Z()));
aMaxPnt = SelectMgr_Vec3 (Max (aNode1.X(), aNode2.X()),
Max (aNode1.Y(), aNode2.Y()),
Max (aNode1.Z(), aNode2.Z()));
}
return Select3D_BndBox3d (aMinPnt, aMaxPnt);
}
//=======================================================================
// function : Center
// purpose : Returns geometry center of triangle/edge with index theIdx
// in array along the given axis theAxis
//=======================================================================
Standard_Real Select3D_SensitiveTriangulation::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
{
const Select3D_BndBox3d& aBox = Box (theIdx);
SelectMgr_Vec3 aCenter = (aBox.CornerMin () + aBox.CornerMax ()) * 0.5;
return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z());
}
//=======================================================================
// function : Swap
// purpose : Swaps items with indexes theIdx1 and theIdx2 in array
//=======================================================================
void Select3D_SensitiveTriangulation::Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2)
{
Standard_Integer anElemIdx1 = myBVHPrimIndexes->Value (theIdx1);
Standard_Integer anElemIdx2 = myBVHPrimIndexes->Value (theIdx2);
myBVHPrimIndexes->ChangeValue (theIdx1) = anElemIdx2;
myBVHPrimIndexes->ChangeValue (theIdx2) = anElemIdx1;
}
//=======================================================================
// function : overlapsElement
// purpose : Checks whether the element with index theIdx overlaps the
// current selecting volume
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth)
{
const Standard_Integer& aPrimitiveIdx = myBVHPrimIndexes->Value (theElemIdx);
Standard_Boolean hasInitLoc = HasInitLocation();
if (mySensType == Select3D_TOS_BOUNDARY)
{
Standard_Integer aSegmStartIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 1);
Standard_Integer aSegmEndIdx = myFreeEdges->Value (aPrimitiveIdx * 2 + 2);
Handle(TColgp_HArray1OfPnt) anEdgePnts = new TColgp_HArray1OfPnt (1, 2);
gp_Pnt aSegmStart = hasInitLoc ? myTriangul->Nodes().Value (aSegmStartIdx).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aSegmStartIdx);
gp_Pnt aSegmEnd = hasInitLoc ? myTriangul->Nodes().Value (aSegmEndIdx).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aSegmEndIdx);
anEdgePnts->SetValue (1, aSegmStart);
anEdgePnts->SetValue (2, aSegmEnd);
Standard_Boolean isMatched = theMgr.Overlaps (anEdgePnts, Select3D_TOS_BOUNDARY, theMatchDepth);
anEdgePnts.Nullify();
return isMatched;
}
else
{
const Poly_Array1OfTriangle& aTriangles = myTriangul->Triangles();
Standard_Integer aNode1, aNode2, aNode3;
aTriangles (aPrimitiveIdx + 1).Get (aNode1, aNode2, aNode3);
gp_Pnt aPnt1 = hasInitLoc ? myTriangul->Nodes().Value (aNode1).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode1);
gp_Pnt aPnt2 = hasInitLoc ? myTriangul->Nodes().Value (aNode2).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode2);
gp_Pnt aPnt3 = hasInitLoc ? myTriangul->Nodes().Value (aNode3).Transformed (myInitLocation.Transformation())
: myTriangul->Nodes().Value (aNode3);
return theMgr.Overlaps (aPnt1, aPnt2, aPnt3, Select3D_TOS_INTERIOR, theMatchDepth);
}
}
//=======================================================================
// function : distanceToCOG
// purpose : Calculates distance from the 3d projection of used-picked
// screen point to center of the geometry
//=======================================================================
Standard_Real Select3D_SensitiveTriangulation::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
{
return theMgr.DistToGeometryCenter (myCDG3D);
}
//=======================================================================
//function : GetConnected
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation::
GetConnected(const TopLoc_Location& aLoc)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveTriangulation::GetConnected()
{
Handle(Select3D_SensitiveTriangulation) NiouEnt =
new Select3D_SensitiveTriangulation(myOwnerId,myTriangul,myiniloc,myFreeEdges,myCDG3D,myIntFlag);
Standard_Boolean isInterior = mySensType == Select3D_TOS_INTERIOR;
Handle(Select3D_SensitiveTriangulation) aNewEntity =
new Select3D_SensitiveTriangulation (myOwnerId, myTriangul, myInitLocation, myFreeEdges, myCDG3D, isInterior);
if(HasLocation())
NiouEnt->SetLocation(Location());
// TopLoc_Location TheLocToApply = HasLocation() ? Location()*aLoc : aLoc;
// if(!TheLocToApply.IsIdentity())
NiouEnt->UpdateLocation(aLoc);
return NiouEnt;
return aNewEntity;
}
//=======================================================================
//function : ResetLocation
//purpose :
// function : applyTransformation
// purpose : Inner function for transformation application to bounding
// box of the triangulation
//=======================================================================
void Select3D_SensitiveTriangulation::ResetLocation()
Select3D_BndBox3d Select3D_SensitiveTriangulation::applyTransformation()
{
Select3D_SensitiveEntity::ResetLocation();
ComputeTotalTrsf();
}
if (!HasInitLocation())
return myBndBox;
//=======================================================================
//function : SetLocation
//purpose :
//=======================================================================
void Select3D_SensitiveTriangulation::SetLocation(const TopLoc_Location& aLoc)
{
Select3D_SensitiveEntity::SetLocation(aLoc);
ComputeTotalTrsf();
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
{
S<<"\tSensitiveTriangulation 3D :"<<endl;
if(myiniloc.IsIdentity())
S<<"\t\tNo Initial Location"<<endl;
else
S<<"\t\tExisting Initial Location"<<endl;
if(HasLocation())
S<<"\t\tExisting Location"<<endl;
S<<"\t\tNb Triangles : "<<myTriangul->NbTriangles()<<endl;
S<<"\t\tNb Nodes : "<<myTriangul->NbNodes()<<endl;
S<<"\t\tNb Free Edges: "<<myFreeEdges->Length()/2<<endl;
if(FullDump)
Select3D_BndBox3d aBndBox;
for (Standard_Integer aX = 0; aX <=1; ++aX)
{
// S<<"\t\t\tOwner:"<<myOwnerId<<endl;
Select3D_SensitiveEntity::DumpBox(S,mybox2d);
}
}
//=======================================================================
//function : ComputeDepth
//purpose :
//=======================================================================
Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& thePickLine,
const Standard_Integer theTriangle) const
{
if (theTriangle == -1)
{
return Precision::Infinite(); // currently not implemented...
}
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
Standard_Integer n1,n2,n3;
triangles (theTriangle).Get (n1,n2,n3);
gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)};
if (myTrsf.Form() != gp_Identity)
{
for (Standard_Integer i =0; i<=2; i++)
for (Standard_Integer aY = 0; aY <=1; ++aY)
{
P[i].Transform (myTrsf);
for (Standard_Integer aZ = 0; aZ <= 1; ++aZ)
{
gp_Pnt aVertex = gp_Pnt (aX == 0 ? myBndBox.CornerMin().x() : myBndBox.CornerMax().x(),
aY == 0 ? myBndBox.CornerMin().y() : myBndBox.CornerMax().y(),
aZ == 0 ? myBndBox.CornerMin().z() : myBndBox.CornerMax().z());
aVertex.Transform (myInitLocation);
aBndBox.Add (Select3D_Vec3 (aVertex.X(), aVertex.Y(), aVertex.Z()));
}
}
}
// formula calculate the parameter of the point on the intersection
// t = (P1P2 ^P1P3)* OP1 / ((P1P2^P1P3)*Dir)
Standard_Real prof (Precision::Infinite());
gp_Pnt Oye = thePickLine.Location(); // origin of the target line eye/point...
gp_Dir Dir = thePickLine.Direction();
gp_Vec Vtr[3];
for (Standard_Integer i=0; i<=2; i++)
{
Vtr[i] = gp_Vec (P[i%3], P[(i+1)%3]);
}
Vtr[2] = -Vtr[2];
// remove singular cases immediately...
Standard_Integer SingularCase (-1);
if (Vtr[0].SquareMagnitude() <= Precision::Confusion())
{
SingularCase = 0;
}
if (Vtr[1].SquareMagnitude() <= Precision::Confusion())
{
SingularCase = (SingularCase == -1) ? 1 : 2;
}
if (Vtr[2].SquareMagnitude() <= Precision::Confusion())
{
if( SingularCase < 0 ) SingularCase = 1;
}
// 3 pts mixed...
if (SingularCase ==2)
{
prof = ElCLib::Parameter (thePickLine, P[0]);
return prof;
}
if (SingularCase!=0)
{
Vtr[0].Normalize();
}
if (SingularCase!=1 && SingularCase!=2)
{
Vtr[2].Normalize();
}
gp_Vec OPo (Oye, P[0]);
// 2 points mixed... the intersection between the segment and the target line eye/point.
if (SingularCase!=-1)
{
gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0];
gp_Vec Det = Dir^V;
gp_Vec VSM = OPo^V;
if (Det.X() > Precision::Confusion())
{
prof = VSM.X() / Det.X();
}
else if (Det.Y() > Precision::Confusion())
{
prof = VSM.Y() / Det.Y();
}
else if (Det.Z() > Precision::Confusion())
{
prof = VSM.Z() / Det.Z();
}
}
else
{
Standard_Real val1 = OPo.DotCross (Vtr[0], Vtr[2]);
Standard_Real val2 = Dir.DotCross (Vtr[0], Vtr[2]);
if (Abs (val2) > Precision::Confusion())
{
prof = val1 / val2;
}
}
if (prof == Precision::Infinite())
{
prof= ElCLib::Parameter (thePickLine, P[0]);
prof = Min (prof, ElCLib::Parameter (thePickLine, P[1]));
prof = Min (prof, ElCLib::Parameter (thePickLine, P[2]));
}
return prof;
return aBndBox;
}
//=======================================================================
//function : DetectedTriangle
//purpose :
// function : BoundingBox
// purpose : Returns bounding box of the triangulation. If location
// transformation is set, it will be applied
//=======================================================================
Standard_Boolean Select3D_SensitiveTriangulation::
DetectedTriangle(gp_Pnt& P1,
gp_Pnt& P2,
gp_Pnt& P3) const
Select3D_BndBox3d Select3D_SensitiveTriangulation::BoundingBox()
{
if(myDetectedTr==-1) return Standard_False; // currently not implemented...
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
Standard_Integer n1,n2,n3;
triangles(myDetectedTr).Get(n1,n2,n3);
if (myBndBox.IsValid())
return applyTransformation();
P1 = Nodes(n1);
P2 = Nodes(n2);
P3 = Nodes(n3);
if(myTrsf.Form()!=gp_Identity)
const Standard_Integer aLower = myTriangul->Nodes().Lower();
const Standard_Integer anUpper = myTriangul->Nodes().Upper();
Select3D_BndBox3d aBndBox;
for (Standard_Integer aNodeIdx = aLower; aNodeIdx <= anUpper; ++aNodeIdx)
{
P1.Transform(myTrsf);
P2.Transform(myTrsf);
P3.Transform(myTrsf);
const gp_Pnt& aNode = myTriangul->Nodes().Value (aNodeIdx);
const SelectMgr_Vec3 aNodeTransf = SelectMgr_Vec3 (aNode.X(), aNode.Y(), aNode.Z());
aBndBox.Add (aNodeTransf);
}
return Standard_True;
myBndBox = aBndBox;
return applyTransformation();
}
//=============================================================================
// Function : DetectedTriangle2d
// Purpose :
//=============================================================================
Standard_Boolean Select3D_SensitiveTriangulation::
DetectedTriangle2d(gp_Pnt2d& P1,
gp_Pnt2d& P2,
gp_Pnt2d& P3) const
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of triangulation. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_SensitiveTriangulation::CenterOfGeometry() const
{
if(myDetectedTr==-1)
return Standard_False; // currently not implemented...
const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
Standard_Integer n1,n2,n3;
triangles( myDetectedTr ).Get(n1,n2,n3);
int aLower = myNodes2d.Lower();
int anUpper = myNodes2d.Upper();
if ( n1 >= aLower && n1 <= anUpper &&
n2 >= aLower && n2 <= anUpper &&
n3 >= aLower && n3 <= anUpper )
{
P1 = myNodes2d.Value( n1 );
P2 = myNodes2d.Value( n2 );
P3 = myNodes2d.Value( n3 );
return Standard_True;
}
else
return Standard_False;
return HasInitLocation() ? myCDG3D.Transformed (myInitLocation) : myCDG3D;
}
//=============================================================================
// Function : ComputeTotalTrsf
// Purpose :
//=============================================================================
void Select3D_SensitiveTriangulation::ComputeTotalTrsf()
//=======================================================================
// function : NbSubElements
// purpose : Returns the amount of nodes in triangulation
//=======================================================================
Standard_Integer Select3D_SensitiveTriangulation::NbSubElements()
{
Standard_Boolean hasloc = (HasLocation() || !myiniloc.IsIdentity());
if(hasloc)
{
if(myiniloc.IsIdentity())
myTrsf = Location().Transformation();
else if(HasLocation())
{
myTrsf = (Location()*myiniloc).Transformation();
}
else
myTrsf = myiniloc.Transformation();
}
else
{
gp_Trsf TheId;
myTrsf = TheId;
}
return myTriangul->Nodes().Length();
}

View File

@@ -0,0 +1,154 @@
// Created on: 1997-05-15
// Created by: Robert COUBLANC
// Copyright (c) 1997-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.
//Modified Thur Apr 09 98 by rob : No more computation of free edges.
// fix bug on Compute Depth (don't forget
// Location...)
#ifndef _Select3D_SensitiveTriangulation_Header
#define _Select3D_SensitiveTriangulation_Header
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Handle_Poly_Triangulation.hxx>
#include <TopLoc_Location.hxx>
#include <gp_Trsf.hxx>
#include <gp_Pnt.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <Handle_TColStd_HArray1OfInteger.hxx>
#include <Standard_Boolean.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <SelectMgr_SelectingVolumeManager.hxx>
#include <Standard_OStream.hxx>
#include <Select3D_SensitiveSet.hxx>
#include <NCollection_Handle.hxx>
class Poly_Triangulation;
class TColStd_HArray1OfInteger;
class SelectBasics_EntityOwner;
class TopLoc_Location;
class gp_Pnt;
class Select3D_SensitiveEntity;
class Handle(Select3D_SensitiveEntity);
class TColgp_Array1OfPnt2d;
//! A framework to define selection of a sensitive entity made of a set of triangles.
class Select3D_SensitiveTriangulation : public Select3D_SensitiveSet
{
public:
//! Constructs a sensitive triangulation object defined by
//! the owner theOwnerId, the triangulation theTrg,
//! the location theInitLoc, and the flag theIsInterior.
Standard_EXPORT Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Poly_Triangulation)& theTrg,
const TopLoc_Location& theInitLoc,
const Standard_Boolean theIsInterior = Standard_True);
//! Constructs a sensitive triangulation object defined by
//! the owner theOwnerId, the triangulation theTrg,
//! the location theInitLoc, the array of free edges
//! theFreeEdges, the center of gravity theCOG, and the flag theIsInterior.
//! As free edges and the center of gravity do not have
//! to be computed later, this syntax reduces computation time.
Standard_EXPORT Select3D_SensitiveTriangulation (const Handle(SelectBasics_EntityOwner)& theOwnerId,
const Handle(Poly_Triangulation)& theTrg,
const TopLoc_Location& theInitLoc,
const Handle(TColStd_HArray1OfInteger)& theFreeEdges,
const gp_Pnt& theCOG,
const Standard_Boolean theIsInterior);
//! Returns the amount of nodes in triangulation
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
Standard_EXPORT Handle_Select3D_SensitiveEntity GetConnected() Standard_OVERRIDE;
const Handle_Poly_Triangulation& Triangulation() const;
Standard_Boolean HasInitLocation() const;
const TopLoc_Location& GetInitLocation() const;
//! Returns the length of array of triangles or edges
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns bounding box of triangle/edge with index theIdx
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
//! Returns geometry center of triangle/edge with index theIdx
//! in array along the given axis theAxis
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIdx1 and theIdx2 in array
Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2) Standard_OVERRIDE;
//! Returns bounding box of the triangulation. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of triangulation. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
public:
DEFINE_STANDARD_RTTI(Select3D_SensitiveTriangulation)
protected:
//! Inner function for transformation application to bounding
//! box of the triangulation
Select3D_BndBox3d applyTransformation();
private:
//! Checks whether the element with index theIdx overlaps the current selecting volume
virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth) Standard_OVERRIDE;
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
public:
Standard_Real myBVHBuildTime;
private:
Handle_Poly_Triangulation myTriangul;
TopLoc_Location myInitLocation;
gp_Pnt myCDG3D; //!< Center of the whole triangulation
Handle_TColStd_HArray1OfInteger myFreeEdges;
Standard_Boolean mySensType; //!< Type of sensitivity: boundary or interior
Standard_Integer myDetectedTr;
Standard_Integer myPrimitivesNb; //!< Amount of free edges or triangles depending on sensitivity type
Handle_TColStd_HArray1OfInteger myBVHPrimIndexes; //!< Indexes of edges or triangles for BVH build
mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveTriangulation, Select3D_SensitiveSet)
#include <Select3D_SensitiveTriangulation.lxx>
#endif // _Select3D_SensitiveTriangulation_Header

View File

@@ -14,29 +14,29 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//=======================================================================
//function : Triangulation
//purpose :
//=======================================================================
inline const Handle(Poly_Triangulation)& Select3D_SensitiveTriangulation::Triangulation() const
{
return myTriangul;
}
inline const gp_Pnt& Select3D_SensitiveTriangulation::CDG3D() const
{
return myCDG3D;
}
inline const gp_Pnt2d& Select3D_SensitiveTriangulation::CDG2D() const
{
return myCDG2D;
}
//=======================================================================
//function : HasInitLocation
//purpose :
//=======================================================================
inline Standard_Boolean Select3D_SensitiveTriangulation::HasInitLocation() const
{return !myiniloc.IsIdentity();}
inline const TopLoc_Location& Select3D_SensitiveTriangulation::GetInitLocation() const
{return myiniloc;}
inline Standard_Integer Select3D_SensitiveTriangulation::DetectedTriangle() const
{
return myDetectedTr;
return !myInitLocation.IsIdentity();
}
//=======================================================================
//function : GetInitLocation
//purpose :
//=======================================================================
inline const TopLoc_Location& Select3D_SensitiveTriangulation::GetInitLocation() const
{
return myInitLocation;
}

View File

@@ -1,124 +0,0 @@
-- Created on: 1996-10-17
-- Created by: Odile OLIVIER
-- Copyright (c) 1996-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.
class SensitiveWire from Select3D
inherits SensitiveEntity from Select3D
---Purpose: A framework to define selection of a wire owner by an
-- elastic wire band.
uses
Pnt from gp,
Projector from Select3D,
Lin from gp,
EntityOwner from SelectBasics,
SensitiveEntity from Select3D,
SensitiveEntitySequence from Select3D,
ListOfBox2d from SelectBasics,
PickArgs from SelectBasics,
Array1OfPnt2d from TColgp,
Box2d from Bnd,
Location from TopLoc
is
Create (OwnerId : EntityOwner from SelectBasics;
MaxRect : Integer = 1)
returns SensitiveWire;
---Purpose: Constructs a sensitive wire object defined by the
-- owner OwnerId, and the maximum number of
-- sensitive rectangles MaxRect.
Add (me :mutable;aSensitive : SensitiveEntity from Select3D)
is static;
---Purpose: Adds the sensitive entity aSensitive to this framework.
Project (me:mutable;aProjector : Projector from Select3D)
is redefined static;
---Level: Public
---Purpose: projection of the sensitive primitive in order to
-- get 2D boxes for the Sort Algorithm
Areas (me:mutable ; boxes : in out ListOfBox2d from SelectBasics)
is redefined static;
---Level: Public
---Purpose: gives the 2D boxes which represent the segment in the
-- selection process...
GetConnected(me:mutable;aLocation: Location from TopLoc)
returns SensitiveEntity from Select3D is redefined static;
GetEdges(me : mutable;
theEdges : in out SensitiveEntitySequence from Select3D);
---Level: Public
---Purpose: returns the sensitive edges stored in this wire
SetLocation(me:mutable;aLoc:Location from TopLoc) is redefined static;
---Purpose: propagation of location on all the sensitive inside...
ResetLocation(me:mutable) is redefined static;
---Purpose: propagation of location on all the sensitive inside...
Matches (me : mutable;
thePickArgs : PickArgs from SelectBasics;
theMatchDMin, theMatchDepth : out Real from Standard)
returns Boolean
is redefined static;
---Level: Public
---Purpose: Checks whether the sensitive entity matches the picking
-- detection area (close to the picking line).
-- For details please refer to base class declaration.
Matches (me :mutable;
XMin,YMin,XMax,YMax : Real from Standard;
aTol: Real from Standard)
returns Boolean
is static;
Matches (me :mutable;
Polyline:Array1OfPnt2d from TColgp;
aBox:Box2d from Bnd;
aTol: Real from Standard)
returns Boolean
is redefined virtual;
---Level: Public
MaxBoxes(me) returns Integer is redefined static;
---Level: Public
---Purpose:returns <mymaxrect>
Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static;
---Purpose: Sets the owner for all entities in wire
GetLastDetected(me)
returns SensitiveEntity from Select3D is static;
---Purpose:returns <mymaxrect>
fields
mysensitive : SensitiveEntitySequence from Select3D;
myDetectedIndex : Integer from Standard;
end SensitiveWire;

View File

@@ -14,206 +14,128 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <Select3D_SensitiveWire.ixx>
#include <SelectBasics_BasicTool.hxx>
#include <Select3D_SensitiveWire.hxx>
#include <Select3D_SensitiveEntity.hxx>
#include <Select3D_SensitiveEntitySequence.hxx>
#include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
#include <SelectBasics_ListOfBox2d.hxx>
#include <Precision.hxx>
#include <TopLoc_Location.hxx>
#include <Bnd_Box2d.hxx>
#include <ElCLib.hxx>
#include <Select3D_SensitiveSegment.hxx>
//static Standard_Boolean debugmode=Standard_False;
IMPLEMENT_STANDARD_HANDLE (Select3D_SensitiveWire, Select3D_SensitiveEntity)
IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveWire, Select3D_SensitiveEntity)
//=====================================================
// Function : Create
// Purpose :Constructor
// Function : Select3D_SensitiveWire
// Purpose :
//=====================================================
Select3D_SensitiveWire::
Select3D_SensitiveWire(const Handle(SelectBasics_EntityOwner)& OwnerId,
const Standard_Integer /*MaxRect*/):
Select3D_SensitiveEntity(OwnerId),
myDetectedIndex(-1)
Select3D_SensitiveWire::Select3D_SensitiveWire (const Handle(SelectBasics_EntityOwner)& theOwnerId)
: Select3D_SensitiveSet (theOwnerId),
myCenter (0.0, 0.0, 0.0)
{}
//=====================================================
// Function : Add
// Purpose :
//=====================================================
void Select3D_SensitiveWire
::Add(const Handle(Select3D_SensitiveEntity)& aSensitive)
void Select3D_SensitiveWire::Add (const Handle(Select3D_SensitiveEntity)& theSensitive)
{
if(!aSensitive.IsNull())
mysensitive.Append(aSensitive);
if (!theSensitive.IsNull())
myEntities.Append (theSensitive);
Select3D_BndBox3d aBndBox = theSensitive->BoundingBox();
myBndBox.Combine (aBndBox);
myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ();
if (myEntities.Length() != 1)
myCenter.ChangeCoord().Divide (2.0);
myEntityIndexes.Append (myEntities.Length() - 1);
}
//=======================================================================
//function : SetLocation
//purpose :
// function : NbSubElements
// purpose : Returns the amount of sub-entities
//=======================================================================
void Select3D_SensitiveWire::SetLocation(const TopLoc_Location& aLoc)
Standard_Integer Select3D_SensitiveWire::NbSubElements()
{
// evitons les problemes...
if(aLoc.IsIdentity()) return;
if(HasLocation())
if(aLoc == Location()) return;
Select3D_SensitiveEntity::SetLocation(aLoc);
for(Standard_Integer i=1;i<=mysensitive.Length();i++){
if(mysensitive(i)->HasLocation()){
if(mysensitive(i)->Location()!=aLoc)
mysensitive(i)->SetLocation(mysensitive(i)->Location()*aLoc);
}
else
mysensitive(i)->SetLocation(aLoc);
}
return myEntities.Length();
}
//=======================================================================
//function : ResetLocation
//purpose :
// function : Size
// purpose : Returns the length of vector of sensitive entities
//=======================================================================
void Select3D_SensitiveWire::ResetLocation()
Standard_Integer Select3D_SensitiveWire::Size() const
{
if(!HasLocation()) return;
for(Standard_Integer i=1;i<=mysensitive.Length();i++){
if(mysensitive(i)->HasLocation() && mysensitive(i)->Location()!=Location())
mysensitive(i)->SetLocation(mysensitive(i)->Location()*Location().Inverted());
else
mysensitive(i)->ResetLocation();
}
Select3D_SensitiveEntity::ResetLocation();
return myEntities.Length();
}
//=====================================================
// Function : Project
// Purpose :
//=====================================================
void Select3D_SensitiveWire::Project(const Handle(Select3D_Projector)& aProj)
//=======================================================================
// function : Box
// purpose : Returns bounding box of sensitive entity with index theIdx
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveWire::Box (const Standard_Integer theIdx) const
{
for (Standard_Integer aSensIt = 1; aSensIt <= mysensitive.Length(); aSensIt++)
const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx);
return myEntities.Value (aSensitiveIdx)->BoundingBox();
}
//=======================================================================
// function : Center
// purpose : Returns geometry center of sensitive entity with index
// theIdx in the vector along the given axis theAxis
//=======================================================================
Standard_Real Select3D_SensitiveWire::Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const
{
const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx);
const gp_Pnt& aCenter = myEntities.Value (aSensitiveIdx)->CenterOfGeometry();
Standard_Real aCenterCoord = 0.0;
aCenterCoord = theAxis == 0 ? aCenter.X() : (theAxis == 1 ? aCenter.Y() : aCenter.Z());
return aCenterCoord;
}
//=======================================================================
// function : Swap
// purpose : Swaps items with indexes theIdx1 and theIdx2 in the vector
//=======================================================================
void Select3D_SensitiveWire::Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2)
{
const Standard_Integer aSensitiveIdx1 = myEntityIndexes.Value (theIdx1);
const Standard_Integer aSensitiveIdx2 = myEntityIndexes.Value (theIdx2);
myEntityIndexes.ChangeValue (theIdx1) = aSensitiveIdx2;
myEntityIndexes.ChangeValue (theIdx2) = aSensitiveIdx1;
}
// =======================================================================
// function : overlapsElement
// purpose : Checks whether the entity with index theIdx overlaps the
// current selecting volume
// =======================================================================
Standard_Boolean Select3D_SensitiveWire::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth)
{
const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx);
const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx);
SelectBasics_PickResult aMatchResult;
if (aSeg->Matches (theMgr, aMatchResult))
{
mysensitive (aSensIt)->Project (aProj);
}
}
//=====================================================
// Function : Areas
// Purpose :
//=====================================================
void Select3D_SensitiveWire
::Areas(SelectBasics_ListOfBox2d& theareas)
{
Bnd_Box2d BB; // en attendant un nouveau champ rob-18-jun-97
SelectBasics_ListOfBox2d BidL;
Standard_Integer i;
for (i=1; i<=mysensitive.Length(); i++)
mysensitive.Value(i)->Areas(BidL);
for(SelectBasics_ListIteratorOfListOfBox2d it(BidL);it.More();it.Next())
BB.Add(it.Value());
theareas.Append(BB);
}
//=====================================================
// Function : Matches
// Purpose :
//=====================================================
Standard_Boolean Select3D_SensitiveWire::Matches (const SelectBasics_PickArgs& thePickArgs,
Standard_Real& theMatchDMin,
Standard_Real& theMatchDepth)
{
theMatchDMin = RealLast();
theMatchDepth = RealLast();
Standard_Real aSegDMin, aSegDepth;
Standard_Boolean isMatched = Standard_False;
myDetectedIndex = -1;
for (Standard_Integer aSegIt = 1; aSegIt <= mysensitive.Length(); aSegIt++)
{
const Handle(SelectBasics_SensitiveEntity)& aSeg = mysensitive.Value (aSegIt);
if (!aSeg->Matches (thePickArgs, aSegDMin, aSegDepth))
{
continue;
}
isMatched = Standard_True;
if (aSegDMin > theMatchDMin)
{
continue;
}
myDetectedIndex = aSegIt;
theMatchDMin = aSegDMin;
theMatchDepth = aSegDepth;
theMatchDepth = aMatchResult.Depth();
return Standard_True;
}
return isMatched;
return Standard_False;
}
//=====================================================
// Function : Matches
// Purpose :
//=====================================================
Standard_Boolean Select3D_SensitiveWire::
Matches (const Standard_Real XMin,
const Standard_Real YMin,
const Standard_Real XMax,
const Standard_Real YMax,
const Standard_Real aTol)
// =======================================================================
// function : distanceToCOG
// purpose : Calculates distance from the 3d projection of used-picked
// screen point to center of the geometry
// =======================================================================
Standard_Real Select3D_SensitiveWire::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
{
Standard_Integer i;
for (i=1; i<=mysensitive.Length(); i++)
{
if (!(mysensitive.Value(i)->Matches(XMin,YMin,XMax,YMax,aTol)))
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : Matches
//purpose :
//=======================================================================
Standard_Boolean Select3D_SensitiveWire::
Matches (const TColgp_Array1OfPnt2d& aPoly,
const Bnd_Box2d& aBox,
const Standard_Real aTol)
{
Standard_Integer i;
for (i=1; i<=mysensitive.Length(); i++)
{
if (!(mysensitive.Value(i)->Matches(aPoly, aBox, aTol)))
return Standard_False;
}
return Standard_True;
}
//=====================================================
// Function : MaxBoxes
// Purpose :
//=====================================================
Standard_Integer Select3D_SensitiveWire::
MaxBoxes () const
{
return 1;
return theMgr.DistToGeometryCenter (myCenter);
}
//=======================================================================
@@ -221,62 +143,37 @@ MaxBoxes () const
//purpose :
//=======================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected(const TopLoc_Location& aLoc)
Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected()
{
Handle(Select3D_SensitiveWire) SWIR = new Select3D_SensitiveWire(myOwnerId);
for(Standard_Integer i=1;i<=mysensitive.Length();i++)
SWIR->Add(mysensitive(i)->GetConnected(aLoc));
if(HasLocation())
SWIR->SetLocation(Location()*aLoc);
else
SWIR->SetLocation(aLoc);
return SWIR;
}
//=======================================================================
//function : Dump
//purpose :
//=======================================================================
void Select3D_SensitiveWire::Dump(Standard_OStream& S,const Standard_Boolean FullDump) const
{
S<<"\tSensitiveWire 3D :"<<endl;;
if(HasLocation())
S<<"\t\tExisting Location"<<endl;
S<<"\t\tComposed Of "<<mysensitive.Length()<<" Sensitive Entities"<<endl;
for(Standard_Integer i=1;i<= mysensitive.Length();i++){
S<<"Sensitive #"<<i<<" : "<<endl;
mysensitive(i)->Dump(S,FullDump);}
S<<"\tEnd Of Sensitive Wire"<<endl;
Handle(Select3D_SensitiveWire) aNewEntity = new Select3D_SensitiveWire (myOwnerId);
for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); anEntityIdx++)
aNewEntity->Add (myEntities(anEntityIdx)->GetConnected());
return aNewEntity;
}
//=======================================================================
//function : GetEdges
//purpose : returns the sensitive edges stored in this wire
//=======================================================================
void Select3D_SensitiveWire::GetEdges( Select3D_SensitiveEntitySequence& theEdges )
const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& Select3D_SensitiveWire::GetEdges()
{
theEdges.Clear();
theEdges.Append(mysensitive);
return myEntities;
}
//=============================================================================
// Function : GetLastDetected
// Purpose :
//=============================================================================
Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
{
Handle(Select3D_SensitiveEntity) aRes;
if ( myDetectedIndex >= 1 && myDetectedIndex <= mysensitive.Length() )
aRes = mysensitive.Value( myDetectedIndex );
if (myDetectedIdx >= 0 && myDetectedIdx < myEntities.Length())
{
const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (myDetectedIdx);
aRes = myEntities.Value (aSensitiveIdx);
}
return aRes;
}
@@ -285,14 +182,41 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
//function : Set
//purpose :
//=======================================================================
void Select3D_SensitiveWire::Set(const Handle(SelectBasics_EntityOwner) &TheOwnerId)
void Select3D_SensitiveWire::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId)
{
Select3D_SensitiveEntity::Set(TheOwnerId);
Select3D_SensitiveEntity::Set (theOwnerId);
// Set TheOwnerId for each element of sensitive wire
for (Standard_Integer i = 1; i <= mysensitive.Length(); ++i)
for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); ++anEntityIdx)
{
mysensitive.Value(i)->Set(TheOwnerId);
myEntities.Value (anEntityIdx)->Set (theOwnerId);
}
}
//=======================================================================
// function : BoundingBox
// purpose : Returns bounding box of the wire. If location
// transformation is set, it will be applied
//=======================================================================
Select3D_BndBox3d Select3D_SensitiveWire::BoundingBox()
{
if (myBndBox.IsValid())
return myBndBox;
for (Standard_Integer aSensitiveIdx = 0; aSensitiveIdx < myEntities.Length(); ++aSensitiveIdx)
{
myBndBox.Combine (myEntities.Value (aSensitiveIdx)->BoundingBox());
}
return myBndBox;
}
//=======================================================================
// function : CenterOfGeometry
// purpose : Returns center of the wire. If location transformation
// is set, it will be applied
//=======================================================================
gp_Pnt Select3D_SensitiveWire::CenterOfGeometry() const
{
return myCenter;
}

View File

@@ -0,0 +1,105 @@
// Created on: 1996-10-17
// Created by: Odile OLIVIER
// Copyright (c) 1996-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.
#ifndef _Select3D_SensitiveWire_HeaderFile
#define _Select3D_SensitiveWire_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Type.hxx>
#include <Select3D_SensitiveSet.hxx>
#include <Handle_SelectBasics_EntityOwner.hxx>
#include <Standard_OStream.hxx>
#include <NCollection_Sequence.hxx>
class SelectBasics_EntityOwner;
class TopLoc_Location;
class Select3D_SensitiveEntitySequence;
//! A framework to define selection of a wire owner by an
//! elastic wire band.
class Select3D_SensitiveWire : public Select3D_SensitiveSet
{
public:
//! Constructs a sensitive wire object defined by the
//! owner theOwnerId
Standard_EXPORT Select3D_SensitiveWire (const Handle(SelectBasics_EntityOwner)& theOwnerId);
//! Adds the sensitive entity theSensitive to this framework.
Standard_EXPORT void Add (const Handle(Select3D_SensitiveEntity)& theSensitive);
//! Returns the amount of sub-entities
Standard_EXPORT virtual Standard_Integer NbSubElements() Standard_OVERRIDE;
Standard_EXPORT virtual Handle(Select3D_SensitiveEntity) GetConnected() Standard_OVERRIDE;
//! returns the sensitive edges stored in this wire
Standard_EXPORT const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& GetEdges();
//! Sets the owner for all entities in wire
Standard_EXPORT void Set (const Handle(SelectBasics_EntityOwner)& theOwnerId);
Standard_EXPORT Handle_Select3D_SensitiveEntity GetLastDetected() const;
//! Returns bounding box of the wire. If location
//! transformation is set, it will be applied
Standard_EXPORT virtual Select3D_BndBox3d BoundingBox() Standard_OVERRIDE;
//! Returns center of the wire. If location transformation
//! is set, it will be applied
Standard_EXPORT virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE;
//! Returns the length of vector of sensitive entities
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
//! Returns bounding box of sensitive entity with index theIdx
Standard_EXPORT virtual Select3D_BndBox3d Box (const Standard_Integer theIdx) const Standard_OVERRIDE;
//! Returns geometry center of sensitive entity index theIdx in
//! the vector along the given axis theAxis
Standard_EXPORT virtual Standard_Real Center (const Standard_Integer theIdx,
const Standard_Integer theAxis) const Standard_OVERRIDE;
//! Swaps items with indexes theIdx1 and theIdx2 in the vector
Standard_EXPORT virtual void Swap (const Standard_Integer theIdx1,
const Standard_Integer theIdx2) Standard_OVERRIDE;
DEFINE_STANDARD_RTTI(Select3D_SensitiveWire)
protected:
//! Checks whether the entity with index theIdx overlaps the current selecting volume
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
Standard_Integer theElemIdx,
Standard_Real& theMatchDepth) Standard_OVERRIDE;
//! Calculates distance from the 3d projection of used-picked screen point to center of the geometry
Standard_EXPORT virtual Standard_Real distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) Standard_OVERRIDE;
private:
NCollection_Vector<Handle(Select3D_SensitiveEntity)> myEntities; //!< Vector of sub-entities
NCollection_Vector<Standard_Integer> myEntityIndexes; //!< Indexes of entities for BVH build
gp_Pnt myCenter; //!< Center of the whole wire
mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole wire
};
DEFINE_STANDARD_HANDLE(Select3D_SensitiveWire, Select3D_SensitiveEntity)
#endif // _Select3D_SensitiveWire_HeaderFile

View File

@@ -0,0 +1,15 @@
#ifndef _Select3D_TypeOfSensitivity_HeaderFile
#define _Select3D_TypeOfSensitivity_HeaderFile
#include <Standard_PrimitiveTypes.hxx>
//! Provides values for type of sensitivity in 3D.
//! These are used to specify whether it is the interior,
//! the boundary, or the exterior of a 3D sensitive entity which is sensitive.
enum Select3D_TypeOfSensitivity
{
Select3D_TOS_INTERIOR,
Select3D_TOS_BOUNDARY
};
#endif // _Select3D_TypeOfSensitivity_HeaderFile