diff --git a/src/Mod/Path/App/AppPath.cpp b/src/Mod/Path/App/AppPath.cpp index e89849f4b2..2e984c5769 100644 --- a/src/Mod/Path/App/AppPath.cpp +++ b/src/Mod/Path/App/AppPath.cpp @@ -47,6 +47,8 @@ #include "AreaPy.h" #include "FeatureArea.h" #include "Voronoi.h" +#include "VoronoiCell.h" +#include "VoronoiCellPy.h" #include "VoronoiEdge.h" #include "VoronoiEdgePy.h" #include "VoronoiPy.h" @@ -79,6 +81,7 @@ PyMOD_INIT_FUNC(Path) Base::Interpreter().addType(&Path::TooltablePy ::Type, pathModule, "Tooltable"); Base::Interpreter().addType(&Path::AreaPy ::Type, pathModule, "Area"); Base::Interpreter().addType(&Path::VoronoiPy ::Type, pathModule, "Voronoi"); + Base::Interpreter().addType(&Path::VoronoiCellPy ::Type, pathModule, "VoronoiCell"); Base::Interpreter().addType(&Path::VoronoiEdgePy ::Type, pathModule, "VoronoiEdge"); Base::Interpreter().addType(&Path::VoronoiVertexPy ::Type, pathModule, "VoronoiVertex"); @@ -104,6 +107,7 @@ PyMOD_INIT_FUNC(Path) Path::FeatureAreaView ::init(); Path::FeatureAreaViewPython ::init(); Path::Voronoi ::init(); + Path::VoronoiCell ::init(); Path::VoronoiEdge ::init(); Path::VoronoiVertex ::init(); diff --git a/src/Mod/Path/App/CMakeLists.txt b/src/Mod/Path/App/CMakeLists.txt index 0196889289..5177dcf8f8 100644 --- a/src/Mod/Path/App/CMakeLists.txt +++ b/src/Mod/Path/App/CMakeLists.txt @@ -37,6 +37,7 @@ generate_from_xml(FeaturePathCompoundPy) generate_from_xml(AreaPy) generate_from_xml(FeatureAreaPy) generate_from_xml(VoronoiPy) +generate_from_xml(VoronoiCellPy) generate_from_xml(VoronoiEdgePy) generate_from_xml(VoronoiVertexPy) @@ -57,6 +58,8 @@ SET(Python_SRCS FeatureAreaPyImp.cpp VoronoiPy.xml VoronoiPyImp.cpp + VoronoiCellPy.xml + VoronoiCellPyImp.cpp VoronoiEdgePy.xml VoronoiEdgePyImp.cpp VoronoiVertexPy.xml @@ -101,6 +104,8 @@ SET(Path_SRCS PathSegmentWalker.cpp Voronoi.cpp Voronoi.h + VoronoiCell.cpp + VoronoiCell.h VoronoiEdge.cpp VoronoiEdge.h VoronoiVertex.cpp diff --git a/src/Mod/Path/App/VoronoiCell.cpp b/src/Mod/Path/App/VoronoiCell.cpp new file mode 100644 index 0000000000..37a2760737 --- /dev/null +++ b/src/Mod/Path/App/VoronoiCell.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (c) sliptonic (shopinthewoods@gmail.com) 2020 * + * * + * 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" + +#ifndef _PreComp_ +# include +# include +# include +# include +#endif + +#include +#include +#include +#include +#include "Voronoi.h" +#include "VoronoiCell.h" + +using namespace Base; +using namespace Path; + +TYPESYSTEM_SOURCE(Path::VoronoiCell , Base::Persistence) + +VoronoiCell::VoronoiCell(Voronoi::diagram_type *d, long index) + : dia(d) + , index(index) + , ptr(0) +{ + if (dia && long(dia->num_cells()) > index) { + ptr = &(dia->cells()[index]); + } +} + +VoronoiCell::VoronoiCell(Voronoi::diagram_type *d, const Voronoi::diagram_type::cell_type *e) + : dia(d) + , index(Voronoi::InvalidIndex) + , ptr(e) +{ + if (d && e) { + index = dia->index(e); + } +} + +VoronoiCell::~VoronoiCell() { +} + +bool VoronoiCell::isBound(void) const { + if (ptr != 0 && dia.isValid() && index != Voronoi::InvalidIndex) { + if (&(dia->cells()[index]) == ptr) { + return true; + } + } + ptr = 0; + return false; +} diff --git a/src/Mod/Path/App/VoronoiCell.h b/src/Mod/Path/App/VoronoiCell.h new file mode 100644 index 0000000000..d45cf4c6bd --- /dev/null +++ b/src/Mod/Path/App/VoronoiCell.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (c) sliptonic (shopinthewoods@gmail.com) 2020 * + * * + * 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 PATH_VORONOICELL_H +#define PATH_VORONOICELL_H + +#include +#include +#include +#include +#include "Voronoi.h" + +namespace Path +{ + +class Voronoi; + +class PathExport VoronoiCell + : public Base::BaseClass +{ + TYPESYSTEM_HEADER(); +public: + + VoronoiCell(Voronoi::diagram_type *dia = 0, long index = Voronoi::InvalidIndex); + VoronoiCell(Voronoi::diagram_type *dia, const Voronoi::diagram_type::cell_type *cell); + ~VoronoiCell(); + + bool isBound(void) const; + + Base::Reference dia; + long index; + mutable const Voronoi::diagram_type::cell_type *ptr; +}; + +} +#endif diff --git a/src/Mod/Path/App/VoronoiCellPy.xml b/src/Mod/Path/App/VoronoiCellPy.xml new file mode 100644 index 0000000000..7da58f3fdd --- /dev/null +++ b/src/Mod/Path/App/VoronoiCellPy.xml @@ -0,0 +1,59 @@ + + + + + + Cell of a Voronoi diagram + + + + Assigned color of the receiver. + + + + + + Returns the index of the cell's source + + + + + + Returns the index of the cell's source + + + + + + Incident edge of the cell - if exists + + + + + + Returns true if the cell contains a point site + + + + + Returns true if the cell contains a segment site + + + + + Returns true if the cell doesn't have an incident edge + + + + diff --git a/src/Mod/Path/App/VoronoiCellPyImp.cpp b/src/Mod/Path/App/VoronoiCellPyImp.cpp new file mode 100644 index 0000000000..99dc6263f3 --- /dev/null +++ b/src/Mod/Path/App/VoronoiCellPyImp.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** + * Copyright (c) sliptonic (shopinthewoods@gmail.com) 2020 * + * * + * 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" + + +#ifndef _PreComp_ +# include +#endif + +#include "Mod/Path/App/Voronoi.h" +#include "Mod/Path/App/Voronoi.h" +#include "Mod/Path/App/VoronoiCell.h" +#include "Mod/Path/App/VoronoiCellPy.h" +#include "Mod/Path/App/VoronoiEdge.h" +#include "Mod/Path/App/VoronoiEdgePy.h" +#include +#include +#include +#include +#include + +// files generated out of VoronoiCellPy.xml +#include "VoronoiCellPy.cpp" + +using namespace Path; + +// returns a string which represents the object e.g. when printed in python +std::string VoronoiCellPy::representation(void) const +{ + std::stringstream ss; + ss.precision(5); + ss << "VoronoiCell("; + VoronoiCell *c = getVoronoiCellPtr(); + if (c->isBound()) { + ss << c->ptr->source_category() << ":" << c->ptr->source_index(); + } + ss << ")"; + return ss.str(); +} + +PyObject *VoronoiCellPy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +{ + // create a new instance of VoronoiCellPy and the Twin object + return new VoronoiCellPy(new VoronoiCell); +} + +// constructor method +int VoronoiCellPy::PyInit(PyObject* args, PyObject* /*kwd*/) +{ + if (!PyArg_ParseTuple(args, "")) { + PyErr_SetString(PyExc_RuntimeError, "no arguments accepted"); + return -1; + } + return 0; +} + + +PyObject* VoronoiCellPy::richCompare(PyObject *lhs, PyObject *rhs, int op) { + PyObject *cmp = Py_False; + if ( PyObject_TypeCheck(lhs, &VoronoiCellPy::Type) + && PyObject_TypeCheck(rhs, &VoronoiCellPy::Type) + && op == Py_EQ) { + const VoronoiCell *vl = static_cast(lhs)->getVoronoiCellPtr(); + const VoronoiCell *vr = static_cast(rhs)->getVoronoiCellPtr(); + if (vl->index == vr->index && vl->dia == vr->dia) { + cmp = Py_True; + } + } + Py_INCREF(cmp); + return cmp; +} + +const Voronoi::voronoi_diagram_type::cell_type* getCellFromPy(VoronoiCellPy *c, bool throwIfNotBound = true) { + auto self = c->getVoronoiCellPtr(); + if (self->isBound()) { + return self->ptr; + } + if (throwIfNotBound) { + throw Py::TypeError("Cell not bound to voronoi diagram"); + } + return 0; +} + +VoronoiCell* getVoronoiCellFromPy(const VoronoiCellPy *c, PyObject *args = 0) { + VoronoiCell *self = c->getVoronoiCellPtr(); + if (!self->isBound()) { + throw Py::TypeError("Cell not bound to voronoi diagram"); + } + if (args && !PyArg_ParseTuple(args, "")) { + throw Py::RuntimeError("No arguments accepted"); + } + return self; +} + +Py::Int VoronoiCellPy::getColor(void) const { + VoronoiCell *c = getVoronoiCellPtr(); + if (c->isBound()) { + return Py::Int(c->dia->cells()[c->index].color()); + } + return Py::Int(0); +} + +void VoronoiCellPy::setColor(Py::Int color) { + getCellFromPy(this)->color(int(color) & 0x0FFFFFFF); +} + +Py::Int VoronoiCellPy::getSourceIndex(void) const +{ + VoronoiCell *c = getVoronoiCellFromPy(this); + return Py::Int(c->ptr->source_index()); +} + +Py::Int VoronoiCellPy::getSourceCategory(void) const +{ + VoronoiCell *c = getVoronoiCellFromPy(this); + return Py::Int(c->ptr->source_category()); +} + +Py::Object VoronoiCellPy::getIncidentEdge(void) const +{ + VoronoiCell *c = getVoronoiCellFromPy(this); + return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(c->dia, c->ptr->incident_edge()))); +} + +PyObject* VoronoiCellPy::containsPoint(PyObject *args) +{ + VoronoiCell *c = getVoronoiCellFromPy(this, args); + PyObject *chk = c->ptr->contains_point() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + +PyObject* VoronoiCellPy::containsSegment(PyObject *args) +{ + VoronoiCell *c = getVoronoiCellFromPy(this, args); + PyObject *chk = c->ptr->contains_segment() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + +PyObject* VoronoiCellPy::isDegenerate(PyObject *args) +{ + VoronoiCell *c = getVoronoiCellFromPy(this, args); + PyObject *chk = c->ptr->is_degenerate() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + + +// custom attributes get/set + +PyObject* VoronoiCellPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int VoronoiCellPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + diff --git a/src/Mod/Path/App/VoronoiEdgePy.xml b/src/Mod/Path/App/VoronoiEdgePy.xml index 4d6ade8d59..f6496e8edb 100644 --- a/src/Mod/Path/App/VoronoiEdgePy.xml +++ b/src/Mod/Path/App/VoronoiEdgePy.xml @@ -22,14 +22,12 @@ - Begin and End voronoi vertex diff --git a/src/Mod/Path/App/VoronoiEdgePyImp.cpp b/src/Mod/Path/App/VoronoiEdgePyImp.cpp index 323630fcc0..73ae0b65a1 100644 --- a/src/Mod/Path/App/VoronoiEdgePyImp.cpp +++ b/src/Mod/Path/App/VoronoiEdgePyImp.cpp @@ -29,6 +29,8 @@ #include "Mod/Path/App/Voronoi.h" #include "Mod/Path/App/Voronoi.h" +#include "Mod/Path/App/VoronoiCell.h" +#include "Mod/Path/App/VoronoiCellPy.h" #include "Mod/Path/App/VoronoiEdge.h" #include "Mod/Path/App/VoronoiEdgePy.h" #include "Mod/Path/App/VoronoiVertex.h" @@ -191,6 +193,13 @@ Py::Object VoronoiEdgePy::getRotatedPrev(void) const return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(e->dia, e->ptr->rot_prev()))); } +Py::Object VoronoiEdgePy::getCell(void) const +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this); + return Py::asObject(new VoronoiCellPy(new VoronoiCell(e->dia, e->ptr->cell()))); +} + + PyObject* VoronoiEdgePy::isFinite(PyObject *args) { VoronoiEdge *e = getVoronoiEdgeFromPy(this, args); diff --git a/src/Mod/Path/App/VoronoiPy.xml b/src/Mod/Path/App/VoronoiPy.xml index 5542fc8084..b38bf6872b 100644 --- a/src/Mod/Path/App/VoronoiPy.xml +++ b/src/Mod/Path/App/VoronoiPy.xml @@ -15,14 +15,12 @@ Voronoi([segments]): Create voronoi for given collection of line segments - List of all edges of the voronoi diagram diff --git a/src/Mod/Path/App/VoronoiPyImp.cpp b/src/Mod/Path/App/VoronoiPyImp.cpp index 85d744d8d4..d90b4c7257 100644 --- a/src/Mod/Path/App/VoronoiPyImp.cpp +++ b/src/Mod/Path/App/VoronoiPyImp.cpp @@ -28,6 +28,7 @@ #endif #include "Mod/Path/App/Voronoi.h" +#include "Mod/Path/App/VoronoiCell.h" #include "Mod/Path/App/VoronoiEdge.h" #include "Mod/Path/App/VoronoiVertex.h" #include @@ -38,6 +39,7 @@ // files generated out of VoronoiPy.xml #include "VoronoiPy.h" #include "VoronoiPy.cpp" +#include "VoronoiCellPy.h" #include "VoronoiEdgePy.h" #include "VoronoiVertexPy.h" @@ -159,6 +161,14 @@ Py::List VoronoiPy::getEdges(void) const { return list; } +Py::List VoronoiPy::getCells(void) const { + Py::List list; + for (int i=0; inumCells(); ++i) { + list.append(Py::asObject(new VoronoiCellPy(new VoronoiCell(getVoronoiPtr()->vd, i)))); + } + return list; +} + // custom attributes get/set PyObject *VoronoiPy::getCustomAttributes(const char* /*attr*/) const diff --git a/src/Mod/Path/App/VoronoiVertexPyImp.cpp b/src/Mod/Path/App/VoronoiVertexPyImp.cpp index 711b18f246..a26ab482fb 100644 --- a/src/Mod/Path/App/VoronoiVertexPyImp.cpp +++ b/src/Mod/Path/App/VoronoiVertexPyImp.cpp @@ -101,6 +101,18 @@ const Voronoi::voronoi_diagram_type::vertex_type* getVertexFromPy(VoronoiVertexP return 0; } +VoronoiVertex* getVoronoiVertexFromPy(const VoronoiVertexPy *v, PyObject *args = 0) { + VoronoiVertex *self = v->getVoronoiVertexPtr(); + if (!self->isBound()) { + throw Py::TypeError("Vertex not bound to voronoi diagram"); + } + if (args && !PyArg_ParseTuple(args, "")) { + throw Py::RuntimeError("No arguments accepted"); + } + return self; +} + + Py::Int VoronoiVertexPy::getColor(void) const { VoronoiVertex *v = getVoronoiVertexPtr(); if (v->isBound()) { @@ -115,27 +127,16 @@ void VoronoiVertexPy::setColor(Py::Int color) { Py::Float VoronoiVertexPy::getX(void) const { - VoronoiVertex *v = getVoronoiVertexPtr(); - if (!v->isBound()) { - throw Py::FloatingPointError("Cannot get coordinates of unbound voronoi vertex"); - } - return Py::Float(v->ptr->x()); + return Py::Float(getVoronoiVertexFromPy(this)->ptr->x()); } Py::Float VoronoiVertexPy::getY(void) const { - VoronoiVertex *v = getVoronoiVertexPtr(); - if (!v->isBound()) { - throw Py::FloatingPointError("Cannot get coordinates of unbound voronoi vertex"); - } - return Py::Float(v->ptr->y()); + return Py::Float(getVoronoiVertexFromPy(this)->ptr->y()); } Py::Object VoronoiVertexPy::getIncidentEdge() const { - VoronoiVertex *v = getVoronoiVertexPtr(); - if (!v->isBound()) { - throw Py::TypeError("Vertex not bound to voronoi diagram"); - } + VoronoiVertex *v = getVoronoiVertexFromPy(this); return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(v->dia, v->ptr->incident_edge()))); }