Added borderline interface to voronoi edge
This commit is contained in:
@@ -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