diff --git a/src/Mod/Path/App/AppPath.cpp b/src/Mod/Path/App/AppPath.cpp index e5de2bb0ad..e89849f4b2 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 "VoronoiEdge.h" +#include "VoronoiEdgePy.h" #include "VoronoiPy.h" #include "VoronoiVertex.h" #include "VoronoiVertexPy.h" @@ -71,13 +73,14 @@ PyMOD_INIT_FUNC(Path) Base::Console().Log("Loading Path module... done\n"); // Add Types to module - Base::Interpreter().addType(&Path::CommandPy ::Type, pathModule, "Command"); - Base::Interpreter().addType(&Path::PathPy ::Type, pathModule, "Path"); - Base::Interpreter().addType(&Path::ToolPy ::Type, pathModule, "Tool"); - 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::VoronoiVertexPy ::Type, pathModule, "VoronoiVertex"); + Base::Interpreter().addType(&Path::CommandPy ::Type, pathModule, "Command"); + Base::Interpreter().addType(&Path::PathPy ::Type, pathModule, "Path"); + Base::Interpreter().addType(&Path::ToolPy ::Type, pathModule, "Tool"); + 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::VoronoiEdgePy ::Type, pathModule, "VoronoiEdge"); + Base::Interpreter().addType(&Path::VoronoiVertexPy ::Type, pathModule, "VoronoiVertex"); // NOTE: To finish the initialization of our own type objects we must // call PyType_Ready, otherwise we run into a segmentation fault, later on. @@ -101,6 +104,7 @@ PyMOD_INIT_FUNC(Path) Path::FeatureAreaView ::init(); Path::FeatureAreaViewPython ::init(); Path::Voronoi ::init(); + Path::VoronoiEdge ::init(); Path::VoronoiVertex ::init(); PyMOD_Return(pathModule); diff --git a/src/Mod/Path/App/CMakeLists.txt b/src/Mod/Path/App/CMakeLists.txt index 0ede609c42..0196889289 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(VoronoiEdgePy) generate_from_xml(VoronoiVertexPy) SET(Python_SRCS @@ -56,6 +57,8 @@ SET(Python_SRCS FeatureAreaPyImp.cpp VoronoiPy.xml VoronoiPyImp.cpp + VoronoiEdgePy.xml + VoronoiEdgePyImp.cpp VoronoiVertexPy.xml VoronoiVertexPyImp.cpp ) @@ -98,6 +101,8 @@ SET(Path_SRCS PathSegmentWalker.cpp Voronoi.cpp Voronoi.h + VoronoiEdge.cpp + VoronoiEdge.h VoronoiVertex.cpp VoronoiVertex.h ${Mod_SRCS} diff --git a/src/Mod/Path/App/Voronoi.cpp b/src/Mod/Path/App/Voronoi.cpp index 19558034c9..23b4895290 100644 --- a/src/Mod/Path/App/Voronoi.cpp +++ b/src/Mod/Path/App/Voronoi.cpp @@ -68,6 +68,48 @@ static void color_exterior(const Voronoi::diagram_type::edge_type *edge) { // Constructors & destructors +int Voronoi::diagram_type::index(const Voronoi::diagram_type::cell_type *cell) const { + auto it = cell_index.find(intptr_t(cell)); + if (it == cell_index.end()) { + return Voronoi::InvalidIndex; + } + return it->second; +} +int Voronoi::diagram_type::index(const Voronoi::diagram_type::edge_type *edge) const { + auto it = edge_index.find(intptr_t(edge)); + if (it == edge_index.end()) { + return Voronoi::InvalidIndex; + } + return it->second; +} +int Voronoi::diagram_type::index(const Voronoi::diagram_type::vertex_type *vertex) const { + auto it = vertex_index.find(intptr_t(vertex)); + if (it == vertex_index.end()) { + return Voronoi::InvalidIndex; + } + return it->second; +} + +void Voronoi::diagram_type::reIndex() { + int idx = 0; + cell_index.clear(); + edge_index.clear(); + vertex_index.clear(); + + idx = 0; + for (auto it = cells().begin(); it != cells().end(); ++it, ++idx) { + cell_index[intptr_t(&(*it))] = idx; + } + idx = 0; + for (auto it = edges().begin(); it != edges().end(); ++it, ++idx) { + edge_index[intptr_t(&(*it))] = idx; + } + idx = 0; + for (auto it = vertices().begin(); it != vertices().end(); ++it, ++idx) { + vertex_index[intptr_t(&(*it))] = idx; + } +} + Voronoi::Voronoi() :vd(new diagram_type) { @@ -103,4 +145,5 @@ void Voronoi::construct() { vd->clear(); construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), (voronoi_diagram_type*)vd); + vd->reIndex(); } diff --git a/src/Mod/Path/App/Voronoi.h b/src/Mod/Path/App/Voronoi.h index 716256db68..76bdd9d506 100644 --- a/src/Mod/Path/App/Voronoi.h +++ b/src/Mod/Path/App/Voronoi.h @@ -46,6 +46,7 @@ namespace Path Voronoi(); ~Voronoi(); + static const int InvalidIndex = INT_MAX; // types typedef double coordinate_type; typedef boost::polygon::point_data point_type; @@ -54,7 +55,24 @@ namespace Path class diagram_type : public voronoi_diagram_type , public Base::Handled - { }; + { + public: + + typedef std::map cell_map_type; + typedef std::map edge_map_type; + typedef std::map vertex_map_type; + + int index(const cell_type *cell) const; + int index(const edge_type *edge) const; + int index(const vertex_type *vertex) const; + + void reIndex(); + + private: + cell_map_type cell_index; + edge_map_type edge_index; + vertex_map_type vertex_index; + }; // specific methods void addPoint(const point_type &p); diff --git a/src/Mod/Path/App/VoronoiEdge.cpp b/src/Mod/Path/App/VoronoiEdge.cpp new file mode 100644 index 0000000000..a0649d7af3 --- /dev/null +++ b/src/Mod/Path/App/VoronoiEdge.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 "VoronoiEdge.h" + +using namespace Base; +using namespace Path; + +TYPESYSTEM_SOURCE(Path::VoronoiEdge , Base::Persistence) + +VoronoiEdge::VoronoiEdge(Voronoi::diagram_type *d, long index) + : dia(d) + , index(index) + , ptr(0) +{ + if (dia && long(dia->num_edges()) > index) { + ptr = &(dia->edges()[index]); + } +} + +VoronoiEdge::VoronoiEdge(Voronoi::diagram_type *d, const Voronoi::diagram_type::edge_type *e) + : dia(d) + , index(Voronoi::InvalidIndex) + , ptr(e) +{ + if (d && e) { + index = dia->index(e); + } +} + +VoronoiEdge::~VoronoiEdge() { +} + +bool VoronoiEdge::isBound(void) const { + if (ptr != 0 && dia.isValid() && index != Voronoi::InvalidIndex) { + if (&(dia->edges()[index]) == ptr) { + return true; + } + } + ptr = 0; + return false; +} diff --git a/src/Mod/Path/App/VoronoiEdge.h b/src/Mod/Path/App/VoronoiEdge.h new file mode 100644 index 0000000000..756d7c6542 --- /dev/null +++ b/src/Mod/Path/App/VoronoiEdge.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_VORONOIEDGE_H +#define PATH_VORONOIEDGE_H + +#include +#include +#include +#include +#include "Voronoi.h" + +namespace Path +{ + +class Voronoi; + +class PathExport VoronoiEdge + : public Base::BaseClass +{ + TYPESYSTEM_HEADER(); +public: + + VoronoiEdge(Voronoi::diagram_type *dia = 0, long index = Voronoi::InvalidIndex); + VoronoiEdge(Voronoi::diagram_type *dia, const Voronoi::diagram_type::edge_type *edge); + ~VoronoiEdge(); + + bool isBound(void) const; + + Base::Reference dia; + long index; + mutable const Voronoi::diagram_type::edge_type *ptr; +}; + +} +#endif diff --git a/src/Mod/Path/App/VoronoiEdgePy.xml b/src/Mod/Path/App/VoronoiEdgePy.xml new file mode 100644 index 0000000000..4d6ade8d59 --- /dev/null +++ b/src/Mod/Path/App/VoronoiEdgePy.xml @@ -0,0 +1,101 @@ + + + + + + Edge of a Voronoi diagram + + + + Assigned color of the receiver. + + + + + + + Begin and End voronoi vertex + + + + + + CCW next edge whithin voronoi cell + + + + + + CCW previous edge whithin voronoi cell + + + + + + Rotated CCW next edge whithin voronoi cell + + + + + + Rotated CCW previous edge whithin voronoi cell + + + + + + Twin edge + + + + + + Returns true if both vertices are finite + + + + + Returns true if the end vertex is infinite + + + + + Returns true if edge is straight + + + + + Returns true if edge is curved + + + + + Returns false if edge goes through endpoint of the segment site + + + + + Returns true if edge goes through endpoint of the segment site + + + --> + + diff --git a/src/Mod/Path/App/VoronoiEdgePyImp.cpp b/src/Mod/Path/App/VoronoiEdgePyImp.cpp new file mode 100644 index 0000000000..323630fcc0 --- /dev/null +++ b/src/Mod/Path/App/VoronoiEdgePyImp.cpp @@ -0,0 +1,254 @@ +/*************************************************************************** + * 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/VoronoiEdge.h" +#include "Mod/Path/App/VoronoiEdgePy.h" +#include "Mod/Path/App/VoronoiVertex.h" +#include "Mod/Path/App/VoronoiVertexPy.h" +#include +#include +#include +#include +#include + +// files generated out of VoronoiEdgePy.xml +#include "VoronoiEdgePy.cpp" + +using namespace Path; + +// returns a string which represents the object e.g. when printed in python +std::string VoronoiEdgePy::representation(void) const +{ + std::stringstream ss; + ss.precision(5); + ss << "VoronoiEdge("; + VoronoiEdge *e = getVoronoiEdgePtr(); + if (e->isBound()) { + const Voronoi::diagram_type::vertex_type *v0 = e->ptr->vertex0(); + const Voronoi::diagram_type::vertex_type *v1 = e->ptr->vertex1(); + if (v0) { + ss << "[" << v0->x() << ", " << v0->y() << "]"; + } else { + ss << "[~]"; + } + ss << ", "; + if (v1) { + ss << "[" << v1->x() << ", " << v1->y() << "]"; + } else { + ss << "[~]"; + } + } + ss << ")"; + return ss.str(); +} + +PyObject *VoronoiEdgePy::PyMake(struct _typeobject *, PyObject *, PyObject *) // Python wrapper +{ + // create a new instance of VoronoiEdgePy and the Twin object + return new VoronoiEdgePy(new VoronoiEdge); +} + +// constructor method +int VoronoiEdgePy::PyInit(PyObject* args, PyObject* /*kwd*/) +{ + if (!PyArg_ParseTuple(args, "")) { + PyErr_SetString(PyExc_RuntimeError, "no arguments accepted"); + return -1; + } + return 0; +} + + +PyObject* VoronoiEdgePy::richCompare(PyObject *lhs, PyObject *rhs, int op) { + PyObject *cmp = Py_False; + if ( PyObject_TypeCheck(lhs, &VoronoiEdgePy::Type) + && PyObject_TypeCheck(rhs, &VoronoiEdgePy::Type) + && op == Py_EQ) { + const VoronoiEdge *vl = static_cast(lhs)->getVoronoiEdgePtr(); + const VoronoiEdge *vr = static_cast(rhs)->getVoronoiEdgePtr(); + if (vl->index == vr->index && vl->dia == vr->dia) { + cmp = Py_True; + } else { + std::cerr << "VoronoiEdge==(" << vl->index << " != " << vr->index << " || " << (vl->dia == vr->dia) << ")" << std::endl; + } + } + Py_INCREF(cmp); + return cmp; +} + +const Voronoi::voronoi_diagram_type::edge_type* getEdgeFromPy(VoronoiEdgePy *e, bool throwIfNotBound = true) { + auto self = e->getVoronoiEdgePtr(); + if (self->isBound()) { + return self->ptr; + } + if (throwIfNotBound) { + throw Py::TypeError("Edge not bound to voronoi diagram"); + } + return 0; +} + +VoronoiEdge* getVoronoiEdgeFromPy(const VoronoiEdgePy *e, PyObject *args = 0) { + VoronoiEdge *self = e->getVoronoiEdgePtr(); + if (!self->isBound()) { + throw Py::TypeError("Edge not bound to voronoi diagram"); + } + if (args && !PyArg_ParseTuple(args, "")) { + throw Py::RuntimeError("No arguments accepted"); + } + return self; +} + +Py::Int VoronoiEdgePy::getColor(void) const { + VoronoiEdge *e = getVoronoiEdgePtr(); + if (e->isBound()) { + return Py::Int(e->dia->edges()[e->index].color()); + } + return Py::Int(0); +} + +void VoronoiEdgePy::setColor(Py::Int color) { + getEdgeFromPy(this)->color(int(color) & 0x0FFFFFFF); +} + +Py::List VoronoiEdgePy::getVertices(void) const +{ + Py::List list; + VoronoiEdge *e = getVoronoiEdgePtr(); + if (e->isBound()) { + auto v0 = e->ptr->vertex0(); + auto v1 = e->ptr->vertex1(); + if (v0) { + list.append(Py::asObject(new VoronoiVertexPy(new VoronoiVertex(e->dia, v0)))); + } else { + Py_INCREF(Py_None); + list.append(Py::asObject(Py_None)); + } + if (v1) { + list.append(Py::asObject(new VoronoiVertexPy(new VoronoiVertex(e->dia, v1)))); + } else { + Py_INCREF(Py_None); + list.append(Py::asObject(Py_None)); + } + } + return list; +} + +Py::Object VoronoiEdgePy::getTwin(void) const +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this); + return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(e->dia, e->ptr->twin()))); +} + +Py::Object VoronoiEdgePy::getNext(void) const +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this); + return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(e->dia, e->ptr->next()))); +} + +Py::Object VoronoiEdgePy::getPrev(void) const +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this); + return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(e->dia, e->ptr->prev()))); +} + +Py::Object VoronoiEdgePy::getRotatedNext(void) const +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this); + return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(e->dia, e->ptr->rot_next()))); +} + +Py::Object VoronoiEdgePy::getRotatedPrev(void) const +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this); + return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(e->dia, e->ptr->rot_prev()))); +} + +PyObject* VoronoiEdgePy::isFinite(PyObject *args) +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this, args); + PyObject *chk = e->ptr->is_finite() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + +PyObject* VoronoiEdgePy::isInfinite(PyObject *args) +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this, args); + PyObject *chk = e->ptr->is_infinite() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + +PyObject* VoronoiEdgePy::isLinear(PyObject *args) +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this, args); + PyObject *chk = e->ptr->is_linear() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + +PyObject* VoronoiEdgePy::isCurved(PyObject *args) +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this, args); + PyObject *chk = e->ptr->is_curved() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + +PyObject* VoronoiEdgePy::isPrimary(PyObject *args) +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this, args); + PyObject *chk = e->ptr->is_primary() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + +PyObject* VoronoiEdgePy::isSecondary(PyObject *args) +{ + VoronoiEdge *e = getVoronoiEdgeFromPy(this, args); + PyObject *chk = e->ptr->is_secondary() ? Py_True : Py_False; + Py_INCREF(chk); + return chk; +} + + +// custom attributes get/set + +PyObject* VoronoiEdgePy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int VoronoiEdgePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + diff --git a/src/Mod/Path/App/VoronoiPy.xml b/src/Mod/Path/App/VoronoiPy.xml index f6e46a37de..5542fc8084 100644 --- a/src/Mod/Path/App/VoronoiPy.xml +++ b/src/Mod/Path/App/VoronoiPy.xml @@ -22,13 +22,13 @@ + --> List of all edges of the voronoi diagram - --> List of all vertices of the voronoi diagram diff --git a/src/Mod/Path/App/VoronoiPyImp.cpp b/src/Mod/Path/App/VoronoiPyImp.cpp index 95d4dd2902..85d744d8d4 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/VoronoiEdge.h" #include "Mod/Path/App/VoronoiVertex.h" #include #include @@ -37,6 +38,7 @@ // files generated out of VoronoiPy.xml #include "VoronoiPy.h" #include "VoronoiPy.cpp" +#include "VoronoiEdgePy.h" #include "VoronoiVertexPy.h" using namespace Path; @@ -149,6 +151,14 @@ Py::List VoronoiPy::getVertices(void) const { return list; } +Py::List VoronoiPy::getEdges(void) const { + Py::List list; + for (int i=0; inumEdges(); ++i) { + list.append(Py::asObject(new VoronoiEdgePy(new VoronoiEdge(getVoronoiPtr()->vd, i)))); + } + return list; +} + // custom attributes get/set PyObject *VoronoiPy::getCustomAttributes(const char* /*attr*/) const diff --git a/src/Mod/Path/App/VoronoiVertex.cpp b/src/Mod/Path/App/VoronoiVertex.cpp index ce1f69164c..c91935b5ca 100644 --- a/src/Mod/Path/App/VoronoiVertex.cpp +++ b/src/Mod/Path/App/VoronoiVertex.cpp @@ -45,8 +45,32 @@ TYPESYSTEM_SOURCE(Path::VoronoiVertex , Base::Persistence) VoronoiVertex::VoronoiVertex(Voronoi::diagram_type *d, long index) : dia(d) , index(index) + , ptr(0) { + if (dia && long(dia->num_vertices()) > index) { + ptr = &(dia->vertices()[index]); + } +} + +VoronoiVertex::VoronoiVertex(Voronoi::diagram_type *d, const Voronoi::diagram_type::vertex_type *v) + : dia(d) + , index(Voronoi::InvalidIndex) + , ptr(v) +{ + if (dia && v) { + index = dia->index(v); + } } VoronoiVertex::~VoronoiVertex() { } + +bool VoronoiVertex::isBound(void) const { + if (ptr != 0 && dia.isValid() && index != Voronoi::InvalidIndex) { + if (&(dia->vertices()[index]) == ptr) { + return true; + } + } + ptr = 0; + return false; +} diff --git a/src/Mod/Path/App/VoronoiVertex.h b/src/Mod/Path/App/VoronoiVertex.h index ab9083dd67..9393f331cc 100644 --- a/src/Mod/Path/App/VoronoiVertex.h +++ b/src/Mod/Path/App/VoronoiVertex.h @@ -39,13 +39,15 @@ class PathExport VoronoiVertex TYPESYSTEM_HEADER(); public: - VoronoiVertex(Voronoi::diagram_type* dia = 0, long index = INT_MAX); + VoronoiVertex(Voronoi::diagram_type *dia = 0, long index = Voronoi::InvalidIndex); + VoronoiVertex(Voronoi::diagram_type *dia, const Voronoi::diagram_type::vertex_type *v); ~VoronoiVertex(); - bool isBound(void) const { return dia.isValid() && index != INT_MAX; } + bool isBound(void) const; Base::Reference dia; long index; + mutable const Voronoi::diagram_type::vertex_type *ptr; }; } diff --git a/src/Mod/Path/App/VoronoiVertexPy.xml b/src/Mod/Path/App/VoronoiVertexPy.xml index 515d849b32..3f90b8b9fa 100644 --- a/src/Mod/Path/App/VoronoiVertexPy.xml +++ b/src/Mod/Path/App/VoronoiVertexPy.xml @@ -34,13 +34,11 @@ - diff --git a/src/Mod/Path/App/VoronoiVertexPyImp.cpp b/src/Mod/Path/App/VoronoiVertexPyImp.cpp index 1dc3c71751..711b18f246 100644 --- a/src/Mod/Path/App/VoronoiVertexPyImp.cpp +++ b/src/Mod/Path/App/VoronoiVertexPyImp.cpp @@ -27,8 +27,12 @@ # include #endif -#include "Mod/Path/App/Voronoi.h" -#include "Mod/Path/App/VoronoiVertex.h" +#include "Voronoi.h" +#include "VoronoiPy.h" +#include "VoronoiEdge.h" +#include "VoronoiEdgePy.h" +#include "VoronoiVertex.h" +#include "VoronoiVertexPy.h" #include #include #include @@ -36,8 +40,6 @@ #include // files generated out of VoronoiVertexPy.xml -#include "VoronoiPy.h" -#include "VoronoiVertexPy.h" #include "VoronoiVertexPy.cpp" using namespace Path; @@ -50,8 +52,7 @@ std::string VoronoiVertexPy::representation(void) const ss << "VoronoiVertex("; VoronoiVertex *v = getVoronoiVertexPtr(); if (v->isBound()) { - Voronoi::diagram_type::vertex_type pt = v->dia->vertices()[v->index]; - ss << "[" << pt.x() << ", " << pt.y() << "]"; + ss << "[" << v->ptr->x() << ", " << v->ptr->y() << "]"; } ss << ")"; return ss.str(); @@ -81,7 +82,7 @@ PyObject* VoronoiVertexPy::richCompare(PyObject *lhs, PyObject *rhs, int op) { && op == Py_EQ) { const VoronoiVertex *vl = static_cast(lhs)->getVoronoiVertexPtr(); const VoronoiVertex *vr = static_cast(rhs)->getVoronoiVertexPtr(); - if (vl->index == vr->index && &(*vl->dia) == &(*vr->dia)) { + if (vl->index == vr->index && vl->dia == vr->dia) { cmp = Py_True; } } @@ -92,7 +93,7 @@ PyObject* VoronoiVertexPy::richCompare(PyObject *lhs, PyObject *rhs, int op) { const Voronoi::voronoi_diagram_type::vertex_type* getVertexFromPy(VoronoiVertexPy *v, bool throwIfNotBound = true) { auto self = v->getVoronoiVertexPtr(); if (self->isBound()) { - return &self->dia->vertices()[self->index]; + return self->ptr; } if (throwIfNotBound) { throw Py::TypeError("Vertex not bound to voronoi diagram"); @@ -103,7 +104,7 @@ const Voronoi::voronoi_diagram_type::vertex_type* getVertexFromPy(VoronoiVertexP Py::Int VoronoiVertexPy::getColor(void) const { VoronoiVertex *v = getVoronoiVertexPtr(); if (v->isBound()) { - return Py::Int(v->dia->vertices()[v->index].color()); + return Py::Int(v->ptr->color()); } return Py::Int(0); } @@ -118,7 +119,7 @@ Py::Float VoronoiVertexPy::getX(void) const if (!v->isBound()) { throw Py::FloatingPointError("Cannot get coordinates of unbound voronoi vertex"); } - return Py::Float(v->dia->vertices()[v->index].x()); + return Py::Float(v->ptr->x()); } Py::Float VoronoiVertexPy::getY(void) const @@ -127,15 +128,16 @@ Py::Float VoronoiVertexPy::getY(void) const if (!v->isBound()) { throw Py::FloatingPointError("Cannot get coordinates of unbound voronoi vertex"); } - return Py::Float(v->dia->vertices()[v->index].y()); + return Py::Float(v->ptr->y()); } -#if 0 Py::Object VoronoiVertexPy::getIncidentEdge() const { - Py_INCREF(Py_None); - return Py_None; + VoronoiVertex *v = getVoronoiVertexPtr(); + if (!v->isBound()) { + throw Py::TypeError("Vertex not bound to voronoi diagram"); + } + return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(v->dia, v->ptr->incident_edge()))); } -#endif // custom attributes get/set