// COMPUTE ====================================== MStatus gear_uToPercentage::compute(const MPlug& plug, MDataBlock& data) { MStatus returnStatus; // Error check if (plug != percentage) return MS::kUnknownParameter; // Curve MFnNurbsCurve crv( data.inputValue( curve ).asNurbsCurve() ); // Sliders bool in_normU = data.inputValue( normalizedU ).asBool(); double in_u = (double)data.inputValue( u ).asFloat(); unsigned in_steps = data.inputValue( steps ).asShort(); // Process if (in_normU) in_u = normalizedUToU(in_u, crv.numCVs()); // Get length MVectorArray u_subpos(in_steps); MVectorArray t_subpos(in_steps); MPoint pt; double step; for (unsigned i = 0; i < in_steps ; i++){ step = i * in_u / (in_steps - 1.0); crv.getPointAtParam(step, pt, MSpace::kWorld); u_subpos[i] = MVector(pt); step = i/(in_steps - 1.0); crv.getPointAtParam(step, pt, MSpace::kWorld); t_subpos[i] = MVector(pt); } double u_length = 0; double t_length = 0; MVector v; for (unsigned i = 0; i < in_steps ; i++){ if (i>0){ v = u_subpos[i] - u_subpos[i-1]; u_length += v.length(); v = t_subpos[i] - t_subpos[i-1]; t_length += v.length(); } } double out_perc = (u_length / t_length) * 100; // Output MDataHandle h = data.outputValue( percentage ); h.setDouble( out_perc ); data.setClean( plug ); return MS::kSuccess; }
/* * crvn * * draws a series of curve segments. * */ void crvn(long int n, Coord (*geom)[3]) { int i; if (!vdevice.initialised) verror("crvn: vogl not initialised"); if (n < 4) verror("crvn: not enough points in geometry matrix"); for (i = 0; i <= n - 4; i++) crv(&geom[i]); }
Bezier_curve SurfCore::GetBorderCurve( int iborder ) const { piecewise_curve_type pwc; curve_segment_type s; s.resize( 3 ); piecewise_surface_type::index_type ip, jp, nupatch, nvpatch; surface_patch_type::index_type icp, jcp; nupatch = m_Surface.number_u_patches(); nvpatch = m_Surface.number_v_patches(); if ( iborder == UMIN || iborder == UMAX ) { if ( iborder == UMIN ) ip = 0; else ip = nupatch - 1; pwc.set_t0( m_Surface.get_v0() ); for( jp = 0; jp < nvpatch; ++jp ) { const surface_patch_type *patch = m_Surface.get_patch( ip, jp ); double dv = patch->get_vmax() - patch->get_vmin(); s.resize( patch->degree_v() ); if ( iborder == UMIN ) icp = 0; else icp = patch->degree_u(); for( jcp = 0; jcp <= patch->degree_v(); ++jcp ) { surface_point_type cp; cp = patch->get_control_point( icp, jcp ); s.set_control_point( cp, jcp ); } pwc.push_back( s, dv ); } } else if ( iborder == WMIN || iborder == WMAX ) { if ( iborder == WMIN ) jp = 0; else jp = nvpatch - 1; pwc.set_t0( m_Surface.get_u0() ); for( ip = 0; ip < nupatch; ++ip ) { const surface_patch_type *patch = m_Surface.get_patch( ip, jp ); double du = patch->get_umax() - patch->get_umin(); s.resize( patch->degree_u() ); if ( iborder == WMIN ) jcp = 0; else jcp = patch->degree_v(); for( icp = 0; icp <= patch->degree_u(); ++icp ) { surface_point_type cp; cp = patch->get_control_point( icp, jcp ); s.set_control_point( cp, icp ); } pwc.push_back( s, du ); } } Bezier_curve crv( pwc ); return crv; }
/* * using curves */ main() { char dev[20]; int i; short val; vinit("mswin"); winopen("curves"); qdevice(KEYBD); unqdevice(INPUTCHANGE); /* * Wait for REDRAW event ... */ while (qread(&val) != REDRAW) ; ortho2(-200.0, 400.0, -100.0, 500.0); color(BLACK); clear(); color(YELLOW); /* * label the control points in geom1 */ for (i = 0; i < 4; i++) { cmov2(geom1[i][0], geom1[i][1]); sprintf(dev, "%d", i); charstr(dev); } /* * label the control points in geom2 */ for (i = 0; i < 6; i++) { cmov2(geom2[i][0], geom2[i][1]); sprintf(dev, "%d", i); charstr(dev); } /* * set the number of line segments appearing in each curve to 20 */ curveprecision((short)20); /* * copy the bezier basis matrix into the basis matrix stack and * set the curve basis accordingly. */ defbasis((short)1, bezier); curvebasis((short)1); color(RED); /* * draw a curve using the current basis matrix (bezier in this case) * and the control points in geom1 */ crv(geom1); cmov2(70.0, 60.0); charstr("Bezier Curve Segment"); cmov2(-190.0, 450.0); charstr("Three overlapping Bezier Curves"); /* * crvn draws overlapping curve segments according to geom2, the * number of curve segments drawn is three less than the number of * points passed, assuming there are a least four points in the * geometry matrix (in this case geom2). This call will draw 3 * overlapping curve segments in the current basis matrix - still * bezier. */ crvn(6L, geom2); qread(&val); /* * load in the cardinal basis matrix */ defbasis((short)1, cardinal); curvebasis((short)1); color(MAGENTA); cmov2(70.0, 10.0); charstr("Cardinal Curve Segment"); /* * plot out a curve segment using the cardinal basis matrix */ crv(geom1); cmov2(-190.0, 400.0); charstr("Three overlapping Cardinal Curves"); /* * now draw a bunch of them again. */ crvn(6L, geom2); qread(&val); /* * change the basis matrix again */ defbasis((short)1, bspline); curvebasis((short)1); color(GREEN); cmov2(70.0, -40.0); charstr("Bspline Curve Segment"); /* * now draw our curve segment in the new basis... */ crv(geom1); cmov2(-190.0, 350.0); charstr("Three overlapping Bspline Curves"); /* * ...and do some overlapping ones */ crvn(6L, geom2); qread(&val); gexit(); }
// COMPUTE ====================================== MStatus gear_slideCurve2::deform( MDataBlock& data, MItGeometry& iter, const MMatrix &mat, unsigned int mIndex ) { MStatus returnStatus; // Inputs --------------------------------------------------------- // Input NurbsCurve // Curve MFnNurbsCurve crv( data.inputValue( master_crv ).asNurbsCurve() ); MMatrix m = data.inputValue(master_mat).asMatrix(); // Input Sliders double in_sl = (double)data.inputValue(slave_length).asFloat(); double in_ml = (double)data.inputValue(master_length).asFloat(); double in_position = (double)data.inputValue(position).asFloat(); double in_maxstretch = (double)data.inputValue(maxstretch).asFloat(); double in_maxsquash = (double)data.inputValue(maxsquash).asFloat(); double in_softness = (double)data.inputValue(softness).asFloat(); // Init ----------------------------------------------------------- double mstCrvLength = crv.length(); int slvPointCount = iter.exactCount(); // Can we use .count() ? int mstPointCount = crv.numCVs(); // Stretch -------------------------------------------------------- double expo = 1; if ((mstCrvLength > in_ml) && (in_maxstretch > 1)){ if (in_softness != 0){ double stretch = (mstCrvLength - in_ml) / (in_sl * in_maxstretch); expo = 1 - exp(-(stretch) / in_softness); } double ext = min(in_sl * (in_maxstretch - 1) * expo, mstCrvLength - in_ml); in_sl += ext; } else if ((mstCrvLength < in_ml) && (in_maxsquash < 1)){ if (in_softness != 0){ double squash = (in_ml - mstCrvLength) / (in_sl * in_maxsquash); expo = 1 - exp(-(squash) / in_softness); } double ext = min(in_sl * (1 - in_maxsquash) * expo, in_ml - mstCrvLength); in_sl -= ext; } // Position -------------------------------------------------------- double size = in_sl / mstCrvLength; double sizeLeft = 1 - size; double start = in_position * sizeLeft; double end = start + size; double tStart, tEnd; crv.getKnotDomain(tStart, tEnd); // Process -------------------------------------------------------- double step = (end - start) / (slvPointCount - 1.0); MPoint pt; MVector tan; while (! iter.isDone()){ double perc = start + (iter.index() * step); double u = crv.findParamFromLength(perc * mstCrvLength); if ((0 <= perc) && (perc <= 1)) crv.getPointAtParam(u, pt, MSpace::kWorld); else{ double overPerc; if (perc < 0){ overPerc = perc; crv.getPointAtParam(0, pt, MSpace::kWorld); tan = crv.tangent(0); } else{ overPerc = perc - 1; crv.getPointAtParam(mstPointCount-3.0, pt, MSpace::kWorld); tan = crv.tangent(mstPointCount-3.0); tan.normalize(); tan *= mstCrvLength * overPerc; pt += tan; } } pt *= mat.inverse(); pt *= m; iter.setPosition(pt); iter.next(); } return MS::kSuccess; }
int main() { boost::reference_wrapper<X const> r = boost::cref( crv() ); // must fail }
// COMPUTE ====================================== MStatus gear_percentageToU::compute(const MPlug& plug, MDataBlock& data) { MStatus returnStatus; // Error check if (plug != percentage) return MS::kUnknownParameter; // Curve MFnNurbsCurve crv( data.inputValue( curve ).asNurbsCurve() ); // Sliders bool in_normU = data.inputValue( normalizedU ).asBool(); double in_percentage = (double)data.inputValue( percentage ).asFloat() * .01; const unsigned in_steps = data.inputValue( steps ).asShort(); // Process // Get length MVectorArray u_subpos(in_steps); MPoint pt; MDoubleArray u_list(in_steps); for(unsigned i = 0 ; i < in_steps ; i++ ){ u_list[i] = normalizedUToU(i /(in_steps - 1.0), crv.numCVs()); crv.getPointAtParam(u_list[i], pt, MSpace::kWorld); u_subpos[i] = MVector(pt); } double t_length = 0; MDoubleArray dist(in_steps); MVector v; for (unsigned i = 0; i < in_steps ; i++){ if (i>0){ v = u_subpos[i] - u_subpos[i-1]; t_length += v.length(); dist[i] = t_length; } } MDoubleArray u_perc(in_steps); for (unsigned i = 0; i < in_steps ; i++){ u_perc[i] = dist[i] / t_length; } // Get closest indices unsigned index = findClosestInArray(in_percentage, u_perc); unsigned indexA, indexB; if (in_percentage <= u_perc[index]){ indexA = abs(int(index)); indexB = index; if ( indexA > indexB){ indexA = indexB; indexB = indexA+1; } } else { indexA = index; indexB = index + 1; } // blend value double blend = set01range(in_percentage, u_perc[indexA], u_perc[indexB]); double out_u = linearInterpolate(u_list[indexA], u_list[indexB], blend); if (in_normU) out_u = uToNormalizedU(out_u, crv.numCVs()); // Ouput MDataHandle h = data.outputValue( u ); h.setDouble( out_u ); data.setClean( plug ); return MS::kSuccess; }