Example #1
0
/// Used inside SkCurveMeasure::getTime's Newton's iteration
static inline SkPoint evaluate(const SkPoint pts[4], SkSegType segType,
                               SkScalar t) {
    SkPoint pos;
    switch (segType) {
        case kQuad_SegType:
            pos = SkEvalQuadAt(pts, t);
            break;
        case kLine_SegType:
            pos = SkPoint::Make(SkScalarInterp(pts[0].x(), pts[1].x(), t),
                                SkScalarInterp(pts[0].y(), pts[1].y(), t));
            break;
        case kCubic_SegType:
            SkEvalCubicAt(pts, t, &pos, nullptr, nullptr);
            break;
        case kConic_SegType: {
            SkConic conic(pts, pts[3].x());
            conic.evalAt(t, &pos);
        }
            break;
        default:
            UNIMPLEMENTED;
    }

    return pos;
}
static void test_conic_tangents(skiatest::Reporter* reporter) {
    SkPoint pts[] = {
        { 10, 20}, {10, 20}, {20, 30},
        { 10, 20}, {15, 25}, {20, 30},
        { 10, 20}, {20, 30}, {20, 30}
    };
    int count = (int) SK_ARRAY_COUNT(pts) / 3;
    for (int index = 0; index < count; ++index) {
        SkConic conic(&pts[index * 3], 0.707f);
        SkVector start = conic.evalTangentAt(0);
        SkVector mid = conic.evalTangentAt(.5f);
        SkVector end = conic.evalTangentAt(1);
        REPORTER_ASSERT(reporter, start.fX && start.fY);
        REPORTER_ASSERT(reporter, mid.fX && mid.fY);
        REPORTER_ASSERT(reporter, end.fX && end.fY);
        REPORTER_ASSERT(reporter, SkScalarNearlyZero(start.cross(mid)));
        REPORTER_ASSERT(reporter, SkScalarNearlyZero(mid.cross(end)));
    }
}
static void test_cubic_tangents(skiatest::Reporter* reporter) {
    SkPoint pts[] = {
        { 10, 20}, {10, 20}, {20, 30}, {30, 40},
        { 10, 20}, {15, 25}, {20, 30}, {30, 40},
        { 10, 20}, {20, 30}, {30, 40}, {30, 40},
    };
    int count = (int) SK_ARRAY_COUNT(pts) / 4;
    for (int index = 0; index < count; ++index) {
        SkConic conic(&pts[index * 3], 0.707f);
        SkVector start, mid, end;
        SkEvalCubicAt(&pts[index * 4], 0, nullptr, &start, nullptr);
        SkEvalCubicAt(&pts[index * 4], .5f, nullptr, &mid, nullptr);
        SkEvalCubicAt(&pts[index * 4], 1, nullptr, &end, nullptr);
        REPORTER_ASSERT(reporter, start.fX && start.fY);
        REPORTER_ASSERT(reporter, mid.fX && mid.fY);
        REPORTER_ASSERT(reporter, end.fX && end.fY);
        REPORTER_ASSERT(reporter, SkScalarNearlyZero(start.cross(mid)));
        REPORTER_ASSERT(reporter, SkScalarNearlyZero(mid.cross(end)));
    }
}
static void test_conic(skiatest::Reporter* reporter) {
    SkRandom rand;
    for (int i = 0; i < 1000; ++i) {
        SkPoint pts[3];
        for (int j = 0; j < 3; ++j) {
            pts[j].set(rand.nextSScalar1() * 100, rand.nextSScalar1() * 100);
        }
        for (int k = 0; k < 10; ++k) {
            SkScalar w = rand.nextUScalar1() * 2;
            SkConic conic(pts, w);

            const SkScalar dt = SK_Scalar1 / 128;
            SkScalar t = dt;
            for (int j = 1; j < 128; ++j) {
                test_conic_eval_pos(reporter, conic, t);
                test_conic_eval_tan(reporter, conic, t);
                t += dt;
            }
        }
    }
}
Example #5
0
/// Used inside SkCurveMeasure::getTime's Newton's iteration
static inline SkVector evaluateDerivative(const SkPoint pts[4],
                                          SkSegType segType, SkScalar t) {
    SkVector tan;
    switch (segType) {
        case kQuad_SegType:
            tan = SkEvalQuadTangentAt(pts, t);
            break;
        case kLine_SegType:
            tan = pts[1] - pts[0];
            break;
        case kCubic_SegType:
            SkEvalCubicAt(pts, t, nullptr, &tan, nullptr);
            break;
        case kConic_SegType: {
            SkConic conic(pts, pts[3].x());
            conic.evalAt(t, nullptr, &tan);
        }
            break;
        default:
            UNIMPLEMENTED;
    }

    return tan;
}
Example #6
0
bool SkOpEdgeBuilder::walk() {
    uint8_t* verbPtr = fPathVerbs.begin();
    uint8_t* endOfFirstHalf = &verbPtr[fSecondHalf];
    SkPoint* pointsPtr = fPathPts.begin() - 1;
    SkScalar* weightPtr = fWeights.begin();
    SkPath::Verb verb;
    while ((verb = (SkPath::Verb) *verbPtr) != SkPath::kDone_Verb) {
        if (verbPtr == endOfFirstHalf) {
            fOperand = true;
        }
        verbPtr++;
        switch (verb) {
            case SkPath::kMove_Verb:
                if (fCurrentContour && fCurrentContour->count()) {
                    if (fAllowOpenContours) {
                        complete();
                    } else if (!close()) {
                        return false;
                    }
                }
                if (!fCurrentContour) {
                    fCurrentContour = fContoursHead->appendContour();
                }
                fCurrentContour->init(fGlobalState, fOperand,
                    fXorMask[fOperand] == kEvenOdd_PathOpsMask);
                pointsPtr += 1;
                continue;
            case SkPath::kLine_Verb:
                fCurrentContour->addLine(pointsPtr);
                break;
            case SkPath::kQuad_Verb:
                {
                    SkVector v1 = pointsPtr[1] - pointsPtr[0];
                    SkVector v2 = pointsPtr[2] - pointsPtr[1];
                    if (v1.dot(v2) < 0) {
                        SkPoint pair[5];
                        if (SkChopQuadAtMaxCurvature(pointsPtr, pair) == 1) {
                            goto addOneQuad;
                        }
                        if (!SkScalarsAreFinite(&pair[0].fX, SK_ARRAY_COUNT(pair) * 2)) {
                            return false;
                        }
                        SkPoint cStorage[2][2];
                        SkPath::Verb v1 = SkReduceOrder::Quad(&pair[0], cStorage[0]);
                        SkPath::Verb v2 = SkReduceOrder::Quad(&pair[2], cStorage[1]);
                        SkPoint* curve1 = v1 != SkPath::kLine_Verb ? &pair[0] : cStorage[0];
                        SkPoint* curve2 = v2 != SkPath::kLine_Verb ? &pair[2] : cStorage[1];
                        if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) {
                            fCurrentContour->addCurve(v1, curve1);
                            fCurrentContour->addCurve(v2, curve2);
                            break;
                        }
                    }
                }
            addOneQuad:
                fCurrentContour->addQuad(pointsPtr);
                break;
            case SkPath::kConic_Verb: {
                SkVector v1 = pointsPtr[1] - pointsPtr[0];
                SkVector v2 = pointsPtr[2] - pointsPtr[1];
                SkScalar weight = *weightPtr++;
                if (v1.dot(v2) < 0) {
                    // FIXME: max curvature for conics hasn't been implemented; use placeholder
                    SkScalar maxCurvature = SkFindQuadMaxCurvature(pointsPtr);
                    if (maxCurvature > 0) {
                        SkConic conic(pointsPtr, weight);
                        SkConic pair[2];
                        if (!conic.chopAt(maxCurvature, pair)) {
                            // if result can't be computed, use original
                            fCurrentContour->addConic(pointsPtr, weight);
                            break;
                        }
                        SkPoint cStorage[2][3];
                        SkPath::Verb v1 = SkReduceOrder::Conic(pair[0], cStorage[0]);
                        SkPath::Verb v2 = SkReduceOrder::Conic(pair[1], cStorage[1]);
                        SkPoint* curve1 = v1 != SkPath::kLine_Verb ? pair[0].fPts : cStorage[0];
                        SkPoint* curve2 = v2 != SkPath::kLine_Verb ? pair[1].fPts : cStorage[1];
                        if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) {
                            fCurrentContour->addCurve(v1, curve1, pair[0].fW);
                            fCurrentContour->addCurve(v2, curve2, pair[1].fW);
                            break;
                        }
                    }
                }
                fCurrentContour->addConic(pointsPtr, weight);
                } break;
            case SkPath::kCubic_Verb:
                {
                    // Split complex cubics (such as self-intersecting curves or
                    // ones with difficult curvature) in two before proceeding.
                    // This can be required for intersection to succeed.
                    SkScalar splitT;
                    if (SkDCubic::ComplexBreak(pointsPtr, &splitT)) {
                        SkPoint pair[7];
                        SkChopCubicAt(pointsPtr, pair, splitT);
                        if (!SkScalarsAreFinite(&pair[0].fX, SK_ARRAY_COUNT(pair) * 2)) {
                            return false;
                        }
                        SkPoint cStorage[2][4];
                        SkPath::Verb v1 = SkReduceOrder::Cubic(&pair[0], cStorage[0]);
                        SkPath::Verb v2 = SkReduceOrder::Cubic(&pair[3], cStorage[1]);
                        SkPoint* curve1 = v1 == SkPath::kCubic_Verb ? &pair[0] : cStorage[0];
                        SkPoint* curve2 = v2 == SkPath::kCubic_Verb ? &pair[3] : cStorage[1];
                        if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) {
                            fCurrentContour->addCurve(v1, curve1);
                            fCurrentContour->addCurve(v2, curve2);
                            break;
                        } 
                    }
                }
                fCurrentContour->addCubic(pointsPtr);
                break;
            case SkPath::kClose_Verb:
                SkASSERT(fCurrentContour);
                if (!close()) {
                    return false;
                }
                continue;
            default:
                SkDEBUGFAIL("bad verb");
                return false;
        }
        SkASSERT(fCurrentContour);
        fCurrentContour->debugValidate();
        pointsPtr += SkPathOpsVerbToPoints(verb);
    }
   if (fCurrentContour && fCurrentContour->count() &&!fAllowOpenContours && !close()) {
       return false;
   }
   return true;
}
Example #7
0
Json::Value SkJSONCanvas::makePath(const SkPath& path) {
    Json::Value result(Json::objectValue);
    switch (path.getFillType()) {
        case SkPath::kWinding_FillType:
            result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_WINDING;
            break;
        case SkPath::kEvenOdd_FillType:
            result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_EVENODD;
            break;
        case SkPath::kInverseWinding_FillType:
            result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEWINDING;
            break;
        case SkPath::kInverseEvenOdd_FillType:
            result[SKJSONCANVAS_ATTRIBUTE_FILLTYPE] = SKJSONCANVAS_FILLTYPE_INVERSEEVENODD;
            break;
    }    
    Json::Value verbs(Json::arrayValue);
    SkPath::Iter iter(path, false);
    SkPoint pts[4];
    SkPath::Verb verb;
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kLine_Verb: {
                Json::Value line(Json::objectValue);
                line[SKJSONCANVAS_VERB_LINE] = this->makePoint(pts[1]);
                verbs.append(line);
                break;
            }
            case SkPath::kQuad_Verb: {
                Json::Value quad(Json::objectValue);
                Json::Value coords(Json::arrayValue);
                coords.append(this->makePoint(pts[1]));
                coords.append(this->makePoint(pts[2]));
                quad[SKJSONCANVAS_VERB_QUAD] = coords;
                verbs.append(quad);
                break;
            }
            case SkPath::kCubic_Verb: {
                Json::Value cubic(Json::objectValue);
                Json::Value coords(Json::arrayValue);
                coords.append(this->makePoint(pts[1]));
                coords.append(this->makePoint(pts[2]));
                coords.append(this->makePoint(pts[3]));
                cubic[SKJSONCANVAS_VERB_CUBIC] = coords;
                verbs.append(cubic);
                break;
            }
            case SkPath::kConic_Verb: {
                Json::Value conic(Json::objectValue);
                Json::Value coords(Json::arrayValue);
                coords.append(this->makePoint(pts[1]));
                coords.append(this->makePoint(pts[2]));
                coords.append(Json::Value(iter.conicWeight()));
                conic[SKJSONCANVAS_VERB_CONIC] = coords;
                verbs.append(conic);
                break;
            }
            case SkPath::kMove_Verb: {
                Json::Value move(Json::objectValue);
                move[SKJSONCANVAS_VERB_MOVE] = this->makePoint(pts[0]);
                verbs.append(move);
                break;
            }
            case SkPath::kClose_Verb:
                verbs.append(Json::Value(SKJSONCANVAS_VERB_CLOSE));
                break;
            case SkPath::kDone_Verb:
                break;
        }
    }
    result[SKJSONCANVAS_ATTRIBUTE_VERBS] = verbs;
    return result;
}
int main(int argc, char* argv[])
{
#if 1
	QApplication a(argc, argv);
	MainWindow w;
	w.show();


	// look for image file
	//std::string img_file("data/floor.jpg");
	//QFile file;
	//for (int i = 0; i < 5; ++i)
	//	if (!file.exists(img_file.c_str()))
	//		img_file.insert(0, "../");
	//w.getGLWidget()->setImage(img_file.c_str());

	

	GLLines* gllines = &w.getGLWidget()->glLines();

	
	//gllines->setVertexLine(0, 0, QVector3D(52.3467f, 125.102f, 1.0f));
	//gllines->setVertexLine(0, 1, QVector3D(340.253f, 130.147f, 1.0f));
	//gllines->setVertexLine(1, 0, QVector3D(193.28f, 126.111f, 1.0f));
	//gllines->setVertexLine(1, 1, QVector3D(225.493f, 360.173f, 1.0f));
	//gllines->setVertexLine(2, 0, QVector3D(42.28f, 263.32f, 1.0f));
	//gllines->setVertexLine(2, 1, QVector3D(296.967f, 397.502f, 1.0f));
	//gllines->setVertexLine(3, 0, QVector3D(212.407f, 269.373f, 1.0f));
	//gllines->setVertexLine(3, 1, QVector3D(34.2267f, 391.449f, 1.0f));
	//gllines->setVertexLine(4, 0, QVector3D(294.953f, 318.809f, 1.0f));
	//gllines->setVertexLine(4, 1, QVector3D(456.02f, 322.844f, 1.0f));
	//gllines->setVertexLine(5, 0, QVector3D(492.26f, 208.84f, 1.0f));
	//gllines->setVertexLine(5, 1, QVector3D(429.847f, 400.529f, 1.0f));
	//gllines->setVertexLine(6, 0, QVector3D(299.987f, 31.2756f, 1.0f));
	//gllines->setVertexLine(6, 1, QVector3D(555.68f, 273.409f, 1.0f));
	//gllines->setVertexLine(7, 0, QVector3D(545.613f, 39.3467f, 1.0f));
	//gllines->setVertexLine(7, 1, QVector3D(236.567f, 250.204f, 1.0f));
	//gllines->setVertexLine(8, 0, QVector3D(95.6333f, 264.329f, 1.0f));
	//gllines->setVertexLine(8, 1, QVector3D(501.32f, 273.409f, 1.0f));
	//gllines->setVertexLine(9, 0, QVector3D(302.00f, 29.2578f, 1.0f));
	//gllines->setVertexLine(9, 1, QVector3D(297.973f, 398.511f, 1.0f));
	gllines->computeCanonicalVertices(w.getGLWidget()->width(), w.getGLWidget()->height());
	gllines->onEnable(true);

	return a.exec();

#else
	std::vector<Eigen::Vector3f> vertices;
	vertices.push_back(Eigen::Vector3f(52.3467f, 125.102f, 1.0f));
	vertices.push_back(Eigen::Vector3f(340.253f, 130.147f, 1.0f));
	vertices.push_back(Eigen::Vector3f(193.28f, 126.111f, 1.0f));
	vertices.push_back(Eigen::Vector3f(225.493f, 360.173f, 1.0f));
	vertices.push_back(Eigen::Vector3f(42.28f, 263.32f, 1.0f));
	vertices.push_back(Eigen::Vector3f(296.967f, 397.502f, 1.0f));
	vertices.push_back(Eigen::Vector3f(212.407f, 269.373f, 1.0f));
	vertices.push_back(Eigen::Vector3f(34.2267f, 391.449f, 1.0f));
	vertices.push_back(Eigen::Vector3f(294.953f, 318.809f, 1.0f));
	vertices.push_back(Eigen::Vector3f(456.02f, 322.844f, 1.0f));
	vertices.push_back(Eigen::Vector3f(492.26f, 208.84f, 1.0f));
	vertices.push_back(Eigen::Vector3f(429.847f, 400.529f, 1.0f));
	vertices.push_back(Eigen::Vector3f(299.987f, 31.2756f, 1.0f));
	vertices.push_back(Eigen::Vector3f(555.68f, 273.409f, 1.0f));
	vertices.push_back(Eigen::Vector3f(545.613f, 39.3467f, 1.0f));
	vertices.push_back(Eigen::Vector3f(236.567f, 250.204f, 1.0f));
	vertices.push_back(Eigen::Vector3f(95.6333f, 264.329f, 1.0f));
	vertices.push_back(Eigen::Vector3f(501.32f, 273.409f, 1.0f));
	vertices.push_back(Eigen::Vector3f(302.00f, 29.2578f, 1.0f));
	vertices.push_back(Eigen::Vector3f(297.973f, 398.511f, 1.0f));


	std::cout << vertices.size() << std::endl;

	std::vector<Eigen::Vector3f> lines;
	for (int i = 0; i < vertices.size() - 1; i += 2)
		lines.push_back(lineNormalized(vertices[i], vertices[i + 1]));
	
	for (int i = 0; i < lines.size(); ++i)
		std::cout << "l" << i << " : " << lines[i].x() << ", " << lines[i].y() << ", " << lines[i].z() << std::endl;

	std::cout << std::endl << std::endl;

	//lines[0] = Eigen::Vector3f(-0.000141084, 0.00805224, -0.999968);
	//lines[1] = Eigen::Vector3f(-0.00568419, 0.000782299, 0.999984);
	//lines[2] = Eigen::Vector3f(-0.00218568, 0.00414856, -0.999989);
	//lines[3] = Eigen::Vector3f(-0.0016513, -0.00241022, 0.999996);
	//lines[4] = Eigen::Vector3f(-8.04546e-05, 0.00321109, -0.999995);
	//lines[5] = Eigen::Vector3f(-0.00178489, -0.000581155, 0.999998);
	//lines[6] = Eigen::Vector3f(-0.00374583, 0.0039556, 0.999985);
	//lines[7] = Eigen::Vector3f(-0.00165759, -0.00242947, 0.999996);
	//lines[8] = Eigen::Vector3f(-8.53647e-05, 0.00381402, -0.999993);
	//lines[9] = Eigen::Vector3f(-0.00330775, -3.60706e-05, 0.999995);


	Eigen::MatrixXf A(5, 5);
	Eigen::Vector3f l, m;
	Eigen::VectorXf b(5);

	for (int i = 0; i < 5; ++i)
	{
		l = lines[i * 2 + 0];
		m = lines[i * 2 + 1];

		A(i, 0) = l[0] * m[0];
		A(i, 1) = (l[0] * m[1] + l[1] * m[0]) / 2.0f;
		A(i, 2) = l[1] * m[1];
		A(i, 3) = (l[0] * m[2] + l[2] * m[0]) / 2.0f;
		A(i, 4) = (l[1] * m[2] + l[2] * m[1]) / 2.0f;
		A(i, 5) = l[2] * m[2];

		b[i] = -l[2] * m[2];
	}

	std::cout << "A: \n" << A << std::endl << std::endl;
	std::cout << "b: \n" << b << std::endl << std::endl;

	Eigen::MatrixXf x = A.colPivHouseholderQr().solve(b);
	std::cout << std::fixed << "x: \n" << x << std::endl << std::endl;


	Eigen::MatrixXf conic(3, 3);
	conic(0, 0) = x(0);
	conic(0, 1) = x(1) / 2.0f;
	conic(0, 2) = x(3) / 2.0f;
	conic(1, 0) = x(1) / 2.0f;
	conic(1, 1) = x(2);
	conic(1, 2) = x(4) / 2.0f;
	conic(2, 0) = x(3) / 2.0f;
	conic(2, 1) = x(4) / 2.0f;
	conic(2, 2) = 1.0f;
	std::cout << "Conic : " << std::endl << conic << std::endl << std::endl;

	Eigen::JacobiSVD<Eigen::MatrixXf> svd(conic, Eigen::ComputeFullU);
	Eigen::MatrixXf H = svd.matrixU();
	
	std::cout << "H matrix: " << std::endl 
		<< H << std::endl << std::endl 
		<< "Singular values: " << svd.singularValues()
		<< std::endl << std::endl;

	std::cout << "Rectification transformation: " << std::endl << H.inverse() << std::endl << std::endl;





	QImage input("floor-persp.jpg");
	Eigen::Vector3f img(input.width(), input.height(), 1.0f);

	float xmin = 0;
	float xmax = 0;
	float ymin = 0;
	float ymax = 0;
	computImageSize(H.inverse(), 0, 0, input.width(), input.height(), xmin, xmax, ymin, ymax);


	float aspect = (xmax - xmin) / (ymax - ymin);
	QImage output(input.width(), input.width() / aspect, input.format());
	output.fill(qRgb(0, 0, 0));

	std::cout << "Output size: " << output.width() << ", " << output.height() << std::endl;

	float dx = (xmax - xmin) / float(output.width());
	float dy = (ymax - ymin) / float(output.height());

	std::cout << std::fixed << "dx, dy: " << dx << ", " << dy << std::endl;

	for (int x = 0; x < output.width(); ++x)
	{
		for (int y = 0; y < output.height(); ++y)
		{
			Eigen::Vector3f px(x, y, 1);

			float tx = 0.0f;
			float ty = 0.0f;
			Eigen::Vector2f t = multiplyPointMatrix(H, xmin + x * dx, ymin + y * dy);

			if (t.x() > -1 && t.y() > -1
				&& t.x() < input.width()
				&& t.y() < input.height())
			{
				//if (interpolate)
				//{
				//	QRgb rgb = bilinearInterpol(input, t.x(), t.y(), dx / 2.0, dy / 2.0);
				//	output.setPixel(x, y, rgb);
				//}
				//else
				{
					output.setPixel(x, y, input.pixel(t.x(), t.y()));
				}
			}
		}
	}


	output.save("output_5_floor.jpg");
	
	return EXIT_SUCCESS;
#endif
}
Example #9
0
  Function qpsol_nlp(const std::string& name, const std::string& solver,
                     const std::map<std::string, M>& qp, const Dict& opts) {
    // We have: minimize    f(x) = 1/2 * x' H x + c'x
    //          subject to  lbx <= x <= ubx
    //                      lbg <= g(x) = A x + b <= ubg
    M x, p, f, g;
    for (auto&& i : qp) {
      if (i.first=="x") {
        x = i.second;
      } else if (i.first=="p") {
        p = i.second;
      } else if (i.first=="f") {
        f = i.second;
      } else if (i.first=="g") {
        g = i.second;
      } else {
        casadi_error("No such field: " + i.first);
      }
    }
    if (g.is_empty(true)) g = M(0, 1); // workaround

    // Gradient of the objective: gf == Hx + g
    M gf = M::gradient(f, x);

    // Identify the linear term in the objective
    M c = substitute(gf, x, M::zeros(x.sparsity()));

    // Identify the quadratic term in the objective
    M H = M::jacobian(gf, x, true);

    // Identify the constant term in the constraints
    M b = substitute(g, x, M::zeros(x.sparsity()));

    // Identify the linear term in the constraints
    M A = M::jacobian(g, x);

    // Create a function for calculating the required matrices vectors
    Function prob(name + "_qp", {x, p}, {H, c, A, b});

    // Create the QP solver
    Function conic_f = conic(name + "_qpsol", solver,
                             {{"h", H.sparsity()}, {"a", A.sparsity()}}, opts);

    // Create an MXFunction with the right signature
    vector<MX> ret_in(NLPSOL_NUM_IN);
    ret_in[NLPSOL_X0] = MX::sym("x0", x.sparsity());
    ret_in[NLPSOL_P] = MX::sym("p", p.sparsity());
    ret_in[NLPSOL_LBX] = MX::sym("lbx", x.sparsity());
    ret_in[NLPSOL_UBX] = MX::sym("ubx", x.sparsity());
    ret_in[NLPSOL_LBG] = MX::sym("lbg", g.sparsity());
    ret_in[NLPSOL_UBG] = MX::sym("ubg", g.sparsity());
    ret_in[NLPSOL_LAM_X0] = MX::sym("lam_x0", x.sparsity());
    ret_in[NLPSOL_LAM_G0] = MX::sym("lam_g0", g.sparsity());
    vector<MX> ret_out(NLPSOL_NUM_OUT);

    // Get expressions for the QP matrices and vectors
    vector<MX> v(NL_NUM_IN);
    v[NL_X] = ret_in[NLPSOL_X0];
    v[NL_P] = ret_in[NLPSOL_P];
    v = prob(v);

    // Call the QP solver
    vector<MX> w(CONIC_NUM_IN);
    w[CONIC_H] = v.at(0);
    w[CONIC_G] = v.at(1);
    w[CONIC_A] = v.at(2);
    w[CONIC_LBX] = ret_in[NLPSOL_LBX];
    w[CONIC_UBX] = ret_in[NLPSOL_UBX];
    w[CONIC_LBA] = ret_in[NLPSOL_LBG] - v.at(3);
    w[CONIC_UBA] = ret_in[NLPSOL_UBG] - v.at(3);
    w[CONIC_X0] = ret_in[NLPSOL_X0];
    w[CONIC_LAM_X0] = ret_in[NLPSOL_LAM_X0];
    w[CONIC_LAM_A0] = ret_in[NLPSOL_LAM_G0];
    w = conic_f(w);

    // Get expressions for the solution
    ret_out[NLPSOL_X] = w[CONIC_X];
    ret_out[NLPSOL_F] = w[CONIC_COST];
    ret_out[NLPSOL_G] = mtimes(v.at(2), w[CONIC_X]) + v.at(3);
    ret_out[NLPSOL_LAM_X] = w[CONIC_LAM_X];
    ret_out[NLPSOL_LAM_G] = w[CONIC_LAM_A];
    ret_out[NLPSOL_LAM_P] = MX::nan(p.sparsity());
    return Function(name, ret_in, ret_out, nlpsol_in(), nlpsol_out(),
                    {{"default_in", nlpsol_default_in()}});
  }
