+ Improve mesh selection (precompute projection matrix and use polygon bounding box)
This commit is contained in:
@@ -51,6 +51,7 @@ Base::Vector3f ViewVolumeProjection::operator()(const Base::Vector3f &pt) const
|
||||
pt3d.setValue(ptt.x, ptt.y, ptt.z);
|
||||
}
|
||||
|
||||
// Calling this function is expensive as the complete projection matrix is recomputed on each step
|
||||
viewVolume.projectToScreen(pt3d,pt3d);
|
||||
return Base::Vector3f(pt3d[0],pt3d[1],pt3d[2]);
|
||||
}
|
||||
@@ -101,12 +102,26 @@ Base::Matrix4D ViewVolumeProjection::getProjectionMatrix () const
|
||||
// Inventor stores the transposed matrix
|
||||
Base::Matrix4D mat;
|
||||
SbMatrix affine, proj;
|
||||
|
||||
// The Inventor projection matrix is obtained by multiplying both matrices together (cf source)
|
||||
viewVolume.getMatrices(affine, proj);
|
||||
SbMatrix pmatrix = affine.multRight(proj);
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<4; j++)
|
||||
mat[i][j] = proj[j][i];
|
||||
mat[i][j] = pmatrix[j][i];
|
||||
}
|
||||
|
||||
// Compose the object transform, if defined
|
||||
if (hasTransform) {
|
||||
mat = mat * transform;
|
||||
}
|
||||
|
||||
// Scale from [-1,1] to [0,1]
|
||||
// As done in OpenInventor sources (see SbDPViewVolume::projectToScreen)
|
||||
mat.scale(0.5, 0.5, 0.5);
|
||||
mat.move(0.5, 0.5, 0.5);
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
@@ -1083,23 +1083,24 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr
|
||||
Base::Vector3f clPt2d;
|
||||
Base::Vector3f clGravityOfFacet;
|
||||
bool bNoPointInside;
|
||||
// Cache current view projection matrix since calls to COIN's projection are expensive
|
||||
Base::ViewProjMatrix fixedProj(pclProj->getProjectionMatrix());
|
||||
// Precompute the polygon's bounding box
|
||||
Base::BoundBox2d clPolyBBox = rclPoly.CalcBoundBox();
|
||||
|
||||
// Falls true, verwende Grid auf Mesh, um Suche zu beschleunigen
|
||||
if (bInner)
|
||||
{
|
||||
BoundBox3f clBBox3d;
|
||||
BoundBox2d clViewBBox, clPolyBBox;
|
||||
BoundBox2d clViewBBox;
|
||||
std::vector<unsigned long> aulAllElements;
|
||||
|
||||
//B-Box des Polygons
|
||||
clPolyBBox = rclPoly.CalcBoundBox();
|
||||
// Iterator fuer die zu durchsuchenden B-Boxen des Grids
|
||||
MeshGridIterator clGridIter(rclGrid);
|
||||
// alle B-Boxen durchlaufen und die Facets speichern
|
||||
for (clGridIter.Init(); clGridIter.More(); clGridIter.Next())
|
||||
{
|
||||
clBBox3d = clGridIter.GetBoundBox();
|
||||
clViewBBox = clBBox3d.ProjectBox(pclProj);
|
||||
clViewBBox = clBBox3d.ProjectBox(&fixedProj);
|
||||
if (clViewBBox.Intersect(clPolyBBox))
|
||||
{
|
||||
// alle Elemente in AllElements sammeln
|
||||
@@ -1119,9 +1120,10 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr
|
||||
MeshGeomFacet rclFacet = _rclMesh.GetFacet(*it);
|
||||
for (int j=0; j<3; j++)
|
||||
{
|
||||
clPt2d = pclProj->operator()(rclFacet._aclPoints[j]);
|
||||
clPt2d = fixedProj(rclFacet._aclPoints[j]);
|
||||
clGravityOfFacet += clPt2d;
|
||||
if (rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) == bInner)
|
||||
if ((clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) &&
|
||||
rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y))) ^ !bInner)
|
||||
{
|
||||
raulFacets.push_back(*it);
|
||||
bNoPointInside = false;
|
||||
@@ -1134,8 +1136,9 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr
|
||||
{
|
||||
clGravityOfFacet *= 1.0f/3.0f;
|
||||
|
||||
if (rclPoly.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y)) == bInner)
|
||||
raulFacets.push_back(*it);
|
||||
if ((clPolyBBox.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y)) &&
|
||||
rclPoly.Contains(Base::Vector2d(clGravityOfFacet.x, clGravityOfFacet.y))) ^ !bInner)
|
||||
raulFacets.push_back(*it);
|
||||
}
|
||||
|
||||
seq.next();
|
||||
@@ -1144,20 +1147,21 @@ void MeshAlgorithm::CheckFacets(const MeshFacetGrid& rclGrid, const Base::ViewPr
|
||||
// Dreiecke ausserhalb schneiden, dann alles durchsuchen
|
||||
else
|
||||
{
|
||||
Base::SequencerLauncher seq("Check facets", _rclMesh.CountFacets());
|
||||
for (clIter.Init(); clIter.More(); clIter.Next())
|
||||
{
|
||||
for (int j=0; j<3; j++)
|
||||
{
|
||||
clPt2d = pclProj->operator()(clIter->_aclPoints[j]);
|
||||
if (rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) == bInner)
|
||||
{
|
||||
raulFacets.push_back(clIter.Position());
|
||||
break;
|
||||
}
|
||||
}
|
||||
seq.next();
|
||||
}
|
||||
Base::SequencerLauncher seq("Check facets", _rclMesh.CountFacets());
|
||||
for (clIter.Init(); clIter.More(); clIter.Next())
|
||||
{
|
||||
for (int j=0; j<3; j++)
|
||||
{
|
||||
clPt2d = fixedProj(clIter->_aclPoints[j]);
|
||||
if ((clPolyBBox.Contains(Base::Vector2d(clPt2d.x, clPt2d.y)) &&
|
||||
rclPoly.Contains(Base::Vector2d(clPt2d.x, clPt2d.y))) ^ !bInner)
|
||||
{
|
||||
raulFacets.push_back(clIter.Position());
|
||||
break;
|
||||
}
|
||||
}
|
||||
seq.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1167,11 +1171,19 @@ void MeshAlgorithm::CheckFacets(const Base::ViewProjMethod* pclProj, const Base:
|
||||
const MeshPointArray& p = _rclMesh.GetPoints();
|
||||
const MeshFacetArray& f = _rclMesh.GetFacets();
|
||||
Base::Vector3f pt2d;
|
||||
// Use a bounding box to reduce number of call to Polygon::Contains
|
||||
Base::BoundBox2d bb = rclPoly.CalcBoundBox();
|
||||
// Precompute the screen projection matrix as COIN's projection function is expensive
|
||||
Base::Matrix4D pmat = pclProj->getProjectionMatrix();
|
||||
|
||||
unsigned long index=0;
|
||||
for (MeshFacetArray::_TConstIterator it = f.begin(); it != f.end(); ++it,++index) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
pt2d = (*pclProj)(p[it->_aulPoints[i]]);
|
||||
if (rclPoly.Contains(Base::Vector2d(pt2d.x, pt2d.y)) == bInner) {
|
||||
pt2d = pmat * p[it->_aulPoints[i]];
|
||||
|
||||
// First check whether the point is in the bounding box of the polygon
|
||||
if ((bb.Contains(Base::Vector2d(pt2d.x, pt2d.y)) &&
|
||||
rclPoly.Contains(Base::Vector2d(pt2d.x, pt2d.y))) ^ !bInner) {
|
||||
raulFacets.push_back(index);
|
||||
break;
|
||||
}
|
||||
@@ -1181,13 +1193,13 @@ void MeshAlgorithm::CheckFacets(const Base::ViewProjMethod* pclProj, const Base:
|
||||
|
||||
float MeshAlgorithm::Surface (void) const
|
||||
{
|
||||
float fTotal = 0.0f;
|
||||
MeshFacetIterator clFIter(_rclMesh);
|
||||
float fTotal = 0.0f;
|
||||
MeshFacetIterator clFIter(_rclMesh);
|
||||
|
||||
for (clFIter.Init(); clFIter.More(); clFIter.Next())
|
||||
fTotal += clFIter->Area();
|
||||
|
||||
return fTotal;
|
||||
for (clFIter.Init(); clFIter.More(); clFIter.Next())
|
||||
fTotal += clFIter->Area();
|
||||
|
||||
return fTotal;
|
||||
}
|
||||
|
||||
void MeshAlgorithm::SubSampleByDist (float fDist, std::vector<Base::Vector3f> &rclPoints) const
|
||||
|
||||
Reference in New Issue
Block a user