Mesh: implement sub-element handling
This commit is contained in:
@@ -76,6 +76,7 @@ PyMOD_INIT_FUNC(Mesh)
|
||||
Mesh::PropertyMeshKernel ::init();
|
||||
|
||||
Mesh::MeshObject ::init();
|
||||
Mesh::MeshSegment ::init();
|
||||
|
||||
Mesh::Feature ::init();
|
||||
Mesh::FeatureCustom ::init();
|
||||
|
||||
@@ -62,6 +62,7 @@ using namespace Mesh;
|
||||
float MeshObject::Epsilon = 1.0e-5f;
|
||||
|
||||
TYPESYSTEM_SOURCE(Mesh::MeshObject, Data::ComplexGeoData)
|
||||
TYPESYSTEM_SOURCE(Mesh::MeshSegment, Data::Segment)
|
||||
|
||||
MeshObject::MeshObject()
|
||||
{
|
||||
@@ -93,7 +94,7 @@ MeshObject::~MeshObject()
|
||||
std::vector<const char*> MeshObject::getElementTypes() const
|
||||
{
|
||||
std::vector<const char*> temp;
|
||||
temp.push_back("Face"); // that's the mesh itself
|
||||
temp.push_back("Mesh");
|
||||
temp.push_back("Segment");
|
||||
|
||||
return temp;
|
||||
@@ -102,31 +103,47 @@ std::vector<const char*> MeshObject::getElementTypes() const
|
||||
unsigned long MeshObject::countSubElements(const char* Type) const
|
||||
{
|
||||
std::string element(Type);
|
||||
if (element == "Face")
|
||||
if (element == "Mesh")
|
||||
return 1;
|
||||
else if (element == "Segment")
|
||||
return countSegments();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Data::Segment* MeshObject::getSubElement(const char* Type, unsigned long /*n*/) const
|
||||
Data::Segment* MeshObject::getSubElement(const char* Type, unsigned long n) const
|
||||
{
|
||||
//TODO
|
||||
std::string element(Type);
|
||||
if (element == "Face")
|
||||
return nullptr;
|
||||
else if (element == "Segment")
|
||||
return nullptr;
|
||||
if (element == "Mesh" && n == 0) {
|
||||
MeshSegment* segm = new MeshSegment();
|
||||
segm->mesh = new MeshObject(*this);
|
||||
return segm;
|
||||
}
|
||||
else if (element == "Segment" && n < countSegments()) {
|
||||
MeshSegment* segm = new MeshSegment();
|
||||
segm->mesh = new MeshObject(*this);
|
||||
const Segment& faces = getSegment(n);
|
||||
segm->segment.reset(new Segment(static_cast<MeshObject*>(segm->mesh), faces.getIndices(), false));
|
||||
return segm;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MeshObject::getFacesFromSubelement(const Data::Segment* /*segm*/,
|
||||
std::vector<Base::Vector3d> &Points,
|
||||
std::vector<Base::Vector3d> &/*PointNormals*/,
|
||||
void MeshObject::getFacesFromSubelement(const Data::Segment* element,
|
||||
std::vector<Base::Vector3d> &points,
|
||||
std::vector<Base::Vector3d> &/*pointNormals*/,
|
||||
std::vector<Facet> &faces) const
|
||||
{
|
||||
//TODO
|
||||
this->getFaces(Points, faces, 0.0f);
|
||||
if (element && element->getTypeId() == MeshSegment::getClassTypeId()) {
|
||||
const MeshSegment* segm = static_cast<const MeshSegment*>(element);
|
||||
if (segm->segment) {
|
||||
Base::Reference<MeshObject> submesh(segm->mesh->meshFromSegment(segm->segment->getIndices()));
|
||||
submesh->getFaces(points, faces, 0.0f);
|
||||
}
|
||||
else {
|
||||
segm->mesh->getFaces(points, faces, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeshObject::transformGeometry(const Base::Matrix4D &rclMat)
|
||||
@@ -161,6 +178,14 @@ Base::BoundBox3d MeshObject::getBoundBox()const
|
||||
return Bnd2;
|
||||
}
|
||||
|
||||
bool MeshObject::getCenterOfGravity(Base::Vector3d& center) const
|
||||
{
|
||||
MeshCore::MeshAlgorithm alg(_kernel);
|
||||
Base::Vector3f pnt = alg.GetGravityPoint();
|
||||
center = transformToOutside(pnt);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MeshObject::copySegments(const MeshObject& mesh)
|
||||
{
|
||||
// After copying the segments the mesh pointers must be adjusted
|
||||
|
||||
@@ -60,6 +60,21 @@ class AbstractPolygonTriangulator;
|
||||
|
||||
namespace Mesh
|
||||
{
|
||||
|
||||
class MeshObject;
|
||||
class MeshExport MeshSegment : public Data::Segment
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
virtual std::string getName() const {
|
||||
return "MeshSegment";
|
||||
}
|
||||
|
||||
Base::Reference<MeshObject> mesh;
|
||||
std::unique_ptr<Mesh::Segment> segment;
|
||||
};
|
||||
|
||||
/**
|
||||
* The MeshObject class provides an interface for the underlying MeshKernel class and
|
||||
* most of its algorithm on it.
|
||||
@@ -142,7 +157,8 @@ public:
|
||||
const MeshCore::MeshKernel& getKernel() const
|
||||
{ return _kernel; }
|
||||
|
||||
virtual Base::BoundBox3d getBoundBox()const;
|
||||
virtual Base::BoundBox3d getBoundBox() const;
|
||||
virtual bool getCenterOfGravity(Base::Vector3d& center) const;
|
||||
|
||||
/** @name I/O */
|
||||
//@{
|
||||
|
||||
@@ -184,7 +184,12 @@ lines = mesh.section(mesh2, [ConnectLines=True, MinDist=0.0001])
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="countSegments" Const="true">
|
||||
<Methode Name="addSegment">
|
||||
<Documentation>
|
||||
<UserDocu>Add a list of facet indices that describes a segment to the mesh</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="countSegments" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Get the number of segments which may also be 0</UserDocu>
|
||||
</Documentation>
|
||||
|
||||
@@ -845,6 +845,27 @@ PyObject* MeshPy::getPointNormals(PyObject *args)
|
||||
} PY_CATCH;
|
||||
}
|
||||
|
||||
PyObject* MeshPy::addSegment(PyObject *args)
|
||||
{
|
||||
PyObject* pylist;
|
||||
if (!PyArg_ParseTuple(args, "O", &pylist))
|
||||
return nullptr;
|
||||
|
||||
Py::Sequence list(pylist);
|
||||
std::vector<Mesh::FacetIndex> segment;
|
||||
unsigned long numFacets = getMeshObjectPtr()->countFacets();
|
||||
segment.reserve(list.size());
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
Py::Long value(*it);
|
||||
Mesh::FacetIndex index = static_cast<unsigned long>(value);
|
||||
if (index < numFacets)
|
||||
segment.push_back(index);
|
||||
}
|
||||
|
||||
getMeshObjectPtr()->addSegment(segment);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* MeshPy::countSegments(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# LGPL
|
||||
|
||||
import FreeCAD, os, sys, unittest, Mesh
|
||||
from FreeCAD import Base
|
||||
import time, tempfile, math
|
||||
# http://python-kurs.eu/threads.php
|
||||
try:
|
||||
@@ -363,3 +364,43 @@ class NastranReader(unittest.TestCase):
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
class MeshSubElement(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.mesh = Mesh.createBox(1.0, 1.0, 1.0)
|
||||
|
||||
def testCenterOfGravity(self):
|
||||
c = self.mesh.CenterOfGravity
|
||||
self.assertEqual(c, Base.Vector(0.0, 0.0, 0.0))
|
||||
|
||||
def testSubElements(self):
|
||||
types = self.mesh.getElementTypes()
|
||||
self.assertIn("Mesh", types)
|
||||
self.assertIn("Segment", types)
|
||||
|
||||
def testCountSubElements(self):
|
||||
self.assertEqual(self.mesh.countSubElements("Mesh"), 1)
|
||||
self.assertEqual(self.mesh.countSubElements("Segment"), 0)
|
||||
|
||||
def testFacesFromSubElement(self):
|
||||
element = self.mesh.getFacesFromSubelement("Mesh", 0)
|
||||
self.assertIsInstance(element, tuple)
|
||||
self.assertEqual(len(element), 2)
|
||||
self.assertEqual(len(element[0]), 8)
|
||||
self.assertEqual(len(element[1]), 12)
|
||||
|
||||
def testSegmentSubElement(self):
|
||||
self.mesh.addSegment([0, 2, 4, 6, 8])
|
||||
self.assertEqual(self.mesh.countSegments(), 1)
|
||||
self.assertEqual(self.mesh.countSubElements("Segment"), 1)
|
||||
element = self.mesh.getFacesFromSubelement("Segment", 0)
|
||||
self.assertIsInstance(element, tuple)
|
||||
self.assertEqual(len(element), 2)
|
||||
self.assertEqual(len(element[0]), 7)
|
||||
self.assertEqual(len(element[1]), 5)
|
||||
segment = self.mesh.meshFromSegment(self.mesh.getSegment(0))
|
||||
self.assertEqual(segment.CountPoints, 7)
|
||||
self.assertEqual(segment.CountFacets, 5)
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user