Loading files
// 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>
#include <NCollection_Array1.hxx>
#include <NCollection_Shared.hxx>
#include <array>
//! 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 occ::handle<SelectMgr_EntityOwner>& theOwnerId);
//! Return patch size limit (1 by default).
int PatchSizeMax() const { return myPatchSizeMax; }
//! Assign patch size limit.
//! Should be set before initialization.
void SetPatchSizeMax(const int 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 occ::handle<Graphic3d_Buffer>& theVerts,
const occ::handle<Graphic3d_IndexBuffer>& theIndices,
const TopLoc_Location& theInitLoc,
const int theIndexLower,
const int theIndexUpper,
const bool theToEvalMinMax = true,
const int 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 occ::handle<Graphic3d_Buffer>& theVerts,
const occ::handle<Graphic3d_IndexBuffer>& theIndices,
const TopLoc_Location& theInitLoc,
const bool theToEvalMinMax = true,
const int theNbGroups = 1)
{
const int 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 occ::handle<Graphic3d_Buffer>& theVerts,
const occ::handle<Graphic3d_IndexBuffer>& theIndices,
const TopLoc_Location& theInitLoc,
const int theIndexLower,
const int theIndexUpper,
const bool theToEvalMinMax = true,
const int 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 occ::handle<Graphic3d_Buffer>& theVerts,
const occ::handle<Graphic3d_IndexBuffer>& theIndices,
const TopLoc_Location& theInitLoc,
const bool theToEvalMinMax = true,
const int theNbGroups = 1)
{
const int 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 occ::handle<Graphic3d_Buffer>& theVerts,
const TopLoc_Location& theInitLoc,
const bool theToEvalMinMax = true,
const int theNbGroups = 1)
{
const int anUpper = !theVerts.IsNull() ? (theVerts->NbElements - 1) : 0;
return InitPoints(theVerts,
occ::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(NCollection_Vec3<double>(theMinX, theMinY, theMinZ),
NCollection_Vec3<double>(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).
int LastDetectedElement() const { return myDetectedElem; }
//! Return the index map of last detected elements (rectangle selection).
const occ::handle<TColStd_HPackedMapOfInteger>& LastDetectedElementMap() const
{
return myDetectedElemMap;
}
//! Return last topmost detected node or -1 if undefined (axis picking).
int LastDetectedNode() const { return myDetectedNode; }
//! Return the index map of last detected nodes (rectangle selection).
const occ::handle<TColStd_HPackedMapOfInteger>& LastDetectedNodeMap() const
{
return myDetectedNodeMap;
}
//! Return the first node of last topmost detected edge or -1 if undefined (axis picking).
int LastDetectedEdgeNode1() const { return myDetectedEdgeNode1; }
//! Return the second node of last topmost detected edge or -1 if undefined (axis picking).
int LastDetectedEdgeNode2() const { return myDetectedEdgeNode2; }
//! Return the three vertex positions of the triangle at the given triangulation index.
//! Only meaningful for triangulation-based primitive arrays.
//! @param[in] theIndex zero-based triangle index within [0, triangle count)
Standard_EXPORT std::array<NCollection_Vec3<float>, 3> GetVertex(const int theIndex) const;
//! Dumps the content of me into the stream
Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const override;
public:
//! Checks whether the sensitive entity is overlapped by current selecting volume.
Standard_EXPORT bool Matches(SelectBasics_SelectingVolumeManager& theMgr,
SelectBasics_PickResult& thePickResult) override;
Standard_EXPORT occ::handle<Select3D_SensitiveEntity> GetConnected() override;
//! Returns the length of array of triangles or edges
Standard_EXPORT int Size() const override;
//! Returns the amount of nodes in triangulation
int NbSubElements() const override
{
return !myGroups.IsNull() ? myGroups->Length() : myBvhIndices.NbElements;
}
//! Returns bounding box of triangle/edge with index theIdx
Standard_EXPORT Select3D_BndBox3d Box(const int theIdx) const override;
//! Returns geometry center of triangle/edge with index theIdx
//! in array along the given axis theAxis
Standard_EXPORT double Center(const int theIdx, const int theAxis) const override;
//! Swaps items with indexes theIdx1 and theIdx2 in array
Standard_EXPORT void Swap(const int theIdx1, const int theIdx2) override;
//! Returns bounding box of the triangulation. If location
//! transformation is set, it will be applied
Standard_EXPORT Select3D_BndBox3d BoundingBox() override;
//! Returns center of triangulation. If location transformation
//! is set, it will be applied
gp_Pnt CenterOfGeometry() const override { return myCDG3D; }
//! Returns true if the shape corresponding to the entity has init location
bool HasInitLocation() const override { return !myInitLocation.IsIdentity(); }
//! Returns inversed location transformation matrix if the shape corresponding
//! to this entity has init location set. Otherwise, returns identity matrix.
gp_GTrsf InvInitLocation() const override { return myInvInitLocation; }
//! Sets the owner for all entities in group
Standard_EXPORT void Set(const occ::handle<SelectMgr_EntityOwner>& theOwnerId) override;
//! Builds BVH tree for sensitive set.
Standard_EXPORT void BVH() 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 NCollection_Vec3<float>& getPosVec3(const int theIndex) const
{
return *reinterpret_cast<const NCollection_Vec3<float>*>(myPosData + myPosStride * theIndex);
}
//! Auxiliary getter.
const NCollection_Vec2<float>& getPosVec2(const int theIndex) const
{
return *reinterpret_cast<const NCollection_Vec2<float>*>(myPosData + myPosStride * theIndex);
}
//! Checks whether the element with index theIdx overlaps the current selecting volume
Standard_EXPORT bool overlapsElement(SelectBasics_PickResult& thePickResult,
SelectBasics_SelectingVolumeManager& theMgr,
int theElemIdx,
bool theIsFullInside) override;
//! Calculates distance from the 3d projection of used-picked screen point to center of the
//! geometry
Standard_EXPORT double distanceToCOG(SelectBasics_SelectingVolumeManager& theMgr) override;
//! Checks whether the entity with index theIdx is inside the current selecting volume
Standard_EXPORT bool elementIsInside(SelectBasics_SelectingVolumeManager& theMgr,
int theElemIdx,
bool theIsFullInside) override;
private:
typedef NCollection_Shared<NCollection_Array1<occ::handle<Select3D_SensitivePrimitiveArray>>>
Select3D_PrimArraySubGroupArray;
struct Select3D_SensitivePrimitiveArray_InitFunctor;
struct Select3D_SensitivePrimitiveArray_BVHFunctor;
private:
occ::handle<Select3D_PrimArraySubGroupArray> myGroups; //!< sub-groups of sensitive entities
occ::handle<Graphic3d_Buffer> myVerts; //!< source data - nodes position
occ::handle<Graphic3d_IndexBuffer> myIndices; //!< source data - primitive indexes
const uint8_t* myPosData; //!< position vertex attribute data
// clang-format off
size_t myPosStride; //!< position vertex attribute stride in bytes
Graphic3d_TypeOfPrimitiveArray myPrimType; //!< primitives type
int myIndexLower; //!< index range - first index in myIndices (inclusive)
int myIndexUpper; //!< index range - last index in myIndices (inclusive)
int 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;
occ::handle<TColStd_HPackedMapOfInteger> myDetectedElemMap; //!< index map of last detected elements
occ::handle<TColStd_HPackedMapOfInteger> myDetectedNodeMap; //!< index map of last detected nodes
double myMinDepthElem; //!< the depth of nearest detected element
double myMinDepthNode; //!< the depth of nearest detected node
double myMinDepthEdge; //!< the depth of nearest detected edge
int myDetectedElem; //!< index of last detected element
int myDetectedNode; //!< index of last detected node
int myDetectedEdgeNode1; //!< index of last detected edge node 1
int 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
// clang-format on
public:
DEFINE_STANDARD_RTTIEXT(Select3D_SensitivePrimitiveArray, Select3D_SensitiveSet)
};
#endif // _Select3D_SensitivePrimitiveArray_Header
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.