Added borderline interface to voronoi edge
This commit is contained in:
@@ -36,10 +36,16 @@
|
||||
</Attribute>
|
||||
<Attribute Name="SourceCategory" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the index of the cell's source</UserDocu>
|
||||
<UserDocu>Returns the cell's category as an integer</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="SourceCategory" Type="Int"/>
|
||||
</Attribute>
|
||||
<Attribute Name="SourceCategoryName" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns the cell's category as a string</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="SourceCategory" Type="String"/>
|
||||
</Attribute>
|
||||
<Attribute Name="IncidentEdge" ReadOnly="true">
|
||||
<Documentation>
|
||||
<UserDocu>Incident edge of the cell - if exists</UserDocu>
|
||||
|
||||
@@ -137,6 +137,21 @@ Py::Int VoronoiCellPy::getSourceCategory(void) const
|
||||
return Py::Int(c->ptr->source_category());
|
||||
}
|
||||
|
||||
Py::String VoronoiCellPy::getSourceCategoryName(void) const
|
||||
{
|
||||
VoronoiCell *c = getVoronoiCellFromPy(this);
|
||||
switch (c->ptr->source_category()) {
|
||||
case boost::polygon::SOURCE_CATEGORY_SINGLE_POINT: return Py::String("SINGLE_POINT");
|
||||
case boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT: return Py::String("SEGMENT_START_POINT");
|
||||
case boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT: return Py::String("SEGMENT_END_POINT");
|
||||
case boost::polygon::SOURCE_CATEGORY_INITIAL_SEGMENT: return Py::String("INITIAL_SEGMENT");
|
||||
case boost::polygon::SOURCE_CATEGORY_REVERSE_SEGMENT: return Py::String("REVERSE_SEGMENT");
|
||||
case boost::polygon::SOURCE_CATEGORY_GEOMETRY_SHIFT: return Py::String("GEOMETRY_SHIFT");
|
||||
case boost::polygon::SOURCE_CATEGORY_BITMASK: return Py::String("BITMASK");
|
||||
}
|
||||
return Py::String("");
|
||||
}
|
||||
|
||||
Py::Object VoronoiCellPy::getIncidentEdge(void) const
|
||||
{
|
||||
VoronoiCell *c = getVoronoiCellFromPy(this);
|
||||
|
||||
@@ -100,6 +100,11 @@
|
||||
<UserDocu>Returns true if edge goes through endpoint of the segment site</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="isBorderline" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns true if the point is on the segment</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="toShape" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns a shape for the edge</UserDocu>
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "VoronoiVertex.h"
|
||||
#include "VoronoiVertexPy.h"
|
||||
|
||||
|
||||
using namespace Path;
|
||||
|
||||
namespace {
|
||||
@@ -164,6 +163,22 @@ namespace {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pointsMatch(const Voronoi::point_type &p0, const Voronoi::point_type &p1, double scale) {
|
||||
return 1e-6 > distanceBetween(p0, p1, scale);
|
||||
}
|
||||
|
||||
bool isPointOnSegment(const Voronoi::point_type &point, const Voronoi::segment_type &segment, double scale) {
|
||||
return pointsMatch(point, low(segment), scale) || pointsMatch(point, high(segment), scale);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
PyObject* makeLineSegment(const VoronoiEdge *e, const T &p0, double z0, const T &p1, double z1) {
|
||||
Part::GeomLineSegment p;
|
||||
p.setPoints(e->dia->scaledVector(p0, z0), e->dia->scaledVector(p1, z1));
|
||||
Handle(Geom_Curve) h = Handle(Geom_Curve)::DownCast(p.handle());
|
||||
BRepBuilderAPI_MakeEdge mkBuilder(h, h->FirstParameter(), h->LastParameter());
|
||||
return new Part::TopoShapeEdgePy(new Part::TopoShape(mkBuilder.Shape()));
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Voronoi::vertex_type &v) {
|
||||
@@ -388,6 +403,21 @@ PyObject* VoronoiEdgePy::isSecondary(PyObject *args)
|
||||
return chk;
|
||||
}
|
||||
|
||||
PyObject* VoronoiEdgePy::isBorderline(PyObject *args)
|
||||
{
|
||||
VoronoiEdge *e = getVoronoiEdgeFromPy(this, args);
|
||||
PyObject *chk = Py_False;
|
||||
if (e->isBound() && !e->ptr->is_linear()) {
|
||||
Voronoi::point_type point = e->ptr->cell()->contains_point() ? e->dia->retrievePoint(e->ptr->cell()) : e->dia->retrievePoint(e->ptr->twin()->cell());
|
||||
Voronoi::segment_type segment = e->ptr->cell()->contains_point() ? e->dia->retrieveSegment(e->ptr->twin()->cell()) : e->dia->retrieveSegment(e->ptr->cell());
|
||||
if (isPointOnSegment(point, segment, e->dia->getScale())) {
|
||||
chk = Py_True;
|
||||
}
|
||||
}
|
||||
Py_INCREF(chk);
|
||||
return chk;
|
||||
}
|
||||
|
||||
PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
{
|
||||
double z0 = 0.0;
|
||||
@@ -406,11 +436,7 @@ PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
auto v0 = e->ptr->vertex0();
|
||||
auto v1 = e->ptr->vertex1();
|
||||
if (v0 && v1) {
|
||||
Part::GeomLineSegment p;
|
||||
p.setPoints(e->dia->scaledVector(*v0, z0), e->dia->scaledVector(*v1, z1));
|
||||
Handle(Geom_Curve) h = Handle(Geom_Curve)::DownCast(p.handle());
|
||||
BRepBuilderAPI_MakeEdge mkBuilder(h, h->FirstParameter(), h->LastParameter());
|
||||
return new Part::TopoShapeEdgePy(new Part::TopoShape(mkBuilder.Shape()));
|
||||
return makeLineSegment(e, *v0, z0, *v1, z1);
|
||||
}
|
||||
} else {
|
||||
// infinite linear, need to clip somehow
|
||||
@@ -455,11 +481,7 @@ PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
end.x(origin.x() + direction.x() * k);
|
||||
end.y(origin.y() + direction.y() * k);
|
||||
}
|
||||
Part::GeomLineSegment p;
|
||||
p.setPoints(e->dia->scaledVector(begin, z0), e->dia->scaledVector(end, z1));
|
||||
Handle(Geom_Curve) h = Handle(Geom_Curve)::DownCast(p.handle());
|
||||
BRepBuilderAPI_MakeEdge mkBuilder(h, h->FirstParameter(), h->LastParameter());
|
||||
return new Part::TopoShapeEdgePy(new Part::TopoShape(mkBuilder.Shape()));
|
||||
return makeLineSegment(e, begin, z0, end, z1);
|
||||
}
|
||||
} else {
|
||||
// parabolic curve, which is always formed by a point and an edge
|
||||
@@ -467,6 +489,11 @@ PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
Voronoi::segment_type segment = e->ptr->cell()->contains_point() ? e->dia->retrieveSegment(e->ptr->twin()->cell()) : e->dia->retrieveSegment(e->ptr->cell());
|
||||
// the location is the mid point between the normal on the segment through point
|
||||
// this is only the mid point of the segment if the parabola is symmetric
|
||||
|
||||
if (isPointOnSegment(point, segment, e->dia->getScale())) {
|
||||
return makeLineSegment(e, low(segment), z0, high(segment), z1);
|
||||
}
|
||||
|
||||
Voronoi::point_type loc;
|
||||
{
|
||||
Voronoi::point_type proj = orthognalProjection(point, segment);
|
||||
@@ -495,7 +522,7 @@ PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
double dist1 = distanceBetween(pt1, pt1x, e->dia->getScale()) * sideOf(pt1, xaxis);
|
||||
if (dist1 < dist0) {
|
||||
// if the parabola is traversed in the revere direction we need to use the points
|
||||
// on the other side of the parabola - beauty of symmetric geometries
|
||||
// on the other side of the parabola - 'beauty of symmetric geometries
|
||||
dist0 = -dist0;
|
||||
dist1 = -dist1;
|
||||
}
|
||||
@@ -521,6 +548,9 @@ PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
// focal length if parabola in the xy-plane is simply half the distance between the
|
||||
// point and segment - aka the distance between point and location, aka the length of axis
|
||||
focal = length(axis) / e->dia->getScale();
|
||||
if (dbg) {
|
||||
std::cerr << "focal = " << length(axis) << "/" << e->dia->getScale() << "\n";
|
||||
}
|
||||
} else {
|
||||
// if the parabola is not in the xy-plane we need to find the
|
||||
// (x,y) coordinates of a point on the parabola in the parabola's
|
||||
@@ -555,6 +585,7 @@ PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
std::cerr << " loc" << loc << ", axis" << axis << std::endl;
|
||||
std::cerr << " dist0(" << dist0 << " : " << flenX0 << ", dist1(" << dist1 << " : " << flenX1 << ")" << std::endl;
|
||||
std::cerr << " z(" << z0 << ", " << zx << ", " << z1 << ")" << std::endl;
|
||||
std::cerr << " focal = (" << flenX << " * " << flenX << ") / (4 * fabs(" << flenY << "))\n";
|
||||
}
|
||||
// use new X values to set the parameters
|
||||
dist0 = dist0 >= 0 ? flenX0 : -flenX0;
|
||||
|
||||
Reference in New Issue
Block a user