bool CollisionManager::checkLineOfSightInParentCell(SceneObject* object, Vector3& endPoint) {
	ManagedReference<SceneObject*> parent = object->getParent();

	if (parent == NULL || !parent->isCellObject())
		return true;

	CellObject* cell = cast<CellObject*>( parent.get());

	SharedObjectTemplate* objectTemplate = parent->getRootParent().get()->getObjectTemplate();
	PortalLayout* portalLayout = objectTemplate->getPortalLayout();
	MeshAppearanceTemplate* appearanceMesh = NULL;

	if (portalLayout == NULL)
		return true;

	try {
		appearanceMesh = portalLayout->getMeshAppearanceTemplate(cell->getCellNumber());
	} catch (Exception& e) {
		return true;
	}

	if (appearanceMesh == NULL) {
		//info("null appearance mesh ");
		return true;
	}

	AABBTree* aabbTree = appearanceMesh->getAABBTree();

	if (aabbTree == NULL)
		return true;

	//switching Y<->Z, adding 0.1 to account floor
	Vector3 startPoint = object->getPosition();
	startPoint.set(startPoint.getX(), startPoint.getY(), startPoint.getZ() + 0.1f);

	endPoint.set(endPoint.getX(), endPoint.getY(), endPoint.getZ() + 0.1f);

	Vector3 dir = endPoint - startPoint;
	dir.normalize();

	float distance = endPoint.distanceTo(startPoint);
	float intersectionDistance;

	Ray ray(startPoint, dir);

	Triangle* triangle = NULL;

	//nothing in the middle
	if (aabbTree->intersects(ray, distance, intersectionDistance, triangle, true))
		return false;

	Ray ray2(endPoint, Vector3(0, -1, 0));

	//check if we are in the cell with dir (0, -1, 0)
	if (!aabbTree->intersects(ray2, 64000.f, intersectionDistance, triangle, true))
		return false;

	return true;
}
示例#2
0
TEST(CubeTest, HasIntersection) {
  Cube cube;

  Ray ray1(Point3(0, 0, 2), Vector3(0, 0, -1));
  EXPECT_TRUE(cube.HasIntersection(ray1, 2));
  EXPECT_FALSE(cube.HasIntersection(ray1, 0.5));

  Ray ray2(Point3(0, 0, 2), Vector3(0, 0, 1));
  EXPECT_FALSE(cube.HasIntersection(ray2, 20));
}
示例#3
0
void Ray2Tests::testBasics()
{
  Ray2 ray1(Point2(2.0f, 0.0f), Vector2(2.0f, 0.0f));
  Ray2 ray2(Point2(1.0f, 1.0f), Vector2(2.0f, 2.0f));
  
  CPTAssert(ray1.origin() == Point2(2.0f, 0.0f));
  CPTAssert(ray1.direction() == Point2(1.0f, 0.0f));  
  CPTAssert(ray2.origin() == Point2(1.0f, 1.0f));
  CPTAssert(ray2.direction() == Point2(1.0f, 1.0f).unit());  
  
}
示例#4
0
TEST(RayTest, equality)
{
	Geom::Point3D origin(0, 0, 0);
	Geom::Vector3D direction(1, 1, 1);

	Geom::Ray ray1(origin, direction);
	Geom::Ray ray2(origin, direction);
	EXPECT_EQ(ray1, ray2);

	Geom::Ray ray3(origin, Geom::Vector3D(2, 3, 2));
	EXPECT_NE(ray1, ray3);
}
示例#5
0
void
LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2)
{
    Geom::Path path;
    path.start( p );
    double diameter = radius_helper_nodes;
    if(helper_size > 0 && Geom::distance(p,p2) > (diameter * 0.35)) {
        Geom::Ray ray2(p, p2);
        p2 =  p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35));
    }
    path.appendNew<Geom::LineSegment>( p2 );
    hp.push_back(path);
}
示例#6
0
		void						ocTriTree::intersect(const z3D::Core::Ray& ray, vector<int32_t>& tris)
		{
			IceMaths::Ray ray2(Point(&ray.origin().x), Point(&ray.direction().x));

			_pimpl.get().ray_collider_dest.Reset();
			bool okay = _pimpl.get().ray_collider.Collide(ray2, _pimpl.get().model);
			if(!okay)
				return;

			size_t count = (size_t)_pimpl.get().ray_collider_dest.GetNbFaces();
			const Opcode::CollisionFace* face_iter = _pimpl.get().ray_collider_dest.GetFaces();
			for(size_t i = 0; i < count; ++i, ++face_iter)
				tris.push_back(face_iter->mFaceID);
		}
