mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-15 11:44:07 +03:00
342 lines
19 KiB
C++
342 lines
19 KiB
C++
// Created on: 2016-02-20
|
|
// Created by: Kirill Gavrilov
|
|
// Copyright (c) 2016 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_SensitivePrimitiveArray_Header
|
|
#define _Select3D_SensitivePrimitiveArray_Header
|
|
|
|
#include <Graphic3d_IndexBuffer.hxx>
|
|
#include <Graphic3d_TypeOfPrimitiveArray.hxx>
|
|
#include <Select3D_SensitiveSet.hxx>
|
|
#include <Select3D_BVHIndexBuffer.hxx>
|
|
#include <TColStd_HPackedMapOfInteger.hxx>
|
|
|
|
//! Sensitive for triangulation or point set defined by Primitive Array.
|
|
//! The primitives can be optionally combined into patches within BVH tree
|
|
//! to reduce its building time in expense of extra traverse time.
|
|
class Select3D_SensitivePrimitiveArray : public Select3D_SensitiveSet
|
|
{
|
|
|
|
public:
|
|
|
|
//! Constructs an empty sensitive object.
|
|
Standard_EXPORT Select3D_SensitivePrimitiveArray (const Handle(SelectMgr_EntityOwner)& theOwnerId);
|
|
|
|
//! Return patch size limit (1 by default).
|
|
Standard_Integer PatchSizeMax() const { return myPatchSizeMax; }
|
|
|
|
//! Assign patch size limit.
|
|
//! Should be set before initialization.
|
|
void SetPatchSizeMax (const Standard_Integer thePatchSizeMax) { myPatchSizeMax = thePatchSizeMax; }
|
|
|
|
//! Maximum allowed distance between consequential elements in patch (ShortRealLast() by default).
|
|
//! Has no effect on indexed triangulation.
|
|
float PatchDistance() const { return myPatchDistance; }
|
|
|
|
//! Assign patch distance limit.
|
|
//! Should be set before initialization.
|
|
void SetPatchDistance (const float thePatchDistMax) { myPatchDistance = thePatchDistMax; }
|
|
|
|
//! Initialize the sensitive object from triangualtion.
|
|
//! The sub-triangulation can be specified by arguments theIndexLower and theIndexUpper
|
|
//! (these are for iterating theIndices, not to restrict the actual index values!).
|
|
//! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
|
|
//! @param theIndices index array defining triangulation
|
|
//! @param theInitLoc location
|
|
//! @param theIndexLower the theIndices range - first value (inclusive), starting from 0 and multiple by 3
|
|
//! @param theIndexUpper the theIndices range - last value (inclusive), upto theIndices->NbElements-1 and multiple by 3
|
|
//! @param theToEvalMinMax compute bounding box within initialization
|
|
//! @param theNbGroups number of groups to split the vertex array into several parts
|
|
Standard_EXPORT bool InitTriangulation (const Handle(Graphic3d_Buffer)& theVerts,
|
|
const Handle(Graphic3d_IndexBuffer)& theIndices,
|
|
const TopLoc_Location& theInitLoc,
|
|
const Standard_Integer theIndexLower,
|
|
const Standard_Integer theIndexUpper,
|
|
const bool theToEvalMinMax = true,
|
|
const Standard_Integer theNbGroups = 1);
|
|
|
|
//! Initialize the sensitive object from triangualtion.
|
|
//! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
|
|
//! @param theIndices index array defining triangulation
|
|
//! @param theInitLoc location
|
|
//! @param theToEvalMinMax compute bounding box within initialization
|
|
//! @param theNbGroups number of groups to split the vertex array into several parts
|
|
bool InitTriangulation (const Handle(Graphic3d_Buffer)& theVerts,
|
|
const Handle(Graphic3d_IndexBuffer)& theIndices,
|
|
const TopLoc_Location& theInitLoc,
|
|
const bool theToEvalMinMax = true,
|
|
const Standard_Integer theNbGroups = 1)
|
|
{
|
|
const Standard_Integer anUpper = !theIndices.IsNull() ? (theIndices->NbElements - 1)
|
|
: (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0);
|
|
return InitTriangulation (theVerts, theIndices, theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups);
|
|
}
|
|
|
|
//! Initialize the sensitive object from point set.
|
|
//! The sub-set of points can be specified by arguments theIndexLower and theIndexUpper
|
|
//! (these are for iterating theIndices, not to restrict the actual index values!).
|
|
//! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
|
|
//! @param theIndices index array defining points
|
|
//! @param theInitLoc location
|
|
//! @param theIndexLower the theIndices range - first value (inclusive), starting from 0
|
|
//! @param theIndexUpper the theIndices range - last value (inclusive), upto theIndices->NbElements-1
|
|
//! @param theToEvalMinMax compute bounding box within initialization
|
|
//! @param theNbGroups number of groups to split the vertex array into several parts
|
|
Standard_EXPORT bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts,
|
|
const Handle(Graphic3d_IndexBuffer)& theIndices,
|
|
const TopLoc_Location& theInitLoc,
|
|
const Standard_Integer theIndexLower,
|
|
const Standard_Integer theIndexUpper,
|
|
const bool theToEvalMinMax = true,
|
|
const Standard_Integer theNbGroups = 1);
|
|
|
|
//! Initialize the sensitive object from point set.
|
|
//! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
|
|
//! @param theIndices index array to define subset of points
|
|
//! @param theInitLoc location
|
|
//! @param theToEvalMinMax compute bounding box within initialization
|
|
//! @param theNbGroups number of groups to split the vertex array into several parts
|
|
bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts,
|
|
const Handle(Graphic3d_IndexBuffer)& theIndices,
|
|
const TopLoc_Location& theInitLoc,
|
|
const bool theToEvalMinMax = true,
|
|
const Standard_Integer theNbGroups = 1)
|
|
{
|
|
const Standard_Integer anUpper = !theIndices.IsNull() ? (theIndices->NbElements - 1)
|
|
: (!theVerts.IsNull() ? (theVerts->NbElements - 1) : 0);
|
|
return InitPoints (theVerts, theIndices, theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups);
|
|
}
|
|
|
|
//! Initialize the sensitive object from point set.
|
|
//! @param theVerts attributes array containing Graphic3d_TOA_POS with type Graphic3d_TOD_VEC3 or Graphic3d_TOD_VEC2
|
|
//! @param theInitLoc location
|
|
//! @param theToEvalMinMax compute bounding box within initialization
|
|
//! @param theNbGroups number of groups to split the vertex array into several parts
|
|
bool InitPoints (const Handle(Graphic3d_Buffer)& theVerts,
|
|
const TopLoc_Location& theInitLoc,
|
|
const bool theToEvalMinMax = true,
|
|
const Standard_Integer theNbGroups = 1)
|
|
{
|
|
const Standard_Integer anUpper = !theVerts.IsNull() ? (theVerts->NbElements - 1) : 0;
|
|
return InitPoints (theVerts, Handle(Graphic3d_IndexBuffer)(), theInitLoc, 0, anUpper, theToEvalMinMax, theNbGroups);
|
|
}
|
|
|
|
//! Assign new not transformed bounding box.
|
|
void SetMinMax (double theMinX, double theMinY, double theMinZ,
|
|
double theMaxX, double theMaxY, double theMaxZ)
|
|
{
|
|
myBndBox = Select3D_BndBox3d (SelectMgr_Vec3 (theMinX, theMinY, theMinZ),
|
|
SelectMgr_Vec3 (theMaxX, theMaxY, theMaxZ));
|
|
if (!myGroups.IsNull())
|
|
{
|
|
for (Select3D_PrimArraySubGroupArray::Iterator aGroupIter (*myGroups); aGroupIter.More(); aGroupIter.Next())
|
|
{
|
|
aGroupIter.Value()->myBndBox = myBndBox;
|
|
}
|
|
}
|
|
}
|
|
|
|
//! Return flag to keep index of last topmost detected element, TRUE by default.
|
|
bool ToDetectElements() const { return myToDetectElem; }
|
|
|
|
//! Setup keeping of the index of last topmost detected element (axis picking).
|
|
void SetDetectElements (bool theToDetect) { myToDetectElem = theToDetect; }
|
|
|
|
//! Return flag to keep index map of last detected elements, FALSE by default (rectangle selection).
|
|
bool ToDetectElementMap() const { return !myDetectedElemMap.IsNull(); }
|
|
|
|
//! Setup keeping of the index map of last detected elements (rectangle selection).
|
|
Standard_EXPORT void SetDetectElementMap (bool theToDetect);
|
|
|
|
//! Return flag to keep index of last topmost detected node, FALSE by default.
|
|
bool ToDetectNodes() const { return myToDetectNode; }
|
|
|
|
//! Setup keeping of the index of last topmost detected node (for axis picking).
|
|
void SetDetectNodes (bool theToDetect) { myToDetectNode = theToDetect; }
|
|
|
|
//! Return flag to keep index map of last detected nodes, FALSE by default (rectangle selection).
|
|
bool ToDetectNodeMap() const { return !myDetectedNodeMap.IsNull(); }
|
|
|
|
//! Setup keeping of the index map of last detected nodes (rectangle selection).
|
|
Standard_EXPORT void SetDetectNodeMap (bool theToDetect);
|
|
|
|
//! Return flag to keep index of last topmost detected edge, FALSE by default.
|
|
bool ToDetectEdges() const { return myToDetectEdge; }
|
|
|
|
//! Setup keeping of the index of last topmost detected edge (axis picking).
|
|
void SetDetectEdges (bool theToDetect) { myToDetectEdge = theToDetect; }
|
|
|
|
//! Return last topmost detected element or -1 if undefined (axis picking).
|
|
Standard_Integer LastDetectedElement() const { return myDetectedElem; }
|
|
|
|
//! Return the index map of last detected elements (rectangle selection).
|
|
const Handle(TColStd_HPackedMapOfInteger)& LastDetectedElementMap() const { return myDetectedElemMap; }
|
|
|
|
//! Return last topmost detected node or -1 if undefined (axis picking).
|
|
Standard_Integer LastDetectedNode() const { return myDetectedNode; }
|
|
|
|
//! Return the index map of last detected nodes (rectangle selection).
|
|
const Handle(TColStd_HPackedMapOfInteger)& LastDetectedNodeMap() const { return myDetectedNodeMap; }
|
|
|
|
//! Return the first node of last topmost detected edge or -1 if undefined (axis picking).
|
|
Standard_Integer LastDetectedEdgeNode1() const { return myDetectedEdgeNode1; }
|
|
|
|
//! Return the second node of last topmost detected edge or -1 if undefined (axis picking).
|
|
Standard_Integer LastDetectedEdgeNode2() const { return myDetectedEdgeNode2; }
|
|
|
|
//! Dumps the content of me into the stream
|
|
Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const Standard_OVERRIDE;
|
|
|
|
public:
|
|
|
|
//! Checks whether the sensitive entity is overlapped by 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 the length of array of triangles or edges
|
|
Standard_EXPORT virtual Standard_Integer Size() const Standard_OVERRIDE;
|
|
|
|
//! Returns the amount of nodes in triangulation
|
|
virtual Standard_Integer NbSubElements() const Standard_OVERRIDE
|
|
{
|
|
return !myGroups.IsNull() ? myGroups->Size() : myBvhIndices.NbElements;
|
|
}
|
|
|
|
//! 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
|
|
virtual gp_Pnt CenterOfGeometry() const Standard_OVERRIDE
|
|
{
|
|
return myCDG3D;
|
|
}
|
|
|
|
//! Returns true if the shape corresponding to the entity has init location
|
|
virtual Standard_Boolean HasInitLocation() const Standard_OVERRIDE
|
|
{
|
|
return !myInitLocation.IsIdentity();
|
|
}
|
|
|
|
//! Returns inversed location transformation matrix if the shape corresponding
|
|
//! to this entity has init location set. Otherwise, returns identity matrix.
|
|
virtual gp_GTrsf InvInitLocation() const Standard_OVERRIDE
|
|
{
|
|
return myInvInitLocation;
|
|
}
|
|
|
|
//! Sets the owner for all entities in group
|
|
Standard_EXPORT virtual void Set (const Handle(SelectMgr_EntityOwner)& theOwnerId) Standard_OVERRIDE;
|
|
|
|
//! Builds BVH tree for sensitive set.
|
|
Standard_EXPORT virtual void BVH() Standard_OVERRIDE;
|
|
|
|
protected:
|
|
|
|
//! Compute bounding box.
|
|
Standard_EXPORT void computeBoundingBox();
|
|
|
|
//! Inner function for transformation application to bounding
|
|
//! box of the triangulation
|
|
Standard_EXPORT Select3D_BndBox3d applyTransformation();
|
|
|
|
//! Auxiliary getter.
|
|
const Graphic3d_Vec3& getPosVec3 (const Standard_Integer theIndex) const
|
|
{
|
|
return *reinterpret_cast<const Graphic3d_Vec3* >(myPosData + myPosStride * theIndex);
|
|
}
|
|
|
|
//! Auxiliary getter.
|
|
const Graphic3d_Vec2& getPosVec2 (const Standard_Integer theIndex) const
|
|
{
|
|
return *reinterpret_cast<const Graphic3d_Vec2* >(myPosData + myPosStride * theIndex);
|
|
}
|
|
|
|
//! Checks whether the element with index theIdx overlaps the current selecting volume
|
|
Standard_EXPORT virtual Standard_Boolean overlapsElement (SelectBasics_PickResult& thePickResult,
|
|
SelectBasics_SelectingVolumeManager& theMgr,
|
|
Standard_Integer theElemIdx,
|
|
Standard_Boolean theIsFullInside) 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;
|
|
|
|
//! Checks whether the entity with index theIdx is inside the current selecting volume
|
|
Standard_EXPORT virtual Standard_Boolean elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
|
|
Standard_Integer theElemIdx,
|
|
Standard_Boolean theIsFullInside) Standard_OVERRIDE;
|
|
|
|
private:
|
|
|
|
typedef NCollection_Shared<NCollection_Array1<Handle(Select3D_SensitivePrimitiveArray)> > Select3D_PrimArraySubGroupArray;
|
|
struct Select3D_SensitivePrimitiveArray_InitFunctor;
|
|
struct Select3D_SensitivePrimitiveArray_BVHFunctor;
|
|
|
|
private:
|
|
|
|
Handle(Select3D_PrimArraySubGroupArray) myGroups; //!< sub-groups of sensitive entities
|
|
|
|
Handle(Graphic3d_Buffer) myVerts; //!< source data - nodes position
|
|
Handle(Graphic3d_IndexBuffer) myIndices; //!< source data - primitive indexes
|
|
const Standard_Byte* myPosData; //!< position vertex attribute data
|
|
Standard_Size myPosStride; //!< position vertex attribute stride in bytes
|
|
Graphic3d_TypeOfPrimitiveArray myPrimType; //!< primitives type
|
|
Standard_Integer myIndexLower; //!< index range - first index in myIndices (inclusive)
|
|
Standard_Integer myIndexUpper; //!< index range - last index in myIndices (inclusive)
|
|
Standard_Integer myPatchSizeMax; //!< patch size limit (1 by default)
|
|
float myPatchDistance; //!< distance between elements in patch
|
|
bool myIs3d; //!< flag indicating that position attribute has 3 components
|
|
TopLoc_Location myInitLocation;
|
|
gp_Pnt myCDG3D; //!< Center of the whole triangulation
|
|
Select3D_BVHIndexBuffer myBvhIndices; //!< Indexes of edges or triangles for BVH tree
|
|
mutable Select3D_BndBox3d myBndBox; //!< Bounding box of the whole triangulation
|
|
gp_GTrsf myInvInitLocation;
|
|
Handle(TColStd_HPackedMapOfInteger) myDetectedElemMap; //!< index map of last detected elements
|
|
Handle(TColStd_HPackedMapOfInteger) myDetectedNodeMap; //!< index map of last detected nodes
|
|
Standard_Real myMinDepthElem; //!< the depth of nearest detected element
|
|
Standard_Real myMinDepthNode; //!< the depth of nearest detected node
|
|
Standard_Real myMinDepthEdge; //!< the depth of nearest detected edge
|
|
Standard_Integer myDetectedElem; //!< index of last detected element
|
|
Standard_Integer myDetectedNode; //!< index of last detected node
|
|
Standard_Integer myDetectedEdgeNode1; //!< index of last detected edge node 1
|
|
Standard_Integer myDetectedEdgeNode2; //!< index of last detected edge node 2
|
|
bool myToDetectElem; //!< flag to keep info about last detected element
|
|
bool myToDetectNode; //!< flag to keep info about last detected node
|
|
bool myToDetectEdge; //!< flag to keep info about last detected edge
|
|
|
|
public:
|
|
|
|
DEFINE_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
|
|
|
|
};
|
|
|
|
DEFINE_STANDARD_HANDLE(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
|
|
|
|
#endif // _Select3D_SensitivePrimitiveArray_Header
|