Replaced toGeom with toPoint for VoronoiVertex and toShape for VoronoiEdge - results in arbitrary orientation of parabola for multiple z
This commit is contained in:
@@ -100,9 +100,9 @@
|
||||
<UserDocu>Returns true if edge goes through endpoint of the segment site</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="toGeom" Const="true">
|
||||
<Methode Name="toShape" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns a geom representation of the edge (line segment or arc of parabola)</UserDocu>
|
||||
<UserDocu>Returns a shape for the edge</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Methode Name="getDistances" Const="true">
|
||||
|
||||
@@ -24,9 +24,12 @@
|
||||
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <boost/algorithm/string.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "BRepLib.hxx"
|
||||
#include "BRepTools.hxx"
|
||||
#include "BRepBuilderAPI_MakeEdge.hxx"
|
||||
#include "BRepBuilderAPI_MakeFace.hxx"
|
||||
#include "BRepProj_Projection.hxx"
|
||||
#include "Mod/Path/App/Voronoi.h"
|
||||
#include "Mod/Path/App/Voronoi.h"
|
||||
#include "Mod/Path/App/VoronoiCell.h"
|
||||
@@ -40,14 +43,109 @@
|
||||
#include <Base/PlacementPy.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Base/VectorPy.h>
|
||||
#include <Mod/Part/App/LineSegmentPy.h>
|
||||
#include <Mod/Part/App/ArcOfParabolaPy.h>
|
||||
#include <Mod/Part/App/LineSegmentPy.h>
|
||||
#include <Mod/Part/App/TopoShapeEdgePy.h>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <Standard_Version.hxx>
|
||||
#include <Base/Tools.h>
|
||||
#endif
|
||||
|
||||
// files generated out of VoronoiEdgePy.xml
|
||||
#include "VoronoiEdgePy.cpp"
|
||||
|
||||
using namespace Path;
|
||||
|
||||
namespace {
|
||||
|
||||
Voronoi::point_type orthognalProjection(const Voronoi::point_type &point, const Voronoi::segment_type &segment) {
|
||||
// move segment so it goes through the origin (s)
|
||||
Voronoi::point_type offset;
|
||||
{
|
||||
offset.x(low(segment).x());
|
||||
offset.y(low(segment).y());
|
||||
}
|
||||
Voronoi::point_type s;
|
||||
{
|
||||
s.x(high(segment).x() - offset.x());
|
||||
s.y(high(segment).y() - offset.y());
|
||||
}
|
||||
// move point accordingly so it maintains it's relation to s (p)
|
||||
Voronoi::point_type p;
|
||||
{
|
||||
p.x(point.x() - offset.x());
|
||||
p.y(point.y() - offset.y());
|
||||
}
|
||||
// calculate the orthogonal projection of p onto s
|
||||
// ((p dot s) / (s dot s)) * s (https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line)
|
||||
// and it back by original offset to get the projected point
|
||||
double proj = (p.x() * s.x() + p.y() * s.y()) / (s.x() * s.x() + s.y() * s.y());
|
||||
Voronoi::point_type pt;
|
||||
{
|
||||
pt.x(offset.x() + proj * s.x());
|
||||
pt.y(offset.y() + proj * s.y());
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
|
||||
template<typename pt_type>
|
||||
double distanceBetween(const Voronoi::diagram_type::vertex_type &v0, const pt_type &p1, double scale) {
|
||||
double x = v0.x() - p1.x();
|
||||
double y = v0.y() - p1.y();
|
||||
return sqrt(x * x + y * y) / scale;
|
||||
}
|
||||
|
||||
void addDistanceBetween(const Voronoi::diagram_type::vertex_type *v0, const Voronoi::point_type &p1, Py::List *list, double scale) {
|
||||
if (v0) {
|
||||
list->append(Py::Float(distanceBetween(*v0, p1, scale)));
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
list->append(Py::asObject(Py_None));
|
||||
}
|
||||
}
|
||||
|
||||
void addProjectedDistanceBetween(const Voronoi::diagram_type::vertex_type *v0, const Voronoi::segment_type &segment, Py::List *list, double scale) {
|
||||
if (v0) {
|
||||
Voronoi::point_type p0;
|
||||
{
|
||||
p0.x(v0->x());
|
||||
p0.y(v0->y());
|
||||
}
|
||||
Voronoi::point_type p1 = orthognalProjection(p0, segment);
|
||||
list->append(Py::Float(distanceBetween(*v0, p1, scale)));
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
list->append(Py::asObject(Py_None));
|
||||
}
|
||||
}
|
||||
|
||||
bool addDistancesToPoint(const VoronoiEdge *edge, Voronoi::point_type p, Py::List *list, double scale) {
|
||||
addDistanceBetween(edge->ptr->vertex0(), p, list, scale);
|
||||
addDistanceBetween(edge->ptr->vertex1(), p, list, scale);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool retrieveDistances(const VoronoiEdge *edge, Py::List *list) {
|
||||
const Voronoi::diagram_type::cell_type *c0 = edge->ptr->cell();
|
||||
if (c0->contains_point()) {
|
||||
return addDistancesToPoint(edge, edge->dia->retrievePoint(c0), list, edge->dia->getScale());
|
||||
}
|
||||
const Voronoi::diagram_type::cell_type *c1 = edge->ptr->twin()->cell();
|
||||
if (c1->contains_point()) {
|
||||
return addDistancesToPoint(edge, edge->dia->retrievePoint(c1), list, edge->dia->getScale());
|
||||
}
|
||||
// at this point both cells are sourced from segments and it does not matter which one we use
|
||||
Voronoi::segment_type segment = edge->dia->retrieveSegment(c0);
|
||||
addProjectedDistanceBetween(edge->ptr->vertex0(), segment, list, edge->dia->getScale());
|
||||
addProjectedDistanceBetween(edge->ptr->vertex1(), segment, list, edge->dia->getScale());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string VoronoiEdgePy::representation(void) const
|
||||
{
|
||||
@@ -257,43 +355,15 @@ PyObject* VoronoiEdgePy::isSecondary(PyObject *args)
|
||||
return chk;
|
||||
}
|
||||
|
||||
namespace {
|
||||
Voronoi::point_type orthognalProjection(const Voronoi::point_type &point, const Voronoi::segment_type &segment) {
|
||||
// move segment so it goes through the origin (s)
|
||||
Voronoi::point_type offset;
|
||||
{
|
||||
offset.x(low(segment).x());
|
||||
offset.y(low(segment).y());
|
||||
}
|
||||
Voronoi::point_type s;
|
||||
{
|
||||
s.x(high(segment).x() - offset.x());
|
||||
s.y(high(segment).y() - offset.y());
|
||||
}
|
||||
// move point accordingly so it maintains it's relation to s (p)
|
||||
Voronoi::point_type p;
|
||||
{
|
||||
p.x(point.x() - offset.x());
|
||||
p.y(point.y() - offset.y());
|
||||
}
|
||||
// calculate the orthogonal projection of p onto s
|
||||
// ((p dot s) / (s dot s)) * s (https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line)
|
||||
// and it back by original offset to get the projected point
|
||||
double proj = (p.x() * s.x() + p.y() * s.y()) / (s.x() * s.x() + s.y() * s.y());
|
||||
Voronoi::point_type pt;
|
||||
{
|
||||
pt.x(offset.x() + proj * s.x());
|
||||
pt.y(offset.y() + proj * s.y());
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* VoronoiEdgePy::toGeom(PyObject *args)
|
||||
PyObject* VoronoiEdgePy::toShape(PyObject *args)
|
||||
{
|
||||
double z = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "|d", &z)) {
|
||||
throw Py::RuntimeError("single argument of type double accepted");
|
||||
double z0 = 0.0;
|
||||
double z1 = DBL_MAX;
|
||||
if (!PyArg_ParseTuple(args, "|dd", &z0, &z1)) {
|
||||
throw Py::RuntimeError("no, one or two arguments of type double accepted");
|
||||
}
|
||||
if (z1 == DBL_MAX) {
|
||||
z1 = z0;
|
||||
}
|
||||
VoronoiEdge *e = getVoronoiEdgePtr();
|
||||
if (e->isBound()) {
|
||||
@@ -303,8 +373,10 @@ PyObject* VoronoiEdgePy::toGeom(PyObject *args)
|
||||
auto v1 = e->ptr->vertex1();
|
||||
if (v0 && v1) {
|
||||
auto p = new Part::GeomLineSegment;
|
||||
p->setPoints(e->dia->scaledVector(*v0, z), e->dia->scaledVector(*v1, z));
|
||||
return new Part::LineSegmentPy(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()));
|
||||
}
|
||||
} else {
|
||||
// infinite linear, need to clip somehow
|
||||
@@ -350,8 +422,10 @@ PyObject* VoronoiEdgePy::toGeom(PyObject *args)
|
||||
end.y(origin.y() + direction.y() * k);
|
||||
}
|
||||
auto p = new Part::GeomLineSegment;
|
||||
p->setPoints(e->dia->scaledVector(begin, z), e->dia->scaledVector(end, z));
|
||||
return new Part::LineSegmentPy(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()));
|
||||
}
|
||||
} else {
|
||||
// parabolic curve, which is always formed by a point and an edge
|
||||
@@ -373,8 +447,8 @@ PyObject* VoronoiEdgePy::toGeom(PyObject *args)
|
||||
}
|
||||
auto p = new Part::GeomParabola;
|
||||
{
|
||||
p->setCenter(e->dia->scaledVector(point, z));
|
||||
p->setLocation(e->dia->scaledVector(loc, z));
|
||||
p->setCenter(e->dia->scaledVector(point, z0));
|
||||
p->setLocation(e->dia->scaledVector(loc, z0));
|
||||
p->setAngleXU(atan2(axis.y(), axis.x()));
|
||||
p->setFocal(sqrt(axis.x() * axis.x() + axis.y() * axis.y()) / e->dia->getScale());
|
||||
}
|
||||
@@ -387,15 +461,86 @@ PyObject* VoronoiEdgePy::toGeom(PyObject *args)
|
||||
auto v1 = e->ptr->vertex1();
|
||||
double param0 = 0;
|
||||
double param1 = 0;
|
||||
if (!p->closestParameter(e->dia->scaledVector(*v0, z), param0)) {
|
||||
if (!p->closestParameter(e->dia->scaledVector(*v0, z0), param0)) {
|
||||
std::cerr << "closestParameter(v0) failed" << std::endl;
|
||||
}
|
||||
if (!p->closestParameter(e->dia->scaledVector(*v1, z), param1)) {
|
||||
if (!p->closestParameter(e->dia->scaledVector(*v1, z0), param1)) {
|
||||
std::cerr << "closestParameter(v0) failed" << std::endl;
|
||||
}
|
||||
a->setRange(param0, param1, false);
|
||||
std::cerr << "range(" << param0 << ", " << param1 << ")" << std::endl;
|
||||
|
||||
if (z0 != z1) {
|
||||
// two points of the plane are the end points of the parabola at the correct z level
|
||||
auto p0 = e->dia->scaledVector(*v0, z0);
|
||||
auto p1 = e->dia->scaledVector(*v1, z1);
|
||||
// we get a third point by moving p0 along the axis of the parabola
|
||||
auto p0_ = e->dia->scaledVector(v0->x() + axis.x(), v0->y() + axis.y(), z0);
|
||||
// normal of the plane defined by those 3 points
|
||||
auto norm = ((p1 - p0).Cross(p0_ - p0)).Normalize();
|
||||
|
||||
if (true) {
|
||||
double r = Distance(p0, p1) * 10;
|
||||
|
||||
// construct a face we can project the parabola on
|
||||
Handle(Geom_Plane) plane = new Geom_Plane(gp_Pnt(p0.x, p0.y, p0.z), gp_Dir(norm.x, norm.y, norm.z));
|
||||
BRepBuilderAPI_MakeFace mkFace(plane, -r, r, -r, r
|
||||
#if OCC_VERSION_HEX >= 0x060502
|
||||
, Precision::Confusion()
|
||||
#endif
|
||||
);
|
||||
|
||||
// get a shape for the parabola arc
|
||||
Handle(Geom_Curve) arc = Handle(Geom_Curve)::DownCast(a->handle());
|
||||
BRepBuilderAPI_MakeEdge parab(arc, arc->FirstParameter(), arc->LastParameter());
|
||||
|
||||
// get projection of parabola onto the plane
|
||||
BRepProj_Projection projection(parab.Shape(), mkFace.Shape(), gp::DZ());
|
||||
TopoDS_Shape shape = projection.Shape();
|
||||
|
||||
// what we get is a compound shape - but we're pretty sure there's only a single edge
|
||||
// in there. if that's the case - return just that single edge
|
||||
TopTools_IndexedMapOfShape map;
|
||||
for (TopExp_Explorer it(shape, TopAbs_EDGE); it.More(); it.Next()) {
|
||||
map.Add(it.Current());
|
||||
}
|
||||
if (map.Extent() == 1) {
|
||||
// there's indeed just a single edge in the compound. Unfortunately the edge
|
||||
// can end up being oriented the wrong way.
|
||||
TopoDS_Shape edge = map(1);
|
||||
edge.Orientation((edge.Orientation() == TopAbs_REVERSED) ? TopAbs_FORWARD : TopAbs_REVERSED);
|
||||
return new Part::TopoShapeEdgePy(new Part::TopoShape(edge));
|
||||
}
|
||||
return new Part::TopoShapePy(new Part::TopoShape(shape));
|
||||
} else {
|
||||
std::cerr << "hugo" << std::endl;
|
||||
double scale = Distance(p0, p1) / distanceBetween(*v0, *v1, e->dia->getScale());
|
||||
double kz = param0 / fabs(param0 - param1);
|
||||
double zc = z0 + (z0 - z1) * kz;
|
||||
|
||||
auto center = e->dia->scaledVector(point, zc);
|
||||
auto location = e->dia->scaledVector(loc, zc);
|
||||
//p->setCenter(center);
|
||||
//p->setLocation(location);
|
||||
p->setFocal(p->getFocal() * scale * scale);
|
||||
|
||||
Handle(Geom_TrimmedCurve) trim = Handle(Geom_TrimmedCurve)::DownCast(a->handle());
|
||||
Handle(Geom_Parabola) parabola = Handle(Geom_Parabola)::DownCast(trim->BasisCurve());
|
||||
gp_Ax1 axis;
|
||||
axis.SetLocation(gp_Pnt(location.x, location.y, location.z));
|
||||
axis.SetDirection(gp_Dir(norm.x, norm.y, norm.z));
|
||||
parabola->SetAxis(axis);
|
||||
parabola->SetFocal(p->getFocal() / scale);
|
||||
|
||||
a->setRange(param0 * scale, param1 * scale, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Part::ArcOfParabolaPy(a);
|
||||
|
||||
// get a shape for the parabola arc
|
||||
Handle(Geom_Curve) h = Handle(Geom_Curve)::DownCast(a->handle());
|
||||
BRepBuilderAPI_MakeEdge mkBuilder(h, h->FirstParameter(), h->LastParameter());
|
||||
return new Part::TopoShapeEdgePy(new Part::TopoShape(mkBuilder.Shape()));
|
||||
}
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
@@ -403,61 +548,6 @@ PyObject* VoronoiEdgePy::toGeom(PyObject *args)
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
double distanceBetween(const Voronoi::diagram_type::vertex_type &v0, const Voronoi::point_type &p1, double scale) {
|
||||
double x = v0.x() - p1.x();
|
||||
double y = v0.y() - p1.y();
|
||||
return sqrt(x * x + y * y) / scale;
|
||||
}
|
||||
|
||||
void addDistanceBetween(const Voronoi::diagram_type::vertex_type *v0, const Voronoi::point_type &p1, Py::List *list, double scale) {
|
||||
if (v0) {
|
||||
list->append(Py::Float(distanceBetween(*v0, p1, scale)));
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
list->append(Py::asObject(Py_None));
|
||||
}
|
||||
}
|
||||
|
||||
void addProjectedDistanceBetween(const Voronoi::diagram_type::vertex_type *v0, const Voronoi::segment_type &segment, Py::List *list, double scale) {
|
||||
if (v0) {
|
||||
Voronoi::point_type p0;
|
||||
{
|
||||
p0.x(v0->x());
|
||||
p0.y(v0->y());
|
||||
}
|
||||
Voronoi::point_type p1 = orthognalProjection(p0, segment);
|
||||
list->append(Py::Float(distanceBetween(*v0, p1, scale)));
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
list->append(Py::asObject(Py_None));
|
||||
}
|
||||
}
|
||||
|
||||
bool addDistancesToPoint(const VoronoiEdge *edge, Voronoi::point_type p, Py::List *list, double scale) {
|
||||
addDistanceBetween(edge->ptr->vertex0(), p, list, scale);
|
||||
addDistanceBetween(edge->ptr->vertex1(), p, list, scale);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool retrieveDistances(const VoronoiEdge *edge, Py::List *list) {
|
||||
const Voronoi::diagram_type::cell_type *c0 = edge->ptr->cell();
|
||||
if (c0->contains_point()) {
|
||||
return addDistancesToPoint(edge, edge->dia->retrievePoint(c0), list, edge->dia->getScale());
|
||||
}
|
||||
const Voronoi::diagram_type::cell_type *c1 = edge->ptr->twin()->cell();
|
||||
if (c1->contains_point()) {
|
||||
return addDistancesToPoint(edge, edge->dia->retrievePoint(c1), list, edge->dia->getScale());
|
||||
}
|
||||
// at this point both cells are sourced from segments and it does not matter which one we use
|
||||
Voronoi::segment_type segment = edge->dia->retrieveSegment(c0);
|
||||
addProjectedDistanceBetween(edge->ptr->vertex0(), segment, list, edge->dia->getScale());
|
||||
addProjectedDistanceBetween(edge->ptr->vertex1(), segment, list, edge->dia->getScale());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PyObject* VoronoiEdgePy::getDistances(PyObject *args)
|
||||
{
|
||||
VoronoiEdge *e = getVoronoiEdgeFromPy(this, args);
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
</Documentation>
|
||||
<Parameter Name="IncidentEdge" Type="Object"/>
|
||||
</Attribute>
|
||||
<Methode Name="toGeom" Const="true">
|
||||
<Methode Name="toPoint" Const="true">
|
||||
<Documentation>
|
||||
<UserDocu>Returns a Vertex - or None if not possible</UserDocu>
|
||||
<UserDocu>Returns a Vector - or None if not possible</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
</PythonExport>
|
||||
|
||||
@@ -151,7 +151,7 @@ Py::Object VoronoiVertexPy::getIncidentEdge() const {
|
||||
return Py::asObject(new VoronoiEdgePy(new VoronoiEdge(v->dia, v->ptr->incident_edge())));
|
||||
}
|
||||
|
||||
PyObject* VoronoiVertexPy::toGeom(PyObject *args)
|
||||
PyObject* VoronoiVertexPy::toPoint(PyObject *args)
|
||||
{
|
||||
double z = 0.0;
|
||||
if (!PyArg_ParseTuple(args, "|d", &z)) {
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathTests.PathTestUtils as PathTestUtils
|
||||
|
||||
vd = None
|
||||
@@ -87,3 +89,84 @@ class TestPathVoronoi(PathTestUtils.PathTestBase):
|
||||
self.assertNotEqual(vd.Cells[0], vd.Cells[1])
|
||||
self.assertNotEqual(vd.Cells[1], vd.Cells[0])
|
||||
|
||||
def test50(self):
|
||||
'''Check toShape for linear edges'''
|
||||
|
||||
edges = [e for e in vd.Edges if e.Color == 0 and e.isLinear()]
|
||||
self.assertNotEqual(len(edges), 0)
|
||||
e0 = edges[0]
|
||||
|
||||
e = e0.toShape()
|
||||
self.assertTrue(type(e.Curve) == Part.LineSegment or type(e.Curve) == Part.Line)
|
||||
self.assertFalse(PathGeom.pointsCoincide(e.valueAt(e.FirstParameter), e.valueAt(e.LastParameter)))
|
||||
self.assertEqual(e.valueAt(e.FirstParameter).z, 0)
|
||||
self.assertEqual(e.valueAt(e.LastParameter).z, 0)
|
||||
|
||||
def test51(self):
|
||||
'''Check toShape for linear edges with set z'''
|
||||
|
||||
edges = [e for e in vd.Edges if e.Color == 0 and e.isLinear()]
|
||||
self.assertNotEqual(len(edges), 0)
|
||||
e0 = edges[0]
|
||||
|
||||
e = e0.toShape(13.7)
|
||||
self.assertTrue(type(e.Curve) == Part.LineSegment or type(e.Curve) == Part.Line)
|
||||
self.assertFalse(PathGeom.pointsCoincide(e.valueAt(e.FirstParameter), e.valueAt(e.LastParameter)))
|
||||
self.assertEqual(e.valueAt(e.FirstParameter).z, 13.7)
|
||||
self.assertEqual(e.valueAt(e.LastParameter).z, 13.7)
|
||||
|
||||
def test52(self):
|
||||
'''Check toShape for linear edges with varying z'''
|
||||
|
||||
edges = [e for e in vd.Edges if e.Color == 0 and e.isLinear()]
|
||||
self.assertNotEqual(len(edges), 0)
|
||||
e0 = edges[0]
|
||||
|
||||
e = e0.toShape(2.37, 5.14)
|
||||
self.assertTrue(type(e.Curve) == Part.LineSegment or type(e.Curve) == Part.Line)
|
||||
self.assertFalse(PathGeom.pointsCoincide(e.valueAt(e.FirstParameter), e.valueAt(e.LastParameter)))
|
||||
self.assertEqual(e.valueAt(e.FirstParameter).z, 2.37)
|
||||
self.assertEqual(e.valueAt(e.LastParameter).z, 5.14)
|
||||
|
||||
def test60(self):
|
||||
'''Check toShape for curved edges'''
|
||||
|
||||
edges = [e for e in vd.Edges if e.Color == 0 and e.isCurved()]
|
||||
self.assertNotEqual(len(edges), 0)
|
||||
e0 = edges[0]
|
||||
|
||||
e = e0.toShape()
|
||||
print(type(e.Curve))
|
||||
self.assertTrue(type(e.Curve) == Part.Parabola or type(e.Curve) == Part.BSplineCurve)
|
||||
self.assertFalse(PathGeom.pointsCoincide(e.valueAt(e.FirstParameter), e.valueAt(e.LastParameter)))
|
||||
self.assertEqual(e.valueAt(e.FirstParameter).z, 0)
|
||||
self.assertEqual(e.valueAt(e.LastParameter).z, 0)
|
||||
|
||||
def test61(self):
|
||||
'''Check toShape for curved edges with set z'''
|
||||
|
||||
edges = [e for e in vd.Edges if e.Color == 0 and e.isCurved()]
|
||||
self.assertNotEqual(len(edges), 0)
|
||||
e0 = edges[0]
|
||||
|
||||
e = e0.toShape(13.7)
|
||||
print(type(e.Curve))
|
||||
self.assertTrue(type(e.Curve) == Part.Parabola or type(e.Curve) == Part.BSplineCurve)
|
||||
self.assertFalse(PathGeom.pointsCoincide(e.valueAt(e.FirstParameter), e.valueAt(e.LastParameter)))
|
||||
self.assertEqual(e.valueAt(e.FirstParameter).z, 13.7)
|
||||
self.assertEqual(e.valueAt(e.LastParameter).z, 13.7)
|
||||
|
||||
def test62(self):
|
||||
'''Check toShape for curved edges with varying z'''
|
||||
|
||||
edges = [e for e in vd.Edges if e.Color == 0 and e.isCurved()]
|
||||
self.assertNotEqual(len(edges), 0)
|
||||
e0 = edges[0]
|
||||
|
||||
e = e0.toShape(2.37, 5.14)
|
||||
print(type(e.Curve))
|
||||
self.assertTrue(type(e.Curve) == Part.Parabola or type(e.Curve) == Part.BSplineCurve)
|
||||
self.assertFalse(PathGeom.pointsCoincide(e.valueAt(e.FirstParameter), e.valueAt(e.LastParameter)))
|
||||
self.assertEqual(e.valueAt(e.FirstParameter).z, 2.37)
|
||||
self.assertEqual(e.valueAt(e.LastParameter).z, 5.14)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user