Added geometries for vertices and linear edges.
This commit is contained in:
committed by
sliptonic
parent
9ba8817382
commit
10e5fce11c
@@ -121,11 +121,11 @@ Voronoi::~Voronoi()
|
||||
|
||||
|
||||
void Voronoi::addPoint(const Voronoi::point_type &p) {
|
||||
points.push_back(p);
|
||||
vd->points.push_back(p);
|
||||
}
|
||||
|
||||
void Voronoi::addSegment(const Voronoi::segment_type &s) {
|
||||
segments.push_back(s);
|
||||
vd->segments.push_back(s);
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +144,6 @@ long Voronoi::numVertices() const {
|
||||
void Voronoi::construct()
|
||||
{
|
||||
vd->clear();
|
||||
construct_voronoi(points.begin(), points.end(), segments.begin(), segments.end(), (voronoi_diagram_type*)vd);
|
||||
construct_voronoi(vd->points.begin(), vd->points.end(), vd->segments.begin(), vd->segments.end(), (voronoi_diagram_type*)vd);
|
||||
vd->reIndex();
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace Path
|
||||
typedef boost::polygon::point_data<coordinate_type> point_type;
|
||||
typedef boost::polygon::segment_data<coordinate_type> segment_type;
|
||||
typedef boost::polygon::voronoi_diagram<coordinate_type> voronoi_diagram_type;
|
||||
|
||||
class diagram_type
|
||||
: public voronoi_diagram_type
|
||||
, public Base::Handled
|
||||
@@ -68,6 +69,9 @@ namespace Path
|
||||
|
||||
void reIndex();
|
||||
|
||||
std::vector<point_type> points;
|
||||
std::vector<segment_type> segments;
|
||||
|
||||
private:
|
||||
cell_map_type cell_index;
|
||||
edge_map_type edge_index;
|
||||
@@ -84,8 +88,6 @@ namespace Path
|
||||
long numVertices() const;
|
||||
|
||||
// attributes
|
||||
std::vector<point_type> points;
|
||||
std::vector<segment_type> segments;
|
||||
Base::Reference<diagram_type> vd;
|
||||
};
|
||||
|
||||
|
||||
@@ -74,3 +74,21 @@ bool VoronoiCell::isBound(void) const {
|
||||
ptr = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
Voronoi::point_type VoronoiCell::sourcePoint() const {
|
||||
int index = ptr->source_index();
|
||||
int category = ptr->source_category();
|
||||
if (category == boost::polygon::SOURCE_CATEGORY_SINGLE_POINT) {
|
||||
return dia->points[index];
|
||||
}
|
||||
if (category == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) {
|
||||
return low(dia->segments[index - dia->points.size()]);
|
||||
} else {
|
||||
return high(dia->segments[index - dia->points.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
Voronoi::segment_type VoronoiCell::sourceSegment() const {
|
||||
return dia->segments[ptr->source_index() - dia->points.size()];
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ public:
|
||||
|
||||
bool isBound(void) const;
|
||||
|
||||
Voronoi::point_type sourcePoint() const;
|
||||
Voronoi::segment_type sourceSegment() const;
|
||||
|
||||
Base::Reference<Voronoi::diagram_type> dia;
|
||||
long index;
|
||||
mutable const Voronoi::diagram_type::cell_type *ptr;
|
||||
|
||||
@@ -94,6 +94,10 @@
|
||||
<UserDocu>Returns true if edge goes through endpoint of the segment site</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
-->
|
||||
<Methode Name="getGeom" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns true if edge goes through endpoint of the segment site</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <Base/PlacementPy.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Mod/Part/App/LineSegmentPy.h>
|
||||
|
||||
// files generated out of VoronoiEdgePy.xml
|
||||
#include "VoronoiEdgePy.cpp"
|
||||
@@ -248,6 +249,96 @@ PyObject* VoronoiEdgePy::isSecondary(PyObject *args)
|
||||
return chk;
|
||||
}
|
||||
|
||||
namespace {
|
||||
Voronoi::point_type retrievPoint(Voronoi::diagram_type *dia, const Voronoi::diagram_type::cell_type *cell) {
|
||||
Voronoi::diagram_type::cell_type::source_index_type index = cell->source_index();
|
||||
Voronoi::diagram_type::cell_type::source_category_type category = cell->source_category();
|
||||
if (category == boost::polygon::SOURCE_CATEGORY_SINGLE_POINT) {
|
||||
return dia->points[index];
|
||||
}
|
||||
index -= dia->points.size();
|
||||
if (category == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) {
|
||||
return low(dia->segments[index]);
|
||||
} else {
|
||||
return high(dia->segments[index]);
|
||||
}
|
||||
}
|
||||
|
||||
Voronoi::segment_type retrieveSegment(Voronoi::diagram_type *dia, const Voronoi::diagram_type::cell_type *cell) {
|
||||
Voronoi::diagram_type::cell_type::source_index_type index = cell->source_index() - dia->points.size();
|
||||
return dia->segments[index];
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* VoronoiEdgePy::getGeom(PyObject *args)
|
||||
{
|
||||
double z = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "|d", &z)) {
|
||||
throw Py::RuntimeError("single argument of type double accepted");
|
||||
}
|
||||
VoronoiEdge *e = getVoronoiEdgePtr();
|
||||
if (e->isBound()) {
|
||||
if (e->ptr->is_linear()) {
|
||||
if (e->ptr->is_finite()) {
|
||||
auto v0 = e->ptr->vertex0();
|
||||
auto v1 = e->ptr->vertex1();
|
||||
if (v0 && v1) {
|
||||
auto p = new Part::GeomLineSegment();
|
||||
p->setPoints(Base::Vector3d(v0->x(), v0->y(), z), Base::Vector3d(v1->x(), v1->y(), z));
|
||||
return new Part::LineSegmentPy(p);
|
||||
}
|
||||
} else {
|
||||
// infinite linear, need to clip somehow
|
||||
const Voronoi::diagram_type::cell_type *c0 = e->ptr->cell();
|
||||
const Voronoi::diagram_type::cell_type *c1 = e->ptr->twin()->cell();
|
||||
Voronoi::point_type origin;
|
||||
Voronoi::point_type direction;
|
||||
if (c0->contains_point() && c1->contains_point()) {
|
||||
Voronoi::point_type p0 = retrievPoint(e->dia, c0);
|
||||
Voronoi::point_type p1 = retrievPoint(e->dia, c1);
|
||||
origin.x((p0.x() + p1.x()) / 2.);
|
||||
origin.y((p0.y() + p1.y()) / 2.);
|
||||
direction.x(p0.y() - p1.y());
|
||||
direction.y(p1.x() - p0.x());
|
||||
} else {
|
||||
origin = c0->contains_segment() ? retrievPoint(e->dia, c1) : retrievPoint(e->dia, c0);
|
||||
Voronoi::segment_type segment = c0->contains_segment() ? retrieveSegment(e->dia, c0) : retrieveSegment(e->dia, c1);
|
||||
Voronoi::coordinate_type dx = high(segment).x() - low(segment).x();
|
||||
Voronoi::coordinate_type dy = high(segment).y() - low(segment).y();
|
||||
if ((low(segment) == origin) ^ c0->contains_point()) {
|
||||
direction.x(dy);
|
||||
direction.y(-dx);
|
||||
} else {
|
||||
direction.x(-dy);
|
||||
direction.y(dx);
|
||||
}
|
||||
}
|
||||
double k = 10.0;
|
||||
Voronoi::point_type begin;
|
||||
Voronoi::point_type end;
|
||||
if (e->ptr->vertex0()) {
|
||||
begin.x(e->ptr->vertex0()->x());
|
||||
begin.y(e->ptr->vertex0()->y());
|
||||
} else {
|
||||
begin.x(origin.x() - direction.x() * k);
|
||||
begin.y(origin.y() - direction.y() * k);
|
||||
}
|
||||
if (e->ptr->vertex1()) {
|
||||
end.x(e->ptr->vertex1()->x());
|
||||
end.y(e->ptr->vertex1()->y());
|
||||
} else {
|
||||
end.x(origin.x() + direction.x() * k);
|
||||
end.y(origin.y() + direction.y() * k);
|
||||
}
|
||||
auto p = new Part::GeomLineSegment();
|
||||
p->setPoints(Base::Vector3d(begin.x(), begin.y(), z), Base::Vector3d(end.x(), end.y()));
|
||||
return new Part::LineSegmentPy(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
// custom attributes get/set
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ std::string VoronoiPy::representation(void) const
|
||||
std::stringstream ss;
|
||||
ss.precision(5);
|
||||
ss << "Voronoi("
|
||||
<< "{" << getVoronoiPtr()->segments.size() << ", " << getVoronoiPtr()->points.size() << "}"
|
||||
<< "{" << getVoronoiPtr()->vd->segments.size() << ", " << getVoronoiPtr()->vd->points.size() << "}"
|
||||
<< " -> "
|
||||
<< "{" << getVoronoiPtr()->numCells() << ", " << getVoronoiPtr()->numEdges() << ", " << getVoronoiPtr()->numVertices() << "}"
|
||||
<< ")";
|
||||
@@ -92,7 +92,7 @@ Voronoi::point_type getPointFromPy(PyObject *obj) {
|
||||
PyObject* VoronoiPy::addPoint(PyObject *args) {
|
||||
PyObject *obj = 0;
|
||||
if (PyArg_ParseTuple(args, "O", &obj)) {
|
||||
getVoronoiPtr()->points.push_back(getPointFromPy(obj));
|
||||
getVoronoiPtr()->vd->points.push_back(getPointFromPy(obj));
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
@@ -105,7 +105,7 @@ PyObject* VoronoiPy::addSegment(PyObject *args) {
|
||||
if (PyArg_ParseTuple(args, "OO", &objBegin, &objEnd)) {
|
||||
auto p0 = getPointFromPy(objBegin);
|
||||
auto p1 = getPointFromPy(objEnd);
|
||||
getVoronoiPtr()->segments.push_back(Voronoi::segment_type(p0, p1));
|
||||
getVoronoiPtr()->vd->segments.push_back(Voronoi::segment_type(p0, p1));
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
@@ -40,5 +40,10 @@
|
||||
</Documentation>
|
||||
<Parameter Name="IncidentEdge" Type="Object"/>
|
||||
</Attribute>
|
||||
<Methode Name="getGeom" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns a Vertex - or None if not possible</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
|
||||
@@ -140,6 +140,20 @@ Py::Object VoronoiVertexPy::getIncidentEdge() const {
|
||||
return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(v->dia, v->ptr->incident_edge())));
|
||||
}
|
||||
|
||||
PyObject* VoronoiVertexPy::getGeom(PyObject *args)
|
||||
{
|
||||
double z = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "|d", &z)) {
|
||||
throw Py::RuntimeError("single argument of type double accepted");
|
||||
}
|
||||
VoronoiVertex *v = getVoronoiVertexPtr();
|
||||
if (v->isBound()) {
|
||||
return new Base::VectorPy(new Base::Vector3d(v->ptr->x(), v->ptr->y(), z));
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
// custom attributes get/set
|
||||
|
||||
PyObject* VoronoiVertexPy::getCustomAttributes(const char* /*attr*/) const
|
||||
|
||||
Reference in New Issue
Block a user