//=========================================================================== double Param2FunctionInt::isolateDegPar(int dir, int deg_edge, double threshold) //=========================================================================== { // Specify boundary parameters int deg = (deg_edge == 3) ? 1 : deg_edge; int bd_idx = 2*dir + deg - 1; double bd_par = (deg == 1) ? startParam(dir) : endParam(dir); if (deg == 0 || deg_tol_ < 0 || !bd_deg_[bd_idx]) return bd_par; // No degeneracy // Compute the end parameter of the domain corresponding to a // piece of the surface of size fac*epsge from the degenerate edge double fac = 10.0; int nsample = 5; double param[2], delta; int ki; param[dir] = bd_par; param[1-dir] = startParam(1-dir); delta = (endParam(1-dir) - param[1-dir])/(double)(nsample-1); Point der[2]; double length; double delta_par = 0.0; for (ki=0; ki<nsample; ki++, param[1-dir] += delta) { derivs(param[0], param[1], der[0], der[1]); length = der[dir].length(); delta_par = std::max(delta_par, fac*deg_tol_/length); } return (deg == 1) ? bd_par + delta_par : bd_par - delta_par; }
//=========================================================================== void Param2FunctionInt::getLengthAndWiggle(double *length, double *wiggle) //=========================================================================== { int nsample_u = 5; // We sample in a nsample*nsample grid. int nsample_v = 5; int ki, kj; double tl1 = 0.0, tw1 = 0.0, tl2 = 0.0, tw2 = 0.0; Point pt, vec1_1, vec1_2, vec2_1, vec2_2; double umin = startParam(0); double ustep = (endParam(0) - umin)/(nsample_u - 1); double vmin = startParam(1); double vstep = (endParam(1) - vmin)/(nsample_v - 1); vector<Point> pts; // We store our sampled pts in a vector for // easy access. We look upon the function as // embedded in 3D: (u, v, f(u, v)). for (ki = 0; ki < nsample_v; ++ki) { double vpar = vmin + ki*vstep; for (kj = 0; kj < nsample_u; ++kj) { double upar = umin + kj*ustep; surf_->point(pt, upar, vpar); pts.push_back(Point(upar, vpar, pt[0])); } } // We then compute the total dist and wiggle in both parameter directions. for (ki = 0; ki < nsample_u; ++ki) { for (kj = 0; kj < nsample_v; ++kj) { if (ki < nsample_u - 1) { tl1 += pts[kj*nsample_u+ki].dist(pts[kj*nsample_u+ki+1]); if (ki > 0) { vec1_1 = pts[kj*nsample_u+ki] - pts[kj*nsample_u+ki-1]; vec1_2 = pts[kj*nsample_u+ki+1] - pts[kj*nsample_u+ki]; if (vec1_1.length2() != 0.0 && vec1_2.length2() != 0.0) tw1 += vec1_1.angle(vec1_2); } } if (kj < nsample_v - 1) { tl2 += pts[kj*nsample_u+ki].dist(pts[(kj+1)*nsample_u+ki]); if (kj > 0) { vec2_1 = pts[kj*nsample_u+ki] - pts[(kj-1)*nsample_u+ki]; vec2_2 = pts[(kj+1)*nsample_u+ki] - pts[kj*nsample_u+ki]; if (vec2_1.length2() != 0.0 && vec2_2.length2() != 0.0) tw2 += vec2_1.angle(vec2_2); } } } } // To minimize dependency on # samples we divide by nsample (in case // function is used as a measure of sf characteristic). length[0] = tl1/nsample_v; wiggle[0] = tw1/nsample_v; length[1] = tl2/nsample_u; wiggle[1] = tw2/nsample_u; }
void QgarAppDescr::endElement(const std::string& uri, const std::string& localName, const std::string& qName) { // Redirect action on the function matching the tag. if (localName == ELT_PARAM) { endParam(); } else if (localName == ELT_NAME) { endName(); } else if (localName == ELT_AUTHOR) { endAuthor(); } else if (localName == ELT_COPYRIGHT) { endCopyright(); } else if (localName == ELT_BRIEF) { endBrief(); } else if (localName == ELT_LONG) { endLong(); } }
//=========================================================================== void Param2FunctionInt::assureInRange(int pardir, double& t) //=========================================================================== { double tmin = startParam(pardir); double tmax = endParam(pardir); if (t < tmin) t = tmin; else if (t > tmax) t = tmax; }
//=========================================================================== void ParamCurveInt::axisFromEndpts(Point& axis) const //=========================================================================== { double start = startParam(0); double end = endParam(0); Point pt1, pt2; point(pt1, &start); point(pt2, &end); axis = pt2 - pt1; }
//=========================================================================== bool ParamCurveInt::boundaryPoint(const double* par, double tol) const //=========================================================================== { ASSERT(par != NULL); double d1 = fabs(*par - startParam(0)); double d2 = fabs(*par - endParam(0)); return min(d1, d2) < tol; }
//=========================================================================== double Param2FunctionInt:: nextSegmentVal(int pardir, double par, bool forward) const //=========================================================================== { // No inner knots expected to exist. if (forward) { return endParam(pardir); } else { return startParam(pardir); } }
//=========================================================================== int Param2FunctionInt:: knotIntervalFuzzy(int pardir, double& t, double tol) const //=========================================================================== { double tmin = startParam(pardir); double tmax = endParam(pardir); if (t < tmin || fabs(t-tmin)<tol) { t = tmin; return 0; } else if (t > tmax || fabs(t-tmax)<tol) { t = tmax; return 1; } else return 0; }
//=========================================================================== vector<double> SplineCurveInt::getCriticalValsAndKnots(int pardir) const //=========================================================================== { vector<double> critical = getCriticalVals(pardir); vector<double> knots = getInnerKnotVals(pardir, false); vector<double> vals; double ta = startParam(pardir); double tb = endParam(pardir); vals.push_back(ta); int ki, kj; for (ki=0, kj=0; ;) { if (ki >= int(critical.size()) && kj >= int(knots.size())) break; else if (ki >= int(critical.size())) { if (knots[kj] > vals[vals.size()-1]) vals.push_back(knots[kj]); kj++; } else if (kj >= int(knots.size())) { if (critical[ki] > vals[vals.size()-1]) vals.push_back(critical[ki]); ki++; } else if (critical[ki] < knots[kj]) { if (critical[ki] > vals[vals.size()-1]) vals.push_back(critical[ki]); ki++; } else { if (critical[ki] > vals[vals.size()-1]) vals.push_back(critical[ki]); ki++; } } if (tb > vals[vals.size()-1]) vals.push_back(tb); return vals; }
//=========================================================================== bool Param2FunctionInt::canDivide(int pardir) //=========================================================================== { // Flatness should be handled by sortParameterDirections() in intersector. // // @@sbr Stop dividing if almost (tol-equal) flat? // // Maybe more corresponding to shouldDivide() ... ? // bool is_deg = isDegenerate(deg_tol_, pardir); // if (is_deg) // return false; // This test must check whether the parameter interval of the surf // is long enough and probably also some other critera // @@@ VSK, for the time being ... double ta = startParam(pardir); double tb = endParam(pardir); double tc = 0.5*(ta+tb); double rel_par_res = 1e-10; // = epsge_->getRelParRes(); if (min(fabs(tc-ta), fabs(tb-tc)) < rel_par_res) return false; else return true; }
//=========================================================================== void Param2FunctionInt:: subdivide(int pardir, double par, vector<shared_ptr<ParamFunctionInt> >& subdiv_objs, vector<shared_ptr<ParamFunctionInt> >& bd_objs) //=========================================================================== { double start = startParam(pardir); double end = endParam(pardir); int other_pardir = (pardir == 1) ? 0 : 1; double other_start = startParam(other_pardir); double other_end = endParam(other_pardir); shared_ptr<SplineSurface> spline_sf = dynamic_pointer_cast<SplineSurface, ParamSurface>(surf_); ASSERT(spline_sf.get() != 0); // @@sbr Does not cope well with a // trimmed sf ... // Perform subdivision // @@@ VSK, This calls should be made more effective, but can do for // the time being shared_ptr<ParamSurface> sf1, sf2; // @@sbr But what if sf is trimmed ... double fuzzy_tol = DEFAULT_PARAMETER_EPSILON; //1e-08; try { if (pardir == 1) { sf1 = shared_ptr<ParamSurface>(spline_sf-> subSurface(other_start, start, other_end, par, fuzzy_tol)); sf2 = shared_ptr<ParamSurface>(spline_sf-> subSurface(other_start, par, other_end, end, fuzzy_tol)); } else { sf1 = shared_ptr<ParamSurface>(spline_sf-> subSurface(start, other_start, par, other_end, fuzzy_tol)); sf2 = shared_ptr<ParamSurface>(spline_sf-> subSurface(par, other_start, end, other_end, fuzzy_tol)); } } catch (...) { THROW("Failed extracting subsurface!"); } DEBUG_ERROR_IF(sf1.get()==0 || sf2.get()==0, "Error in subdivide"); // Get the subdivision curve // pardir == 1 => par is a v-par. int bdidx = (pardir == 0) ? 3 : 1; // @@sbr Is this correct? int sub_pardir; double sub_tpar; shared_ptr<SplineSurface> spline_sf1 = dynamic_pointer_cast<SplineSurface, ParamSurface>(sf1); shared_ptr<ParamCurve> subsf_cv(extractBdCurve(*spline_sf1, bdidx, sub_pardir, sub_tpar)); // Make intersection objects subdiv_objs.push_back(makeIntFunction(sf1)); subdiv_objs.push_back(makeIntFunction(sf2)); bd_objs.push_back(shared_ptr<ParamFunctionInt> (new Spline1FunctionInt(subsf_cv, this))); // @@sbr // Instead // of // Param1F... }