Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement trimming of a mesh with a plane
- Loading branch information
Showing
8 changed files
with
298 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
/*************************************************************************** | ||
* Copyright (c) 2019 Werner Mayer <wmayer[at]users.sourceforge.net> * | ||
* * | ||
* This file is part of the FreeCAD CAx development system. * | ||
* * | ||
* This library is free software; you can redistribute it and/or * | ||
* modify it under the terms of the GNU Library General Public * | ||
* License as published by the Free Software Foundation; either * | ||
* version 2 of the License, or (at your option) any later version. * | ||
* * | ||
* This library is distributed in the hope that it will be useful, * | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
* GNU Library General Public License for more details. * | ||
* * | ||
* You should have received a copy of the GNU Library General Public * | ||
* License along with this library; see the file COPYING.LIB. If not, * | ||
* write to the Free Software Foundation, Inc., 59 Temple Place, * | ||
* Suite 330, Boston, MA 02111-1307, USA * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "PreCompiled.h" | ||
#include <algorithm> | ||
|
||
#include "TrimByPlane.h" | ||
#include "Grid.h" | ||
#include "Iterator.h" | ||
|
||
using namespace MeshCore; | ||
|
||
MeshTrimByPlane::MeshTrimByPlane(MeshKernel &rclM) | ||
: myMesh(rclM) | ||
{ | ||
} | ||
|
||
MeshTrimByPlane::~MeshTrimByPlane() | ||
{ | ||
} | ||
|
||
void MeshTrimByPlane::CheckFacets(const MeshFacetGrid& rclGrid, const Base::Vector3f& base, const Base::Vector3f& normal, | ||
std::vector<unsigned long> &trimFacets, std::vector<unsigned long>& removeFacets) const | ||
{ | ||
// Go through the grid and check for each cell if its bounding box intersects the plane. | ||
// If the box is completely below the plane all facets will be kept, if it's above the | ||
// plane all triangles will be removed. | ||
std::vector<unsigned long> checkElements; | ||
MeshGridIterator clGridIter(rclGrid); | ||
for (clGridIter.Init(); clGridIter.More(); clGridIter.Next()) { | ||
Base::BoundBox3f clBBox3d = clGridIter.GetBoundBox(); | ||
if (clBBox3d.IsCutPlane(base, normal)) { | ||
// save all elements in checkElements | ||
clGridIter.GetElements(checkElements); | ||
} | ||
else if (clBBox3d.CalcPoint(0).DistanceToPlane(base, normal) > 0.0f) { | ||
// save all elements in removeFacets | ||
clGridIter.GetElements(removeFacets); | ||
} | ||
} | ||
|
||
// remove double elements | ||
std::sort(checkElements.begin(), checkElements.end()); | ||
checkElements.erase(std::unique(checkElements.begin(), checkElements.end()), checkElements.end()); | ||
|
||
trimFacets.reserve(checkElements.size()/2); // reserve some memory | ||
for (auto it = checkElements.begin(); it != checkElements.end(); ++it) { | ||
MeshGeomFacet clFacet = myMesh.GetFacet(*it); | ||
if (clFacet.IntersectWithPlane(base, normal)) { | ||
trimFacets.push_back(*it); | ||
removeFacets.push_back(*it); | ||
} | ||
else if (clFacet._aclPoints[0].DistanceToPlane(base, normal) > 0.0f) { | ||
removeFacets.push_back(*it); | ||
} | ||
} | ||
|
||
// remove double elements | ||
std::sort(removeFacets.begin(), removeFacets.end()); | ||
removeFacets.erase(std::unique(removeFacets.begin(), removeFacets.end()), removeFacets.end()); | ||
} | ||
|
||
void MeshTrimByPlane::CreateOneFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, | ||
const MeshGeomFacet& facet, std::vector<MeshGeomFacet>& trimmedFacets) const | ||
{ | ||
unsigned short nul = shift % 3; | ||
unsigned short one = (shift + 1) % 3; | ||
unsigned short two = (shift + 2) % 3; | ||
|
||
Base::Vector3f p1, p2; | ||
MeshGeomEdge edge; | ||
|
||
edge._aclPoints[0] = facet._aclPoints[nul]; | ||
edge._aclPoints[1] = facet._aclPoints[one]; | ||
edge.IntersectWithPlane(base, normal, p1); | ||
|
||
edge._aclPoints[0] = facet._aclPoints[nul]; | ||
edge._aclPoints[1] = facet._aclPoints[two]; | ||
edge.IntersectWithPlane(base, normal, p2); | ||
|
||
MeshGeomFacet create; | ||
create._aclPoints[0] = facet._aclPoints[nul]; | ||
create._aclPoints[1] = p1; | ||
create._aclPoints[2] = p2; | ||
trimmedFacets.push_back(create); | ||
} | ||
|
||
void MeshTrimByPlane::CreateTwoFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, | ||
const MeshGeomFacet& facet, std::vector<MeshGeomFacet>& trimmedFacets) const | ||
{ | ||
unsigned short nul = shift % 3; | ||
unsigned short one = (shift + 1) % 3; | ||
unsigned short two = (shift + 2) % 3; | ||
|
||
Base::Vector3f p1, p2; | ||
MeshGeomEdge edge; | ||
|
||
edge._aclPoints[0] = facet._aclPoints[nul]; | ||
edge._aclPoints[1] = facet._aclPoints[two]; | ||
edge.IntersectWithPlane(base, normal, p1); | ||
|
||
edge._aclPoints[0] = facet._aclPoints[one]; | ||
edge._aclPoints[1] = facet._aclPoints[two]; | ||
edge.IntersectWithPlane(base, normal, p2); | ||
|
||
MeshGeomFacet create; | ||
create._aclPoints[0] = facet._aclPoints[nul]; | ||
create._aclPoints[1] = facet._aclPoints[one]; | ||
create._aclPoints[2] = p1; | ||
trimmedFacets.push_back(create); | ||
|
||
create._aclPoints[0] = facet._aclPoints[one]; | ||
create._aclPoints[1] = p2; | ||
create._aclPoints[2] = p1; | ||
trimmedFacets.push_back(create); | ||
} | ||
|
||
void MeshTrimByPlane::TrimFacets(const std::vector<unsigned long>& trimFacets, const Base::Vector3f& base, | ||
const Base::Vector3f& normal, std::vector<MeshGeomFacet>& trimmedFacets) | ||
{ | ||
trimmedFacets.reserve(2 * trimFacets.size()); | ||
for (auto it = trimFacets.begin(); it != trimFacets.end(); ++it) { | ||
MeshGeomFacet facet = myMesh.GetFacet(*it); | ||
float dist1 = facet._aclPoints[0].DistanceToPlane(base, normal); | ||
float dist2 = facet._aclPoints[1].DistanceToPlane(base, normal); | ||
float dist3 = facet._aclPoints[2].DistanceToPlane(base, normal); | ||
|
||
// only one point below | ||
if (dist1 < 0.0f && dist2 > 0.0f && dist3 > 0.0f) { | ||
CreateOneFacet(base, normal, 0, facet, trimmedFacets); | ||
} | ||
else if (dist1 > 0.0f && dist2 < 0.0f && dist3 > 0.0f) { | ||
CreateOneFacet(base, normal, 1, facet, trimmedFacets); | ||
} | ||
else if (dist1 > 0.0f && dist2 > 0.0f && dist3 < 0.0f) { | ||
CreateOneFacet(base, normal, 2, facet, trimmedFacets); | ||
} | ||
// two points below | ||
else if (dist1 < 0.0f && dist2 < 0.0f && dist3 > 0.0f) { | ||
CreateTwoFacet(base, normal, 0, facet, trimmedFacets); | ||
} | ||
else if (dist1 > 0.0f && dist2 < 0.0f && dist3 < 0.0f) { | ||
CreateTwoFacet(base, normal, 1, facet, trimmedFacets); | ||
} | ||
else if (dist1 < 0.0f && dist2 > 0.0f && dist3 < 0.0f) { | ||
CreateTwoFacet(base, normal, 2, facet, trimmedFacets); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/*************************************************************************** | ||
* Copyright (c) 2019 Werner Mayer <wmayer[at]users.sourceforge.net> * | ||
* * | ||
* This file is part of the FreeCAD CAx development system. * | ||
* * | ||
* This library is free software; you can redistribute it and/or * | ||
* modify it under the terms of the GNU Library General Public * | ||
* License as published by the Free Software Foundation; either * | ||
* version 2 of the License, or (at your option) any later version. * | ||
* * | ||
* This library is distributed in the hope that it will be useful, * | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
* GNU Library General Public License for more details. * | ||
* * | ||
* You should have received a copy of the GNU Library General Public * | ||
* License along with this library; see the file COPYING.LIB. If not, * | ||
* write to the Free Software Foundation, Inc., 59 Temple Place, * | ||
* Suite 330, Boston, MA 02111-1307, USA * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef MESHTRIM_BY_PLANE_H | ||
#define MESHTRIM_BY_PLANE_H | ||
|
||
#include <Mod/Mesh/App/Core/Elements.h> | ||
#include <Mod/Mesh/App/Core/MeshKernel.h> | ||
|
||
namespace MeshCore { | ||
|
||
/** | ||
* Trim the the facets in 3D with a plane | ||
* \author Werner Mayer | ||
*/ | ||
class MeshExport MeshTrimByPlane | ||
{ | ||
public: | ||
MeshTrimByPlane(MeshKernel& mesh); | ||
~MeshTrimByPlane(); | ||
|
||
public: | ||
/** | ||
* Checks all facets for intersection with the plane and writes all touched facets into the vector | ||
*/ | ||
void CheckFacets(const MeshFacetGrid& rclGrid, const Base::Vector3f& base, const Base::Vector3f& normal, | ||
std::vector<unsigned long>& trimFacets, std::vector<unsigned long>& removeFacets) const; | ||
|
||
/** | ||
* The facets from \a trimFacets will be trimmed or deleted and \a trimmedFacets holds the newly generated facets | ||
*/ | ||
void TrimFacets(const std::vector<unsigned long>& trimFacets, const Base::Vector3f& base, | ||
const Base::Vector3f& normal, std::vector<MeshGeomFacet>& trimmedFacets); | ||
|
||
private: | ||
void CreateOneFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, | ||
const MeshGeomFacet& facet, std::vector<MeshGeomFacet>& trimmedFacets) const; | ||
void CreateTwoFacet(const Base::Vector3f& base, const Base::Vector3f& normal, unsigned short shift, | ||
const MeshGeomFacet& facet, std::vector<MeshGeomFacet>& trimmedFacets) const; | ||
|
||
private: | ||
MeshKernel& myMesh; | ||
}; | ||
|
||
} //namespace MeshCore | ||
|
||
#endif //MESHTRIM_BY_PLANE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.