Exemple #1
0
void Model::storeActiveNodeGeometry()
{
    if (activeNode == nullptr) return;

    QSet<Structure::Node*> nodes;
    nodes << activeNode;

    // Apply to group if in any
    for(auto g : groupsOf(activeNode->id)){
        for(auto nid : g){
            nodes << getNode(nid);
        }
    }

    for(auto n : nodes)
    {
        // Store initial node and mesh geometries
        n->property["restNodeGeometry"].setValue(n->controlPoints());
        n->property["restNodeCentroid"].setValue(n->center());
        auto mesh = getMesh(n->id);
        Array1D_Vector3 meshPoints;
        for (auto v : mesh->vertices()) meshPoints.push_back(mesh->vertex_coordinates()[v]);
        n->property["restMeshGeometry"].setValue(meshPoints);
    }
}
Exemple #2
0
void Model::createSheetFromPoints(QVector<QVector3D> &points)
{
    if (points.size() < 2) return;

    // Convert corner points to Vector3
    Array1D_Vector3 cp;
    for(auto p : points) cp.push_back(Vector3(p[0],p[1],p[2]));

    // midpoint of diagonal
    Vector3 center = 0.5 * (cp[1] + cp[2]);

    // Extent
    Vector3 du = cp[0] - cp[2], dv = cp[0] - cp[1];
    double u = du.norm(), v = dv.norm();

    // Create sheet
    auto newSheetGeometry = NURBS::NURBSRectangled::createSheet(u, v, center, du.normalized(), dv.normalized());
    QString newSheetID = QString("sheetNode%1").arg((nodes.empty()? -1 : nodes.back()->property["index"].toInt())+1);
    auto newSheet = new Structure::Sheet(newSheetGeometry, newSheetID);

    // Add sheet
    activeNode = this->addNode(newSheet);

    generateSurface();
}
Exemple #3
0
void Model::modifyLastAdded(QVector<QVector3D> &guidePoints)
{
    if (guidePoints.size() < 2 || activeNode == nullptr) return;

    Structure::Curve* curve = dynamic_cast<Structure::Curve*>(activeNode);
    Structure::Sheet* sheet = dynamic_cast<Structure::Sheet*>(activeNode);

    auto fp = guidePoints.takeFirst();
    Vector3 axis(fp.x(),fp.y(),fp.z());

    int skipAxis = -1;
    if (axis.isApprox(-Vector3::UnitX())) skipAxis = 0;
    if (axis.isApprox(-Vector3::UnitY())) skipAxis = 1;
    if (axis.isApprox(Vector3::UnitZ())) skipAxis = 2;

    // Smooth curve
    guidePoints = GeometryHelper::smooth(GeometryHelper::uniformResampleCount(guidePoints, 20), 5);

    // Convert to Vector3
    Array1D_Vector3 gpoint;
    for(auto p : guidePoints) gpoint.push_back(Vector3(p[0],p[1],p[2]));

    if(curve)
    {
        auto oldPoints = curve->controlPoints();
        auto newPoints = oldPoints;

        for(size_t i = 0; i < oldPoints.size(); i++){
            for(int j = 0; j < 3; j++){
                if(j == skipAxis) newPoints[i][j] = oldPoints[i][j];
                else newPoints[i][j] = gpoint[i][j];
            }
        }

        curve->setControlPoints(newPoints);
    }

    if(sheet)
    {
        auto oldPoints = sheet->controlPoints();
        auto newPoints = oldPoints;

        Vector3 centroid = sheet->position(Eigen::Vector4d(0.5, 0.5, 0, 0));
        Vector3 delta = gpoint.front() - centroid;

        for(size_t i = 0; i < oldPoints.size(); i++){
            for (int j = 0; j < 3; j++){
                if (j == skipAxis) continue;
                newPoints[i][j] += delta[j];
            }
        }

        sheet->setControlPoints(newPoints);
        sheet->surface.quads.clear();
    }

    generateSurface();
}
void DeformationPath::badMorphing()
{
	for(double t = 0; t <= 1.0; t += scheduler->timeStep)
	{
		// Current nodes geometry
		QMap<Structure::Node*, Array1D_Vector3> startGeometry;
		for(auto n : scheduler->activeGraph->nodes)
		{
			if(n->property["taskTypeReal"].toInt() == Task::GROW)
			{
				Array1D_Vector3 pnts = n->controlPoints();
				Vector3 p = pnts.front();
				Array1D_Vector3 newpnts(pnts.size(), p);
				for(auto & p: newpnts) p += Eigen::Vector3d(starlab::uniformRand(), starlab::uniformRand(), starlab::uniformRand()) * 1e-5;
				n->setControlPoints(newpnts);
			}

			if(n->property["taskTypeReal"].toInt() == Task::SHRINK)
			{
				auto tn = scheduler->targetGraph->getNode( n->property["correspond"].toString() );
				Array1D_Vector3 pnts = tn->controlPoints();
				Vector3 p = pnts[pnts.size() / 2];
				Array1D_Vector3 newpnts(pnts.size(), p);
				for(auto & p: newpnts) p += Eigen::Vector3d(starlab::uniformRand(), starlab::uniformRand(), starlab::uniformRand()) * 1e-5;
				tn->setControlPoints(newpnts);
			}

			startGeometry[n] = n->controlPoints();
		}

		// Morph nodes
		for(auto n : scheduler->activeGraph->nodes)
		{
			auto tn = scheduler->targetGraph->getNode( n->property["correspond"].toString() );
			if(!tn) continue;

			Array1D_Vector3 finalGeometry = tn->controlPoints();
			Array1D_Vector3 newGeometry;

			for(int i = 0; i < (int) finalGeometry.size(); i++)
				newGeometry.push_back( AlphaBlend(t, startGeometry[n][i], Vector3(finalGeometry[i])) );

			n->setControlPoints( newGeometry );
			n->property["t"].setValue( t );

			if(t > 0.5 && n->property["taskTypeReal"].toInt() == Task::SHRINK) 
				n->property["shrunk"].setValue( true );
		}

		scheduler->allGraphs.push_back(  new Structure::Graph( *scheduler->activeGraph )  );
	}

	property["progressDone"] = true;
}
Exemple #5
0
Array1D_Real NURBSCurve<Real>::insertKnot(Real u, int k, int s, int r, Array1D_Vector3 & Qw, int * uq)
{
    Array1D_Real	UP = GetKnotVector();
    Array1D_Vector3 Pw = mCtrlPoint;
    Array1D_Real	UQ;

    Array1D_Vector3 Rw;
    Scalar alpha;
    int L = 0;

    int order = this->GetDegree() + 1;
    int p = order - 1;
    int np = Pw.size() - 1;

    int mp = np+p+1;
    int nq = np+r;

    // Define array
    UQ.resize(mp+r+1);
    Qw.resize(nq+1);
    Rw.resize(p+1);

    // Load new knot vector
    for (int i=0; i<=k; i++)	UQ[i]	= UP[i];
    for (int i=1; i<=r; i++)	UQ[k+i] = u;
    for (int i=k+1; i<=mp; i++)	UQ[i+r] = UP[i];

    // Save unaltered control points
    for (int i=0; i<=k-p; i++)	Qw[i]	= Pw[i];
    for (int i=k-s; i<=np; i++)	Qw[i+r] = Pw[i];
    for (int i=0; i<=p-s; i++)	Rw[i]	= Pw[k-p+i];

    // Insert the knot r times
    for (int j=1; j<=r; j++)
    {
        L = k-p+j;
        for (int i=0; i<=p-j-s; i++)
        {
            alpha = (u-UP[L+i])/(UP[i+k+1]-UP[L+i]);
            Rw[i] = alpha*Rw[i+1] + (1.0 - alpha) * Rw[i];
        }
        Qw[L] = Rw[0];
        Qw[k+r-j-s] = Rw[p-j-s];
    }

    // Load remaining control points
    for (int i=L+1; i<k-s; i++)
        Qw[i] = Rw[i-L];

    if(uq) *uq = k-p+1;

    return UQ;
}
Exemple #6
0
Real NURBSCurve<Real>::KnotRemovalError( int r, int s )
{
    Array1D_Real	U = GetKnotVector();
    Array1D_Vector3 P = mCtrlPoint;

    Array1D_Vector3 temp(P.size(), Vector3(0,0,0)) ;

    int deg_ = GetDegree();

    int ord = deg_+1 ;
    int last = r-s ;
    int first = r-deg_ ;
    int off ;
    int i,j,ii,jj ;
    Real alfi,alfj ;
    Real u ;

    u = U[r] ;

    off = first-1;
    temp[0] = P[off] ;
    temp[last+1-off] = P[last+1] ;

    i=first ;
    j=last ;
    ii=1 ;
    jj=last-off ;

    while(j-i>0) {
        alfi = (u-U[i])/(U[i+ord]-U[i]) ;
        alfj = (u-U[j])/(U[j+ord]-U[j]) ;
        temp[ii] = (P[i]-(1.0-alfi)*temp[ii-1])/alfi ;
        temp[jj] = (P[j]-alfj*temp[jj+1])/(1.0-alfj) ;
        ++i ;
        ++ii ;
        --j ;
        --jj ;
    }
    if(j-i<0) {
        return (temp[ii-1]-temp[jj+1]).norm() ;
    }
    else {
        alfi=(u-U[i])/(U[i+ord]-U[i]) ;
        return (P[i]-alfi*temp[ii+1]+(1.0-alfi)*temp[ii-1]).norm() ;
    }

}
Exemple #7
0
Array1D_Vector3 Sheet::discretizedAsCurve(Scalar resolution)
{
    // Return a representative curve along the longest side at the middle of the sheet
    NURBS::NURBSCurved curve;

    Vector3 uDir = surface.mCtrlPoint.front().back() - surface.mCtrlPoint.front().front();
    Vector3 vDir = surface.mCtrlPoint.back().front() - surface.mCtrlPoint.front().front();

    double projux = abs(dot(Vector3d(1,0,0), uDir.normalized()));
    double projvx = abs(dot(Vector3d(1,0,0), vDir.normalized()));

    //bool isU = uDir.norm() > vDir.norm();
	bool isU = projux > projvx;

    if( isU )
    {
        int v = (surface.mNumUCtrlPoints - 1) * 0.5;
        curve = NURBS::NURBSCurved(surface.GetControlPointsV(v), surface.GetControlWeightsV(v));
    }
    else
    {
        int u = (surface.mNumVCtrlPoints - 1) * 0.5;
        curve = NURBS::NURBSCurved(surface.GetControlPointsU(u), surface.GetControlWeightsU(u));
    }

    Array1D_Vector3 result;
    Scalar curveLength = curve.GetLength(0,1);

    // Degenerate cases
    bool validControlPoints = std::isfinite(curve.mCtrlPoint.front().x());
    if( !validControlPoints ){
        result.clear();
        for(int i = 0; i < 4; i++) result.push_back(Vector3(0,0,0));
        return result;
    }
    if( !std::isfinite(curveLength) || curveLength < resolution )
        return curve.mCtrlPoint;

    int np = qMax(2.0, 1.0 + (curveLength / resolution));

    curve.SubdivideByLength(np, result);
    return result;
}
Exemple #8
0
void Model::createCurveFromPoints(QVector<QVector3D> & points)
{
    if(points.size() < 2) return;

    // Nicer curve
    points = GeometryHelper::smooth(GeometryHelper::uniformResampleCount(points, 20), 5);

    // Create curve
    Array1D_Vector3 controlPoints;
    for(auto p : points) controlPoints.push_back(Vector3(p[0],p[1],p[2]));

    auto newCurveGeometry = NURBS::NURBSCurved::createCurveFromPoints(controlPoints);
    QString newCurveID = QString("curveNode%1").arg((nodes.empty()? -1 : nodes.back()->property["index"].toInt())+1);
    auto newCurve = new Structure::Curve(newCurveGeometry, newCurveID);

    // Add curve
    activeNode = this->addNode(newCurve);

    generateSurface();
}
Exemple #9
0
void TaskSheet::executeCrossingSheet( double t )
{
	Node *n = node(), *tn = targetNode();

	QVector<Link*> edges = active->getEdges( property["edges"].value< QVector<int> >() );

	if (property.contains("path"))
	{
		Vector3 p0 = n->position(Vec4d(0,0,0,0));
		Vector3 delta(0,0,0);

		if(!edges.isEmpty())
		{
			p0 = edges.front()->position(n->id);

			// Blend Deltas
			Structure::Link *slink = edges.front();
			Structure::Link* tlink = target->getEdge(slink->property["correspond"].toInt());
			Vector3 d1 = slink->position(n->id) - slink->positionOther(n->id);
			Vector3 d2 = tlink->position(tn->id) - tlink->positionOther(tn->id);
			delta = AlphaBlend(t, d1, d2);
		}

		executeMorphSheet(t);
		
		// Cancel any absolute movement
		if(!edges.isEmpty())
			n->moveBy(p0 - edges.front()->position(n->id));

		// Move it to the correct position
		Array1D_Vector3 path = property["path"].value< Array1D_Vector3 >();
		int idx = t * (path.size() - 1);

		Vector3 oldPosOnMe = p0;
		Vector3 newPosOnMe = path[idx] + delta;

		n->moveBy(newPosOnMe - p0);
	}
}
Exemple #10
0
void TaskSheet::executeMorphSheet( double t )
{
    Structure::Node * n = node();
    Structure::Sheet * sheet = (Structure::Sheet *)n;

    // Decode
    SheetEncoding cpCoords = property["cpCoords"].value<SheetEncoding>();
    SheetEncoding cpCoordsT = property["cpCoordsT"].value<SheetEncoding>();

    RMF::Frame sframe = property["sframe"].value<RMF::Frame>();
    RMF::Frame tframe = property["tframe"].value<RMF::Frame>();
	QVector<double> rot = property["rotation"].value< QVector<double> >();
    Eigen::Quaterniond rotation(rot[0],rot[1],rot[2],rot[3]),
        eye = Eigen::Quaterniond::Identity();

    // Source sheet
    Eigen::Vector3d R = (sframe.r), S = (sframe.s), T = (sframe.t);
    R = eye.slerp(t, rotation) * R;
    S = eye.slerp(t, rotation) * S;
    T = eye.slerp(t, rotation) * T;
    RMF::Frame curFrame ((R),(S),(T));

    curFrame.center = tframe.center = AlphaBlend(t, sframe.center, tframe.center);

    Array1D_Vector3 newPnts = Sheet::decodeSheet( cpCoords, curFrame.center, curFrame.r, curFrame.s, curFrame.t );
    Array1D_Vector3 newPntsT = Sheet::decodeSheet( cpCoordsT, tframe.center, tframe.r, tframe.s, tframe.t );

    Array1D_Vector3 blendedPnts;

    for(int i = 0; i < (int)newPnts.size(); i++)
    {
        blendedPnts.push_back( AlphaBlend(t, newPnts[i], newPntsT[i]) );
    }

    sheet->setControlPoints( blendedPnts );
}
Exemple #11
0
NURBSCurve<Real>::NURBSCurve (
    const Array1D_Vector3 & ctrlPoint, const Array1D_Real & ctrlWeight, int degree,
    bool loop, bool open)
    :
    SingleCurve<Real>((Real)0, (Real)1),
    mLoop(loop)
{
    int numCtrlPoints = ctrlPoint.size();

    assertion(numCtrlPoints >= 2, "Invalid input\n");
    assertion(1 <= degree && degree <= numCtrlPoints-1, "Invalid input\n");

    mNumCtrlPoints = numCtrlPoints;
    mReplicate = (loop ? (open ? 1 : degree) : 0);
    CreateControl(ctrlPoint, ctrlWeight);
    mBasis.Create(mNumCtrlPoints + mReplicate, degree, open);
}
Exemple #12
0
Array1D_Vector3 NURBSCurve<Real>::removeKnots(int iterations)
{
    NURBSCurve<Real> curCurve = *this;

    for(int itr = 0; itr < iterations; itr++)
    {
        Array1D_Real	U = curCurve.GetKnotVector();
        Array1D_Vector3 P = curCurve.mCtrlPoint;
        int p = curCurve.GetDegree();

        QMap<Real, int> errors;
        for(int i = p + 1; i < (int)U.size() - 1; i++)
        {
            if(U[i] < U[i+1])
                errors[ curCurve.KnotRemovalError(i, 1) ] = i;
        }

        int r = errors.values().at(itr); // Knot to remove

        int num = 1;
        int s = 1;

        int deg_ = curCurve.GetDegree();
        int m = U.size() ;
        int ord = deg_+1 ;
        int fout = (2*r-s-deg_)/2 ;
        int last = r-s ;
        int first = r-deg_ ;
        Real alfi, alfj ;
        int i,j,k,ii,jj,off ;
        Real u ;

        Array1D_Vector3 temp( 2*deg_+1, Vector3(0,0,0) ) ;

        u = U[r] ;

        int t;
        for(t=0; t<num; ++t)
        {
            off = first-1 ;
            temp[0] = P[off] ;
            temp[last+1-off] = P[last+1] ;
            i = first;
            j = last ;
            ii = 1 ;
            jj = last-off ;
            while(j-i > t) {
                alfi = (u-U[i])/(U[i+ord+t]-U[i]) ;
                alfj = (u-U[j-t])/(U[j+ord]-U[j-t]) ;
                temp[ii] = (P[i]-(1.0-alfi)*temp[ii-1])/alfi ;
                temp[jj] = (P[j]-alfj*temp[jj+1])/(1.0-alfj) ;
                ++i ;
                ++ii ;
                --j ;
                --jj ;
            }
            i = first ;
            j = last ;
            while(j-i>t) {
                P[i] = temp[i-off] ;
                P[j] = temp[j-off] ;
                ++i;
                --j ;
            }
            --first ;
            ++last ;
        }
        if(t == 0)
            return P;

        for(k=r+1; k<m ; ++k)
            U[k-t] = U[k] ;
        j = fout ;
        i=j ; // Pj thru Pi will be overwritten
        for(k=1; k<t; k++)
            if( (k%2) == 1)
                ++i ;
            else
                --j ;
        for(k=i+1; k<(int)P.size() ; k++) {// Shift
            P[j++] = P[k] ;
        }

        P.resize(P.size() - t);
        curCurve = createCurveFromPoints(P);
    }

    return curCurve.mCtrlPoint;
}
Exemple #13
0
void NURBSCurve<Real>::refine(Array1D_Real & insknts, Array1D_Vector3 & Qw, Array1D_Real & Ubar )
{
    // Input
    Array1D_Real X		= insknts;
    Array1D_Vector3 Pw	= this->mCtrlPoint;
    Array1D_Real U		= GetKnotVector();

    int s = insknts.size();
    int order = this->GetDegree() + 1;
    int p = order - 1;
    int n = Pw.size() - 1;
    int r = X.size() - 1;
    int m = n+p+1;

    // Output
    Qw.resize	( n+s+1, Vector3(0,0,0) );
    Ubar.resize	( m+s+1, 0 );

    int a = findSpan(n,p,X[0],U);
    int b = findSpan(n,p,X[r],U) + 1;

    int j = 0;
    for(j=0	 ; j<=a-p; j++)  Qw[j]		 = Pw[j];
    for(j=b-1; j<=n	 ; j++)  Qw[j+r+1]	 = Pw[j];
    for(j=0	 ; j<=a	 ; j++)  Ubar[j]	 = U[j];
    for(j=b+p; j<=m	 ; j++)  Ubar[j+r+1] = U[j];

    int i = b+p-1;
    int k = b+p+r;

    Real alfa = 0;

    for (int j=r; j>=0; j--)
    {
        while (X[j] <= U[i] && i > a) {
            Qw[k-p-1] = Pw[i-p-1];
            Ubar[k] = U[i];
            k = k - 1;
            i = i - 1;
        }

        Qw[k-p-1] = Qw[k-p];

        for (int l=1; l<=p; l++)
        {
            int ind = k-p+l;
            alfa = Ubar[k+l] - X[j];
            if (fabs(alfa) == 0.0)
            {
                Qw[ind-1] = Qw[ind];
            }
            else
            {
                alfa = alfa / (Ubar[k+l] - U[i-p+l]);
                Qw[ind-1] = alfa * Qw[ind-1] + (1.0 - alfa) * Qw[ind];
            }
        }
        Ubar[k] = X[j];
        k = k - 1;
    }
}