示例#7
0
文件: tst_qray3d.cpp 项目: RSATom/Qt
void tst_QRay3D::compare()
{
    Qt3DRender::RayCasting::QRay3D ray1(QVector3D(10, 20, 30), QVector3D(-3, -4, -5));
    Qt3DRender::RayCasting::QRay3D ray2(QVector3D(10, 20, 30), QVector3D(1.5f, 2.0f, 2.5f));
    Qt3DRender::RayCasting::QRay3D ray3(QVector3D(0, 20, 30), QVector3D(-3, -4, -5));
    QVERIFY(ray1 == ray1);
    QVERIFY(!(ray1 != ray1));
    QVERIFY(qFuzzyCompare(ray1, ray1));
    QVERIFY(ray1 != ray2);
    QVERIFY(!(ray1 == ray2));
    QVERIFY(!qFuzzyCompare(ray1, ray2));
    QVERIFY(ray1 != ray3);
    QVERIFY(!(ray1 == ray3));
    QVERIFY(!qFuzzyCompare(ray1, ray3));
}
示例#8
0
int main(int argc, char *argv[]) {
	Vector orig(0,0,0);
	double radius = 1;

	Ray ray1(Vector(-2, 1, 0), Vector(1,0,0));
	Ray ray2(Vector(-2, 1, 0), Vector(-1,0,0));
	Ray ray3(Vector(0, 0.5f, 0), Vector(1,0,0));
	Sphere sphere(orig, radius);

	ASSERT(sphere.intersect(ray1), true, "No intersection");

	ASSERT(sphere.intersect(ray2), false, "Error in intersection");

	ASSERT(sphere.intersect(ray3), false, "Origin is inside the Sphere");

	REPORT();
	return ERROR_COUNT;
}
示例#9
0
TEST(CubeTest, FindIntersection) {
  Cube cube;
  double t;
  Point3 point;
  Vector3 normal;

  Ray ray1(Point3(0, 0, 2), Vector3(0, 0, -1));
  EXPECT_TRUE(cube.FindIntersection(ray1, &t, &point, &normal));
  EXPECT_EQ(1, t);
  EXPECT_EQ(0, point[0]);
  EXPECT_EQ(0, point[1]);
  EXPECT_EQ(1, point[2]);
  EXPECT_EQ(0, normal[0]);
  EXPECT_EQ(0, normal[1]);
  EXPECT_EQ(1, normal[2]);

  Ray ray2(Point3(0, 0, 2), Vector3(0, 0, 1));
  EXPECT_FALSE(cube.FindIntersection(ray2, &t, &point, &normal));
}
示例#10
0
TEST(TestRaycast, TestPlaneIntersection) {
    FTRaycast ray(glm::vec3(0, 2, 0), glm::vec3(1, 3, 1));

    // Test Standard
    glm::vec3 intersection;
    EXPECT_TRUE(ray.intersectsPlane(glm::vec3(2,1,-4), glm::vec3(3,2,1), intersection));
    EXPECT_EQ(intersection, glm::vec3(2, 8, 2));

    // Test parrallel no intersection
    intersection = glm::vec3(23, 5, 78);
    FTRaycast ray2(glm::vec3(1, 4, 0), glm::vec3(1, 2, 1));
    EXPECT_FALSE(ray2.intersectsPlane(glm::vec3(2, 1, -4), glm::vec3(3, 2, 1), intersection));
    EXPECT_EQ(intersection, glm::vec3(23, 5, 78));

    // Test parallel with intersection
    FTRaycast ray3(glm::vec3(2, 8, 2), glm::vec3(1, 2, 1));
    EXPECT_TRUE(ray3.intersectsPlane(glm::vec3(2, 1, -4), glm::vec3(3, 2, 1), intersection));
    EXPECT_EQ(intersection, glm::vec3(3,2,1));

}
示例#11
0
//---------------------------------------------------------------------
Vec3 Scene::ComputeFirstBounceIllumination(const Ray& ray, KdTreeStats& kdTreeStats, ShadingStats& shadingStats) const {
	const int nSamples = 128;
	const Object* obj = m_kdtree.Intersect(ray, kdTreeStats);
	if (!obj) {
		return Vec3(0.f);
	}
	Vec3 p = ray(ray.tmax);
	Vec3 n = (p - obj->center).GetNormalized();
	Vec3 t1, t2;
	BuildCoordSystem(n, t1, t2);
	Vec3 radiance = Vec3(0.f);
	for (int i = 0; i < nSamples; i++) {
		float u1 = genrand_float();
		float u2 = genrand_float();
		Vec3 localDir = CosineSampleHemisphere(u1, u2);
		Vec3 wi = localDir.x * t1 + localDir.y * t2 + localDir.z * n;
		Ray ray2(p, wi);
		radiance += ComputeDirectIllumination(ray2, kdTreeStats, shadingStats);
	}
	radiance *= obj->albedo / nSamples;
  return radiance;
}
示例#12
0
文件: tst_qray3d.cpp 项目: RSATom/Qt
void tst_QRay3D::transform()
{
    QFETCH(QVector3D, point);
    QFETCH(QVector3D, direction);

    QMatrix4x4 m;
    m.translate(-1.0f, 2.5f, 5.0f);
    m.rotate(45.0f, 1.0f, 1.0f, 1.0f);
    m.scale(23.5f);

    Qt3DRender::RayCasting::QRay3D ray1(point, direction);
    Qt3DRender::RayCasting::QRay3D ray2(ray1);
    Qt3DRender::RayCasting::QRay3D ray3;

    ray1.transform(m);
    ray3 = ray2.transformed(m);

    QVERIFY(fuzzyCompare(ray1.origin(), ray3.origin()));
    QVERIFY(fuzzyCompare(ray1.direction(), ray3.direction()));

    QVERIFY(fuzzyCompare(ray1.origin(), m * point));
    QVERIFY(fuzzyCompare(ray1.direction(), m.mapVector(direction)));
}
示例#13
0
void tst_QRay3D::transform()
{
    QFETCH(QVector3D, point);
    QFETCH(QVector3D, direction);

    QMatrix4x4 m;
    m.translate(-1.0f, 2.5f, 5.0f);
    m.rotate(45.0f, 1.0f, 1.0f, 1.0f);
    m.scale(23.5f);

    QRay3D ray1(point, direction);
    QRay3D ray2(ray1);
    QRay3D ray3;

    ray1.transform(m);
    ray3 = ray2.transformed(m);

    QCOMPARE(ray1.origin(), ray3.origin());
    QCOMPARE(ray1.direction(), ray3.direction());

    QCOMPARE(ray1.origin(), m * point);
    QCOMPARE(ray1.direction(), m.mapVector(direction));
}
示例#14
0
Vec3f RayTracer::traceRay(Ray &ray, float tmin, int bounces, float weight,
	float indexOfRefraction, Hit &hit) const
{
	//printf("当前已有光线:\n");
	//RayTree::Print();

	Vec3f canswer;
	if (bounces > max_bounces)
		return Vec3f(0.0f, 0.0f, 0.0f); 
	Camera *camera = sceneParser->getCamera();
	Group *group = sceneParser->getGroup();
	int num_lights = sceneParser->getNumLights();
	Vec3f cambient = sceneParser->getAmbientLight();
	//原来最后是这里出了问题,一旦碰到有转换的物体,那么hit带出来的值是
	//转换后的视线看到的值,而非本来视线看到的值
	//所以解决方案是:距离不变,根据距离重新计算焦点
	if (group->intersect(ray, hit, tmin))//撞到了
	{
		if (is_view_ray)
		{
			RayTree::SetMainSegment(ray, 0, hit.getT());
			is_view_ray = false;
		}
		Vec3f cobject = hit.getMaterial()->getDiffuseColor();
		Vec3f hitPoint = hit.getIntersectionPoint();
		//环境光部分
		canswer = cambient * cobject;
		Vec3f clight;//光的颜色
		Vec3f light_dir;//指向光的方向
		Vec3f normal_dir = hit.getNormal();//交点法线向量
		float distolight;//距离光源的距离
		for (int i = 0; i < num_lights; i++)
		{
			Light *light = sceneParser->getLight(i);
			//light_dir : the direction to the light
			// 该方法用于获得指向光的方向,光的颜色,和到达光的距离
			// 第一个参数传递的是焦点信息
			light->getIllumination(hitPoint, light_dir, clight, distolight);

			Ray ray2(hitPoint, light_dir);
			Vec3f init_normal(0, 0, 0);
			Hit hit2(distolight, NULL, init_normal);
			//阴影检测
			if (shadow)
			{
				if (group->intersect(ray2, hit2, tmin)){
					RayTree::AddShadowSegment(ray2, 0, hit2.getT());
					continue;
				}
				RayTree::AddShadowSegment(ray2, 0, hit2.getT());
			}
			//cpixel  =  cambient * cobject + SUMi [ clamped(Li . N) * clighti * cobject ]
			//返回局部光
			canswer = canswer + hit.getMaterial()->Shade(ray, hit, light_dir, clight);
		}

		//printf("当前已有光线:\n");
		//RayTree::Print();

		
		//反射光
		Material *material = hit.getMaterial();
		Vec3f rc = material->getReflectiveColor();
		if (rc.r() > 0 && rc.g() > 0 && rc.b() > 0)
		{
			Vec3f mirrorDir;
			Vec3f incoming = ray.getDirection();
			mirrorDir = mirrorDirection(normal_dir, incoming);
			// The ray weight is simply multiplied by the magnitude of the reflected color
			Ray ray3(hitPoint, mirrorDir);
			Vec3f init_normal(0, 0, 0);
			Hit hit3(distolight, NULL, init_normal);
			//忘记乘以本身的反射光系数%…………
			canswer += traceRay(ray3, tmin, bounces + 1, weight*rc.Length(), indexOfRefraction, hit3)*rc;
			if (bounces + 1 < max_bounces)
				RayTree::AddReflectedSegment(ray3, 0, hit3.getT());
		}

		//printf("当前已有光线:\n");
		//RayTree::Print();


		//从这里开始还都存在问题!!!!!
		//折射光
		Vec3f transmitted;
		Vec3f tc = material->getTransparentColor();
		float index = material->getIndexOfRefraction();
		if (tc.r() > 0 && tc.g() > 0 && tc.b() > 0)
		{
			Vec3f init_normal(0, 0, 0);
			Hit hit4(distolight, NULL, init_normal);
			//在判断折射光的存在之后,要考虑光线的位置:物体内还是物体外
			//这里根据normal和incoming的点积来判断
			Vec3f incoming = ray.getDirection();
			float judge = normal_dir.Dot3(incoming);
			if (judge < 0)//光线在外
			{
				if (transmittedDirection(normal_dir, incoming, 1, index, transmitted))
				{
					Ray ray4(hitPoint, transmitted);
					canswer += traceRay(ray4, tmin, bounces+1, weight*rc.Length(), index, hit4)*tc;
					RayTree::AddTransmittedSegment(ray4, 0, hit4.getT());
				}
			}
			else//光线在内
			{
				normal_dir.Negate();
				if (transmittedDirection(normal_dir, incoming, index, 1, transmitted))
				{
					Ray ray4(hitPoint, transmitted);
					canswer += traceRay(ray4, tmin, bounces+1, weight*rc.Length(), 1, hit4)*tc;
					RayTree::AddTransmittedSegment(ray4, 0, hit4.getT());
				}
			}
		}

		//printf("当前已有光线:\n");
		//RayTree::Print();

	}
	else
		canswer = sceneParser->getBackgroundColor();

	canswer.Clamp();
	return canswer;
}
示例#15
0
bool smooth_curve(const BVH *bvh, const VectorXu &E2E, std::vector<CurvePoint> &curve, bool watertight) {
    const MatrixXu &F = *bvh->F();
    const MatrixXf &V = *bvh->V(), &N = *bvh->N();
    cout << endl;

    std::vector<CurvePoint> curve_new;
    std::vector<Float> weight;
    std::vector<uint32_t> path;

    cout << "Input: " << curve.size() << " vertices" << endl;

    for (int it=0;; ++it) {
        if (curve.size() < 2)
            return false;

        for (uint32_t it2=0; it2<curve.size(); ++it2) {
            curve_new.clear();
            curve_new.push_back(curve[0]);
            for (uint32_t i=1; i<curve.size()-1; ++i) {
                Vector3f p_new = 0.5f * (curve[i-1].p + curve[i+1].p);
                Vector3f n_new = (curve[i-1].n + curve[i+1].n).normalized();
                Float maxlength = (curve[i-1].p - curve[i+1].p).norm()*2;

                Ray ray1(p_new,  n_new, 0, maxlength);
                Ray ray2(p_new, -n_new, 0, maxlength);
                uint32_t idx1 = 0, idx2 = 0;
                Float t1 = 0, t2 = 0;
                Vector2f uv1, uv2;
                bool hit1 = bvh->rayIntersect(ray1, idx1, t1, &uv1);
                bool hit2 = bvh->rayIntersect(ray2, idx2, t2, &uv2);

                if (!hit1 && !hit2)
                    continue;

                CurvePoint pt;
                if (t1 < t2) {
                    pt.p = ray1(t1);
                    pt.f = idx1;
                    pt.n = ((1 - uv1.sum()) * N.col(F(0, idx1)) + uv1.x() * N.col(F(1, idx1)) + uv1.y() * N.col(F(2, idx1))).normalized();
                } else {
                    pt.p = ray2(t2);
                    pt.f = idx2;
                    pt.n = ((1 - uv2.sum()) * N.col(F(0, idx2)) + uv2.x() * N.col(F(1, idx2)) + uv2.y() * N.col(F(2, idx2))).normalized();
                }
                curve_new.push_back(pt);
            }
            curve_new.push_back(curve[curve.size()-1]);
            curve.swap(curve_new);
        }

        if (!watertight && it == 1)
            break;

        curve_new.clear();
        curve_new.push_back(curve[0]);
        for (uint32_t i=1; i<curve.size(); ++i) {
            if (!astar(F, E2E, V, curve[i-1].f, curve[i].f, path))
                return false;

            auto closest = [](const Vector3f &p0, const Vector3f &p1, const Vector3f &target) -> Vector3f {
                Vector3f d = (p1-p0).normalized();
                return p0 + d * std::min(std::max((target-p0).dot(d), 0.0f), (p0-p1).norm());
            };

            if (path.size() > 2) {
                uint32_t base = curve_new.size() - 1;
                for (uint32_t j=1; j<path.size()-1; ++j) {
                    uint32_t f = path[j];
                    Vector3f p0 = V.col(F(0, f)), p1 = V.col(F(1, f)), p2 = V.col(F(2, f));
                    CurvePoint pt2;
                    pt2.f = f;
                    pt2.n = (p1-p0).cross(p2-p0).normalized();
                    pt2.p = (p0+p1+p2) * (1.0f / 3.0f);
                    curve_new.push_back(pt2);
                }
                curve_new.push_back(curve[i]);

                for (uint32_t q=1; q<path.size()-1; ++q) {
                    for (uint32_t j=1; j<path.size()-1; ++j) {
                        Float bestDist1 = std::numeric_limits<Float>::infinity();
                        Float bestDist2 = std::numeric_limits<Float>::infinity();
                        Vector3f bestPt1 = Vector3f::Zero(), bestPt2 = Vector3f::Zero();
                        uint32_t f = path[j];
                        for (uint32_t k=0; k<3; ++k) {
                            Vector3f closest1 = closest(V.col(F(k, f)), V.col(F((k + 1) % 3, f)), curve_new[base+j-1].p);
                            Vector3f closest2 = closest(V.col(F(k, f)), V.col(F((k + 1) % 3, f)), curve_new[base+j+1].p);
                            Float dist1 = (closest1 - curve_new[base+j-1].p).norm();
                            Float dist2 = (closest2 - curve_new[base+j+1].p).norm();
                            if (dist1 < bestDist1) { bestDist1 = dist1; bestPt1 = closest1; }
                            if (dist2 < bestDist2) { bestDist2 = dist2; bestPt2 = closest2; }
                        }
                        curve_new[base+j].p = (bestPt1 + bestPt2) * 0.5f;
                    }
                }
            } else {
                curve_new.push_back(curve[i]);
            }
        }
        curve.swap(curve_new);

        curve_new.clear();
        curve_new.push_back(curve[0]);
        weight.clear();
        weight.push_back(1.0f);
        for (uint32_t i=0; i<curve.size(); ++i) {
            auto &cur = curve_new[curve_new.size()-1];
            auto &cur_weight = weight[weight.size()-1];
            if (cur.f == curve[i].f) {
                cur.p += curve[i].p;
                cur.n += curve[i].n;
                cur_weight += 1;
            } else {
                curve_new.push_back(curve[i]);
                weight.push_back(1.f);
            }
        }
        for (uint32_t i=0; i<curve_new.size(); ++i) {
            curve_new[i].p /= weight[i];
            curve_new[i].n.normalize();
        }
        curve_new[0] = curve[0];
        curve_new[curve_new.size()-1] = curve[curve.size()-1];
        if (curve_new.size() < 2 || curve_new[0].f == curve_new[curve_new.size()-1].f)
            return false;
        curve_new.swap(curve);

        if (it > 2)
            break;
    }
    cout << "Smoothed curve: " << curve.size() << " vertices" << endl;

    return true;
}
示例#16
0
void
LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result)
{
    if(steps < 1) {
        return;
    }
    Geom::PathVector tmp_path;
    Geom::CubicBezier const *cubic = NULL;
    for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) {
        if (path_it->empty()) {
            continue;
        }

        Geom::Path::iterator curve_it1 = path_it->begin(); // incoming curve
        Geom::Path::iterator curve_it2 = ++(path_it->begin());// outgoing curve
        Geom::Path::iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop
        SPCurve *nCurve = new SPCurve();
        if (path_it->closed()) {
            // if the path is closed, maybe we have to stop a bit earlier because the
            // closing line segment has zerolength.
            const Geom::Curve &closingline =
                path_it->back_closed(); // the closing line segment is always of type
            // Geom::LineSegment.
            if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
                // closingline.isDegenerate() did not work, because it only checks for
                // *exact* zero length, which goes wrong for relative coordinates and
                // rounding errors...
                // the closing line segment has zero-length. So stop before that one!
                curve_endit = path_it->end_open();
            }
        }
        if(helper_size > 0) {
            drawNode(curve_it1->initialPoint());
        }
        nCurve->moveto(curve_it1->initialPoint());
        Geom::Point start = Geom::Point(0,0);
        while (curve_it1 != curve_endit) {
            cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
            Geom::Point point_at1 = curve_it1->initialPoint();
            Geom::Point point_at2 = curve_it1->finalPoint();
            Geom::Point point_at3 = curve_it1->finalPoint();
            Geom::Point point_at4 = curve_it1->finalPoint();

            if(start == Geom::Point(0,0)) {
                start = point_at1;
            }

            if (cubic) {
                point_at1 = (*cubic)[1];
                point_at2 = (*cubic)[2];
            }

            if(path_it->closed() && curve_it2 == curve_endit) {
                point_at4 = start;
            }
            if(curve_it2 != curve_endit) {
                cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it2);
                if (cubic) {
                    point_at4 = (*cubic)[1];
                }
            }
            Geom::Ray ray1(point_at2, point_at3);
            Geom::Ray ray2(point_at3, point_at4);
            double angle1 = Geom::deg_from_rad(ray1.angle());
            double angle2 = Geom::deg_from_rad(ray2.angle());
            if((smooth_angles  >= std::abs(angle2 - angle1)) && !are_near(point_at4,point_at3) && !are_near(point_at2,point_at3)) {
                double dist = Geom::distance(point_at2,point_at3);
                Geom::Angle angleFixed = ray2.angle();
                angleFixed -= Geom::Angle::from_degrees(180.0);
                point_at2 =  Geom::Point::polar(angleFixed, dist) + point_at3;
            }
            nCurve->curveto(point_at1, point_at2, curve_it1->finalPoint());
            cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment());
            if (cubic) {
                point_at1 = (*cubic)[1];
                point_at2 = (*cubic)[2];
                if(helper_size > 0) {
                    if(!are_near((*cubic)[0],(*cubic)[1])) {
                        drawHandle((*cubic)[1]);
                        drawHandleLine((*cubic)[0],(*cubic)[1]);
                    }
                    if(!are_near((*cubic)[3],(*cubic)[2])) {
                        drawHandle((*cubic)[2]);
                        drawHandleLine((*cubic)[3],(*cubic)[2]);
                    }
                }
            }
            if(helper_size > 0) {
                drawNode(curve_it1->finalPoint());
            }
            ++curve_it1;
            ++curve_it2;
        }
        if (path_it->closed()) {
            nCurve->closepath_current();
        }
        tmp_path.push_back(nCurve->get_pathvector()[0]);
        nCurve->reset();
        delete nCurve;
    }
    result = tmp_path;
}