Mesh: extend API to access edges of a facet via Python
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include "Mesh.h"
|
||||
#include "MeshPy.h"
|
||||
#include "MeshPointPy.h"
|
||||
#include "EdgePy.h"
|
||||
#include "FacetPy.h"
|
||||
#include "MeshFeaturePy.h"
|
||||
#include "FeatureMeshImport.h"
|
||||
@@ -66,6 +67,7 @@ PyMOD_INIT_FUNC(Mesh)
|
||||
|
||||
// add mesh elements
|
||||
Base::Interpreter().addType(&Mesh::MeshPointPy ::Type,meshModule,"MeshPoint");
|
||||
Base::Interpreter().addType(&Mesh::EdgePy ::Type,meshModule,"Edge");
|
||||
Base::Interpreter().addType(&Mesh::FacetPy ::Type,meshModule,"Facet");
|
||||
Base::Interpreter().addType(&Mesh::MeshPy ::Type,meshModule,"Mesh");
|
||||
Base::Interpreter().addType(&Mesh::MeshFeaturePy::Type,meshModule,"Feature");
|
||||
|
||||
@@ -28,12 +28,14 @@ if (BUILD_QT5)
|
||||
)
|
||||
endif()
|
||||
|
||||
generate_from_xml(EdgePy)
|
||||
generate_from_xml(FacetPy)
|
||||
generate_from_xml(MeshFeaturePy)
|
||||
generate_from_xml(MeshPointPy)
|
||||
generate_from_xml(MeshPy)
|
||||
|
||||
SET(Mesh_XML_SRCS
|
||||
EdgePy.xml
|
||||
FacetPy.xml
|
||||
MeshFeaturePy.xml
|
||||
MeshPointPy.xml
|
||||
@@ -331,6 +333,9 @@ SET(Mesh_SRCS
|
||||
Exporter.h
|
||||
Importer.cpp
|
||||
Importer.h
|
||||
Edge.cpp
|
||||
Edge.h
|
||||
EdgePyImp.cpp
|
||||
Facet.cpp
|
||||
Facet.h
|
||||
FacetPyImp.cpp
|
||||
|
||||
@@ -280,6 +280,25 @@ bool MeshGeomEdge::IntersectWithLine (const Base::Vector3f &rclPt,
|
||||
return dist2 + dist3 <= dist1 + eps;
|
||||
}
|
||||
|
||||
bool MeshGeomEdge::IsParallel(const MeshGeomEdge &edge) const
|
||||
{
|
||||
Base::Vector3f r(_aclPoints[1] - _aclPoints[0]);
|
||||
Base::Vector3f s(edge._aclPoints[1] - edge._aclPoints[0]);
|
||||
Base::Vector3f n = r.Cross(s);
|
||||
return n.IsNull();
|
||||
}
|
||||
|
||||
bool MeshGeomEdge::IsCollinear(const MeshGeomEdge &edge) const
|
||||
{
|
||||
if (IsParallel(edge)) {
|
||||
Base::Vector3f r(_aclPoints[1] - _aclPoints[0]);
|
||||
Base::Vector3f d = edge._aclPoints[0] - _aclPoints[0];
|
||||
return d.Cross(r).IsNull();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MeshGeomEdge::IntersectWithEdge (const MeshGeomEdge &edge, Base::Vector3f &res) const
|
||||
{
|
||||
const float eps = 1e-06f;
|
||||
|
||||
@@ -198,6 +198,16 @@ public:
|
||||
* Checks if the projection point of \a point lies on the edge.
|
||||
*/
|
||||
bool IsProjectionPointOf(const Base::Vector3f& point) const;
|
||||
/**
|
||||
* Checks if the two edges are parallel.
|
||||
* \note Parallel edges could be collinear.
|
||||
*/
|
||||
bool IsParallel(const MeshGeomEdge &edge) const;
|
||||
/**
|
||||
* Checks if the two edges are collinear.
|
||||
* \note Collinear edges always are parallel.
|
||||
*/
|
||||
bool IsCollinear(const MeshGeomEdge &edge) const;
|
||||
|
||||
public:
|
||||
Base::Vector3f _aclPoints[2]; /**< Corner points */
|
||||
|
||||
@@ -41,7 +41,7 @@ OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
*/
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
#define FABS(x) ((float)fabs(x)) /* implement as is fastest on your machine */
|
||||
|
||||
|
||||
74
src/Mod/Mesh/App/Edge.cpp
Normal file
74
src/Mod/Mesh/App/Edge.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 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., 51 Franklin Street, *
|
||||
* Fifth Floor, Boston, MA 02110-1301, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
#endif
|
||||
|
||||
#include "Edge.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
using namespace Mesh;
|
||||
|
||||
Edge::Edge()
|
||||
: Index(-1)
|
||||
, Mesh(nullptr)
|
||||
{
|
||||
for (int i=0; i<2; i++) {
|
||||
PIndex[i] = MeshCore::POINT_INDEX_MAX;
|
||||
NIndex[i] = MeshCore::FACET_INDEX_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
Edge::Edge(const Edge& e)
|
||||
: MeshCore::MeshGeomEdge(e)
|
||||
, Index(e.Index)
|
||||
, Mesh(e.Mesh)
|
||||
{
|
||||
for (int i=0; i<2; i++) {
|
||||
PIndex[i] = e.PIndex[i];
|
||||
NIndex[i] = e.NIndex[i];
|
||||
}
|
||||
}
|
||||
|
||||
Edge::~Edge()
|
||||
{
|
||||
}
|
||||
|
||||
void Edge::operator = (const Edge& e)
|
||||
{
|
||||
MeshCore::MeshGeomEdge::operator = (e);
|
||||
Mesh = e.Mesh;
|
||||
Index = e.Index;
|
||||
for (int i=0; i<2; i++) {
|
||||
PIndex[i] = e.PIndex[i];
|
||||
NIndex[i] = e.NIndex[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Edge::unbound()
|
||||
{
|
||||
Index = -1;
|
||||
Mesh = nullptr;
|
||||
}
|
||||
63
src/Mod/Mesh/App/Edge.h
Normal file
63
src/Mod/Mesh/App/Edge.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 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., 51 Franklin Street, *
|
||||
* Fifth Floor, Boston, MA 02110-1301, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef MESH_EDGE_H
|
||||
#define MESH_EDGE_H
|
||||
|
||||
#include <Base/Matrix.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/Handle.h>
|
||||
|
||||
#include <Mod/Mesh/App/Core/Elements.h>
|
||||
|
||||
namespace Mesh
|
||||
{
|
||||
// forward declaration
|
||||
class MeshObject;
|
||||
|
||||
/** The Edge helper class
|
||||
* The Edge class provides an interface for the EdgePy class for
|
||||
* convenient access to the Mesh data structure. This class should not be used
|
||||
* for programming algorithms in C++. Use Mesh Core classes instead!
|
||||
*/
|
||||
class MeshExport Edge : public MeshCore::MeshGeomEdge
|
||||
{
|
||||
public:
|
||||
Edge();
|
||||
Edge(const Edge& f);
|
||||
~Edge();
|
||||
|
||||
bool isBound() const {return Index != -1;}
|
||||
void unbound();
|
||||
void operator = (const Edge& f);
|
||||
|
||||
int Index;
|
||||
MeshCore::PointIndex PIndex[2];
|
||||
MeshCore::FacetIndex NIndex[2];
|
||||
Base::Reference<MeshObject> Mesh;
|
||||
};
|
||||
|
||||
} // namespace Mesh
|
||||
|
||||
|
||||
#endif // MESH_EDGE_H
|
||||
90
src/Mod/Mesh/App/EdgePy.xml
Normal file
90
src/Mod/Mesh/App/EdgePy.xml
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="PyObjectBase"
|
||||
Name="EdgePy"
|
||||
Twin="Edge"
|
||||
TwinPointer="Edge"
|
||||
Include="Mod/Mesh/App/Edge.h"
|
||||
FatherInclude="Base/PyObjectBase.h"
|
||||
Namespace="Mesh"
|
||||
Constructor="true"
|
||||
Delete="true"
|
||||
FatherNamespace="Base">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer[at]users.sourceforge.net" />
|
||||
<DeveloperDocu>Edge in a Mesh</DeveloperDocu>
|
||||
<UserDocu>Edge in mesh
|
||||
This is an edge of a facet in a MeshObject. You can get it by e.g. iterating over the facets of a
|
||||
mesh and calling getEdge(index).
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="intersectWithEdge">
|
||||
<Documentation>
|
||||
<UserDocu>intersectWithEdge(Edge) -> list
|
||||
Get a list of intersection points with another edge.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isParallel">
|
||||
<Documentation>
|
||||
<UserDocu>isParallel(Edge) -> bool
|
||||
Checks if the two edges are parallel.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isCollinear">
|
||||
<Documentation>
|
||||
<UserDocu>isCollinear(Edge) -> bool
|
||||
Checks if the two edges are collinear.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="unbound">
|
||||
<Documentation>
|
||||
<UserDocu>method unbound()
|
||||
Cut the connection to a MeshObject. The edge becomes
|
||||
free and is more or less a simple edge.
|
||||
After calling unbound() no topological operation will
|
||||
work!
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="Index" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The index of this edge of the facet</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Index" Type="Long"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Points" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>A list of points of the edge</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Points" Type="List"/>
|
||||
</Attribute>
|
||||
<Attribute Name="PointIndices" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The index tuple of point vertices of the mesh this edge is built of</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="PointIndices" Type="Tuple"/>
|
||||
</Attribute>
|
||||
<Attribute Name="NeighbourIndices" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The index tuple of neighbour facets of the mesh this edge is adjacent with</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="NeighbourIndices" Type="Tuple"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Length" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The length of the edge</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Length" Type="Float"/>
|
||||
</Attribute>
|
||||
<Attribute Name="Bound" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Bound state of the edge</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="Bound" Type="Boolean"/>
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
194
src/Mod/Mesh/App/EdgePyImp.cpp
Normal file
194
src/Mod/Mesh/App/EdgePyImp.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2021 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., 51 Franklin Street, *
|
||||
* Fifth Floor, Boston, MA 02110-1301, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "Mesh.h"
|
||||
#include "Edge.h"
|
||||
#include <Mod/Mesh/App/EdgePy.h>
|
||||
#include <Mod/Mesh/App/EdgePy.cpp>
|
||||
|
||||
#include <Base/Converter.h>
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
|
||||
using namespace Mesh;
|
||||
|
||||
// returns a string which represent the object e.g. when printed in python
|
||||
std::string EdgePy::representation() const
|
||||
{
|
||||
EdgePy::PointerType ptr = getEdgePtr();
|
||||
std::stringstream str;
|
||||
str << "Edge (";
|
||||
str << "(" << ptr->_aclPoints[0].x << ", " << ptr->_aclPoints[0].y << ", " << ptr->_aclPoints[0].z << ", Idx=" << ptr->PIndex[0] << "), ";
|
||||
str << "(" << ptr->_aclPoints[1].x << ", " << ptr->_aclPoints[1].y << ", " << ptr->_aclPoints[1].z << ", Idx=" << ptr->PIndex[1] << "), ";
|
||||
str << "Idx=" << ptr->Index << ", (" << ptr->NIndex[0] << ", " << ptr->NIndex[1] << ")";
|
||||
str << ")";
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
PyObject *EdgePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper
|
||||
{
|
||||
// create a new instance of EdgePy and the Twin object
|
||||
return new EdgePy(new Edge);
|
||||
}
|
||||
|
||||
// constructor method
|
||||
int EdgePy::PyInit(PyObject* args, PyObject* /*kwds*/)
|
||||
{
|
||||
PyObject* pt1 = nullptr;
|
||||
PyObject* pt2 = nullptr;
|
||||
if (!PyArg_ParseTuple(args, "|O!O!", &Base::VectorPy::Type, &pt1
|
||||
, &Base::VectorPy::Type, &pt2))
|
||||
return -1;
|
||||
|
||||
if (pt1)
|
||||
getEdgePtr()->_aclPoints[0] = Base::convertTo<Base::Vector3f>(Py::Vector(pt1, false).toVector());
|
||||
if (pt2)
|
||||
getEdgePtr()->_aclPoints[1] = Base::convertTo<Base::Vector3f>(Py::Vector(pt2, false).toVector());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Py::Long EdgePy::getIndex() const
|
||||
{
|
||||
return Py::Long((long) getEdgePtr()->Index);
|
||||
}
|
||||
|
||||
PyObject* EdgePy::intersectWithEdge(PyObject *args)
|
||||
{
|
||||
PyObject* object;
|
||||
if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object))
|
||||
return nullptr;
|
||||
EdgePy *edge = static_cast<EdgePy*>(object);
|
||||
EdgePy::PointerType edge_ptr = edge->getEdgePtr();
|
||||
EdgePy::PointerType this_ptr = this->getEdgePtr();
|
||||
Base::Vector3f p;
|
||||
bool ok = this_ptr->IntersectWithEdge(*edge_ptr, p);
|
||||
|
||||
try {
|
||||
Py::List sct;
|
||||
if (ok) {
|
||||
Py::Tuple pt(3);
|
||||
pt.setItem(0, Py::Float(p.x));
|
||||
pt.setItem(1, Py::Float(p.y));
|
||||
pt.setItem(2, Py::Float(p.z));
|
||||
sct.append(pt);
|
||||
}
|
||||
return Py::new_reference_to(sct);
|
||||
}
|
||||
catch (const Py::Exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* EdgePy::isParallel(PyObject *args)
|
||||
{
|
||||
PyObject* object;
|
||||
if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object))
|
||||
return nullptr;
|
||||
EdgePy *edge = static_cast<EdgePy*>(object);
|
||||
EdgePy::PointerType edge_ptr = edge->getEdgePtr();
|
||||
EdgePy::PointerType this_ptr = this->getEdgePtr();
|
||||
bool ok = this_ptr->IsParallel(*edge_ptr);
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* EdgePy::isCollinear(PyObject *args)
|
||||
{
|
||||
PyObject* object;
|
||||
if (!PyArg_ParseTuple(args, "O!", &EdgePy::Type, &object))
|
||||
return nullptr;
|
||||
EdgePy *edge = static_cast<EdgePy*>(object);
|
||||
EdgePy::PointerType edge_ptr = edge->getEdgePtr();
|
||||
EdgePy::PointerType this_ptr = this->getEdgePtr();
|
||||
bool ok = this_ptr->IsCollinear(*edge_ptr);
|
||||
return Py::new_reference_to(Py::Boolean(ok));
|
||||
}
|
||||
|
||||
PyObject* EdgePy::unbound(PyObject *args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args, ""))
|
||||
return nullptr;
|
||||
getEdgePtr()->unbound();
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
Py::Boolean EdgePy::getBound() const
|
||||
{
|
||||
return Py::Boolean(getEdgePtr()->isBound());
|
||||
}
|
||||
|
||||
Py::List EdgePy::getPoints() const
|
||||
{
|
||||
EdgePy::PointerType edge = this->getEdgePtr();
|
||||
|
||||
Py::List pts;
|
||||
for (int i=0; i<2; i++) {
|
||||
Py::Tuple pt(3);
|
||||
pt.setItem(0, Py::Float(edge->_aclPoints[i].x));
|
||||
pt.setItem(1, Py::Float(edge->_aclPoints[i].y));
|
||||
pt.setItem(2, Py::Float(edge->_aclPoints[i].z));
|
||||
pts.append(pt);
|
||||
}
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
Py::Tuple EdgePy::getPointIndices() const
|
||||
{
|
||||
EdgePy::PointerType edge = this->getEdgePtr();
|
||||
|
||||
Py::Tuple idxTuple(2);
|
||||
for (int i=0; i<2; i++) {
|
||||
idxTuple.setItem(i, Py::Long(edge->PIndex[i]));
|
||||
}
|
||||
return idxTuple;
|
||||
}
|
||||
|
||||
Py::Tuple EdgePy::getNeighbourIndices() const
|
||||
{
|
||||
EdgePy::PointerType edge = this->getEdgePtr();
|
||||
|
||||
Py::Tuple idxTuple(2);
|
||||
for (int i=0; i<2; i++) {
|
||||
idxTuple.setItem(i, Py::Long(edge->NIndex[i]));
|
||||
}
|
||||
return idxTuple;
|
||||
}
|
||||
|
||||
Py::Float EdgePy::getLength() const
|
||||
{
|
||||
EdgePy::PointerType edge = this->getEdgePtr();
|
||||
return Py::Float(Base::Distance(edge->_aclPoints[0], edge->_aclPoints[1]));
|
||||
}
|
||||
|
||||
PyObject *EdgePy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int EdgePy::setCustomAttributes(const char* /*attr*/, PyObject * /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -69,3 +69,23 @@ void Facet::operator = (const Facet& f)
|
||||
NIndex[i] = f.NIndex[i];
|
||||
}
|
||||
}
|
||||
|
||||
Edge Facet::getEdge(int index) const
|
||||
{
|
||||
index = index % 3;
|
||||
Edge edge;
|
||||
// geometric coordinates
|
||||
edge._aclPoints[0] = this->_aclPoints[index];
|
||||
edge._aclPoints[1] = this->_aclPoints[(index + 1) % 3];
|
||||
|
||||
// indices
|
||||
edge.Index = index;
|
||||
edge.PIndex[0] = this->PIndex[index];
|
||||
edge.PIndex[1] = this->PIndex[(index + 1) % 3];
|
||||
edge.NIndex[0] = this->Index;
|
||||
edge.NIndex[1] = this->NIndex[index];
|
||||
edge._bBorder = (this->NIndex[index] == MeshCore::FACET_INDEX_MAX);
|
||||
|
||||
edge.Mesh = this->Mesh;
|
||||
return edge;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/Handle.h>
|
||||
|
||||
#include "Core/Elements.h"
|
||||
#include <Mod/Mesh/App/Edge.h>
|
||||
|
||||
namespace Mesh
|
||||
{
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
|
||||
bool isBound() const {return Index != MeshCore::FACET_INDEX_MAX;}
|
||||
void operator = (const Facet& f);
|
||||
Edge getEdge(int) const;
|
||||
|
||||
MeshCore::FacetIndex Index;
|
||||
MeshCore::PointIndex PIndex[3];
|
||||
|
||||
@@ -56,6 +56,13 @@ The two angles are given in radian.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getEdge">
|
||||
<Documentation>
|
||||
<UserDocu>getEdge(int) -> Edge
|
||||
Returns the edge of the facet.
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="Index" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>The index of this facet in the MeshObject</UserDocu>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "Facet.h"
|
||||
#include <Mod/Mesh/App/FacetPy.h>
|
||||
#include <Mod/Mesh/App/FacetPy.cpp>
|
||||
#include <Mod/Mesh/App/EdgePy.h>
|
||||
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
@@ -78,6 +79,16 @@ PyObject* FacetPy::unbound(PyObject *args)
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
PyObject* FacetPy::getEdge(PyObject *args)
|
||||
{
|
||||
int index;
|
||||
if (!PyArg_ParseTuple(args, "i", &index))
|
||||
return nullptr;
|
||||
|
||||
Edge edge = getFacetPtr()->getEdge(index);
|
||||
return new EdgePy(new Edge(edge));
|
||||
}
|
||||
|
||||
Py::Long FacetPy::getIndex() const
|
||||
{
|
||||
return Py::Long((long) getFacetPtr()->Index);
|
||||
@@ -85,7 +96,7 @@ Py::Long FacetPy::getIndex() const
|
||||
|
||||
Py::Boolean FacetPy::getBound() const
|
||||
{
|
||||
return Py::Boolean(getFacetPtr()->Index != UINT_MAX);
|
||||
return Py::Boolean(getFacetPtr()->isBound());
|
||||
}
|
||||
|
||||
Py::Object FacetPy::getNormal() const
|
||||
|
||||
@@ -252,6 +252,65 @@ class MeshGeoTestCases(unittest.TestCase):
|
||||
res = f1.intersect(f2)
|
||||
self.assertTrue(len(res) == 2)
|
||||
|
||||
def testIntersectionOfIntersectingEdges(self):
|
||||
self.planarMesh.append( [0.,10.,10.] )
|
||||
self.planarMesh.append( [10.,0.,10.] )
|
||||
self.planarMesh.append( [10.,10.,10.] )
|
||||
self.planarMesh.append( [6.,8.,10.] )
|
||||
self.planarMesh.append( [16.,8.,10.] )
|
||||
self.planarMesh.append( [6.,18.,10.] )
|
||||
planarMeshObject = Mesh.Mesh(self.planarMesh)
|
||||
|
||||
edge1 = planarMeshObject.Facets[0].getEdge(2)
|
||||
edge2 = planarMeshObject.Facets[1].getEdge(2)
|
||||
res = edge1.intersectWithEdge(edge2)
|
||||
self.assertTrue(len(res) == 1)
|
||||
self.assertEqual(res[0][0], 6.0)
|
||||
self.assertEqual(res[0][1], 10.0)
|
||||
self.assertEqual(res[0][2], 10.0)
|
||||
|
||||
def testIntersectionOfParallelEdges(self):
|
||||
self.planarMesh.append( [0.,10.,10.] )
|
||||
self.planarMesh.append( [10.,0.,10.] )
|
||||
self.planarMesh.append( [10.,10.,10.] )
|
||||
self.planarMesh.append( [6.,8.,10.] )
|
||||
self.planarMesh.append( [16.,8.,10.] )
|
||||
self.planarMesh.append( [6.,18.,10.] )
|
||||
planarMeshObject = Mesh.Mesh(self.planarMesh)
|
||||
|
||||
edge1 = planarMeshObject.Facets[0].getEdge(2)
|
||||
edge2 = planarMeshObject.Facets[1].getEdge(0)
|
||||
res = edge1.intersectWithEdge(edge2)
|
||||
self.assertTrue(len(res) == 0)
|
||||
|
||||
def testIntersectionOfCollinearEdges(self):
|
||||
self.planarMesh.append( [0.,0.,0.] )
|
||||
self.planarMesh.append( [6.,0.,0.] )
|
||||
self.planarMesh.append( [3.,4.,0.] )
|
||||
self.planarMesh.append( [7.,0.,0.] )
|
||||
self.planarMesh.append( [13.,0.,0.] )
|
||||
self.planarMesh.append( [10.,4.,0.] )
|
||||
planarMeshObject = Mesh.Mesh(self.planarMesh)
|
||||
|
||||
edge1 = planarMeshObject.Facets[0].getEdge(0)
|
||||
edge2 = planarMeshObject.Facets[1].getEdge(0)
|
||||
res = edge1.intersectWithEdge(edge2)
|
||||
self.assertTrue(len(res) == 0)
|
||||
|
||||
def testIntersectionOfWarpedEdges(self):
|
||||
self.planarMesh.append( [0.,0.,0.] )
|
||||
self.planarMesh.append( [6.,0.,0.] )
|
||||
self.planarMesh.append( [3.,4.,0.] )
|
||||
self.planarMesh.append( [2.,2.,1.] )
|
||||
self.planarMesh.append( [8.,2.,1.] )
|
||||
self.planarMesh.append( [5.,6.,1.] )
|
||||
planarMeshObject = Mesh.Mesh(self.planarMesh)
|
||||
|
||||
edge1 = planarMeshObject.Facets[0].getEdge(1)
|
||||
edge2 = planarMeshObject.Facets[1].getEdge(0)
|
||||
res = edge1.intersectWithEdge(edge2)
|
||||
self.assertTrue(len(res) == 0)
|
||||
|
||||
def testSelfIntersection(self):
|
||||
s = b"""solid Simple
|
||||
facet normal 0.0e0 0.0e0 1.0e1
|
||||
|
||||
Reference in New Issue
Block a user