Example #10
0
bool SkOpEdgeBuilder::walk() {
    uint8_t* verbPtr = fPathVerbs.begin();
    uint8_t* endOfFirstHalf = &verbPtr[fSecondHalf];
    SkPoint* pointsPtr = fPathPts.begin() - 1;
    SkScalar* weightPtr = fWeights.begin();
    SkPath::Verb verb;
    SkOpContour* contour = fContourBuilder.contour();
    while ((verb = (SkPath::Verb) *verbPtr) != SkPath::kDone_Verb) {
        if (verbPtr == endOfFirstHalf) {
            fOperand = true;
        }
        verbPtr++;
        switch (verb) {
            case SkPath::kMove_Verb:
                if (contour && contour->count()) {
                    if (fAllowOpenContours) {
                        complete();
                    } else if (!close()) {
                        return false;
                    }
                }
                if (!contour) {
                    fContourBuilder.setContour(contour = fContoursHead->appendContour());
                }
                contour->init(fGlobalState, fOperand,
                    fXorMask[fOperand] == kEvenOdd_PathOpsMask);
                pointsPtr += 1;
                continue;
            case SkPath::kLine_Verb:
                fContourBuilder.addLine(pointsPtr);
                break;
            case SkPath::kQuad_Verb:
                {
                    SkVector v1 = pointsPtr[1] - pointsPtr[0];
                    SkVector v2 = pointsPtr[2] - pointsPtr[1];
                    if (v1.dot(v2) < 0) {
                        SkPoint pair[5];
                        if (SkChopQuadAtMaxCurvature(pointsPtr, pair) == 1) {
                            goto addOneQuad;
                        }
                        if (!SkScalarsAreFinite(&pair[0].fX, SK_ARRAY_COUNT(pair) * 2)) {
                            return false;
                        }
                        for (unsigned index = 0; index < SK_ARRAY_COUNT(pair); ++index) {
                            force_small_to_zero(&pair[index]);
                        }
                        SkPoint cStorage[2][2];
                        SkPath::Verb v1 = SkReduceOrder::Quad(&pair[0], cStorage[0]);
                        SkPath::Verb v2 = SkReduceOrder::Quad(&pair[2], cStorage[1]);
                        SkPoint* curve1 = v1 != SkPath::kLine_Verb ? &pair[0] : cStorage[0];
                        SkPoint* curve2 = v2 != SkPath::kLine_Verb ? &pair[2] : cStorage[1];
                        if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) {
                            fContourBuilder.addCurve(v1, curve1);
                            fContourBuilder.addCurve(v2, curve2);
                            break;
                        }
                    }
                }
            addOneQuad:
                fContourBuilder.addQuad(pointsPtr);
                break;
            case SkPath::kConic_Verb: {
                SkVector v1 = pointsPtr[1] - pointsPtr[0];
                SkVector v2 = pointsPtr[2] - pointsPtr[1];
                SkScalar weight = *weightPtr++;
                if (v1.dot(v2) < 0) {
                    // FIXME: max curvature for conics hasn't been implemented; use placeholder
                    SkScalar maxCurvature = SkFindQuadMaxCurvature(pointsPtr);
                    if (maxCurvature > 0) {
                        SkConic conic(pointsPtr, weight);
                        SkConic pair[2];
                        if (!conic.chopAt(maxCurvature, pair)) {
                            // if result can't be computed, use original
                            fContourBuilder.addConic(pointsPtr, weight);
                            break;
                        }
                        SkPoint cStorage[2][3];
                        SkPath::Verb v1 = SkReduceOrder::Conic(pair[0], cStorage[0]);
                        SkPath::Verb v2 = SkReduceOrder::Conic(pair[1], cStorage[1]);
                        SkPoint* curve1 = v1 != SkPath::kLine_Verb ? pair[0].fPts : cStorage[0];
                        SkPoint* curve2 = v2 != SkPath::kLine_Verb ? pair[1].fPts : cStorage[1];
                        if (can_add_curve(v1, curve1) && can_add_curve(v2, curve2)) {
                            fContourBuilder.addCurve(v1, curve1, pair[0].fW);
                            fContourBuilder.addCurve(v2, curve2, pair[1].fW);
                            break;
                        }
                    }
                }
                fContourBuilder.addConic(pointsPtr, weight);
                } break;
            case SkPath::kCubic_Verb:
                {
                    // Split complex cubics (such as self-intersecting curves or
                    // ones with difficult curvature) in two before proceeding.
                    // This can be required for intersection to succeed.
                    SkScalar splitT[3];
                    int breaks = SkDCubic::ComplexBreak(pointsPtr, splitT);
                    if (!breaks) {
                        fContourBuilder.addCubic(pointsPtr);
                        break;
                    }
                    SkASSERT(breaks <= (int) SK_ARRAY_COUNT(splitT));
                    struct Splitsville {
                        double fT[2];
                        SkPoint fPts[4];
                        SkPoint fReduced[4];
                        SkPath::Verb fVerb;
                        bool fCanAdd;
                    } splits[4];
                    SkASSERT(SK_ARRAY_COUNT(splits) == SK_ARRAY_COUNT(splitT) + 1);
                    SkTQSort(splitT, &splitT[breaks - 1]);
                    for (int index = 0; index <= breaks; ++index) {
                        Splitsville* split = &splits[index];
                        split->fT[0] = index ? splitT[index - 1] : 0;
                        split->fT[1] = index < breaks ? splitT[index] : 1;
                        SkDCubic part = SkDCubic::SubDivide(pointsPtr, split->fT[0], split->fT[1]);
                        if (!part.toFloatPoints(split->fPts)) {
                            return false;
                        }
                        split->fVerb = SkReduceOrder::Cubic(split->fPts, split->fReduced);
                        SkPoint* curve = SkPath::kCubic_Verb == verb
                                ? split->fPts : split->fReduced;
                        split->fCanAdd = can_add_curve(split->fVerb, curve);
                    }
                    for (int index = 0; index <= breaks; ++index) {
                        Splitsville* split = &splits[index];
                        if (!split->fCanAdd) {
                            continue;
                        }
                        int prior = index;
                        while (prior > 0 && !splits[prior - 1].fCanAdd) {
                            --prior;
                        }
                        if (prior < index) {
                            split->fT[0] = splits[prior].fT[0];
                            split->fPts[0] = splits[prior].fPts[0];
                        }
                        int next = index;
                        int breakLimit = SkTMin(breaks, (int) SK_ARRAY_COUNT(splits) - 1);
                        while (next < breakLimit && !splits[next + 1].fCanAdd) {
                            ++next;
                        }
                        if (next > index) {
                            split->fT[1] = splits[next].fT[1];
                            split->fPts[3] = splits[next].fPts[3];
                        }
                        if (prior < index || next > index) {
                            split->fVerb = SkReduceOrder::Cubic(split->fPts, split->fReduced);
                        }
                        SkPoint* curve = SkPath::kCubic_Verb == split->fVerb
                                ? split->fPts : split->fReduced;
                        if (!can_add_curve(split->fVerb, curve)) {
                            return false;
                        }
                        fContourBuilder.addCurve(split->fVerb, curve);
                    }
                }
                break;
            case SkPath::kClose_Verb:
                SkASSERT(contour);
                if (!close()) {
                    return false;
                }
                contour = nullptr;
                continue;
            default:
                SkDEBUGFAIL("bad verb");
                return false;
        }
        SkASSERT(contour);
        if (contour->count()) {
            contour->debugValidate();
        }
        pointsPtr += SkPathOpsVerbToPoints(verb);
    }
    fContourBuilder.flush();
    if (contour && contour->count() &&!fAllowOpenContours && !close()) {
        return false;
    }
    return true;
}