// push-cutter: vertex and facet handled in base-class //C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: bool generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const protected new bool generalEdgePush(Fiber f, Interval i, Point p1, Point p2) { bool result = false; if (GlobalMembers.isZero_tol((p2 - p1).xyNorm())) { // this would be a vertical edge return(result); } Point ufp1 = f.p1 + new Point(0, 0, radius); // take a fiber which is raised up by radius Point ufp2 = f.p2 + new Point(0, 0, radius); // and intersect it with a cylinder around the edge p1-p2 // Ray : P(t) = O + t*V from point O, in direction V // Cylinder [A, B, r] from point A to point B, radius r // Point P on infinite cylinder if ((P - A) x (B - A))^2 = r^2 * (B - A)^2 // expand : ((O - A) x (B - A) + t * (V x (B - A)))^2 = r^2 * (B - A)^2 // equation in the form (X + t * Y)^2 = d , where: // X = (O - A) x (B - A) // Y = V x (B - A) // d = r^2 * (B - A)^2 // expand the equation : // t^2 * (Y . Y) + t * (2 * (X . Y)) + (X . X) - d = 0 // => second order equation in the form : a*t^2 + b*t + c = 0 where // a = (Y . Y) // b = 2 * (X . Y) // c = (X . X) - d Point ab = p2 - p1; // axis of the cylinder Point ao = (ufp1 - p1); // cyl start to ray start Point ao_x_ab = ao.cross(ab); // cross product Point v_x_ab = (ufp2 - ufp1).cross(ab); // cross product double ab2 = ab.dot(ab); // dot product double a = v_x_ab.dot(v_x_ab); // dot product double b = 2 * (v_x_ab.dot(ao_x_ab)); // dot product double c = ao_x_ab.dot(ao_x_ab) - (radius * radius * ab2); // solve second order equation : a*t^2 + b*t + c = 0 // t = (-b +/- sqrt( b^2 - 4ac ) ) / 2a double discr = b * b - 4 * a * c; double t1; double t2; if (GlobalMembers.isZero_tol(discr)) { // tangent case, only one root t1 = -b / (2 * a); if (calcCCandUpdateInterval(t1, p1, p2, f, i)) { result = true; } } else if (discr > 0.0) { // two roots t1 = (-b + Math.Sqrt(discr)) / (2 * a); t2 = (-b - Math.Sqrt(discr)) / (2 * a); if (calcCCandUpdateInterval(t1, p1, p2, f, i)) { result = true; } if (calcCCandUpdateInterval(t2, p1, p2, f, i)) { result = true; } } return(result); }
/// y-direction adaptive sampling protected void yfiber_adaptive_sample(Span span, double start_t, double stop_t, Fiber start_f, Fiber stop_f) { double mid_t = start_t + (stop_t - start_t) / 2.0; // mid point sample Debug.Assert(mid_t > start_t); Debug.Assert(mid_t < stop_t); //std::cout << "yfiber sample= ( " << start_t << " , " << stop_t << " ) \n"; Point mid_p1 = new Point(span.getPoint(mid_t).x, miny, zh); Point mid_p2 = new Point(span.getPoint(mid_t).x, maxy, zh); Fiber mid_f = new Fiber(mid_p1, mid_p2); subOp[1].run(mid_f); double fw_step = Math.Abs(start_f.p1.x - stop_f.p1.x); if (fw_step > sampling) { // above minimum step-forward, need to sample more //C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created: //ORIGINAL LINE: yfiber_adaptive_sample(span, start_t, mid_t, start_f, mid_f); yfiber_adaptive_sample(span, start_t, mid_t, new ocl.Fiber(start_f), new ocl.Fiber(mid_f)); //C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created: //ORIGINAL LINE: yfiber_adaptive_sample(span, mid_t, stop_t, mid_f, stop_f); yfiber_adaptive_sample(span, mid_t, stop_t, new ocl.Fiber(mid_f), new ocl.Fiber(stop_f)); } //C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created: //ORIGINAL LINE: else if (!flat(start_f,mid_f,stop_f)) else if (!flat(new ocl.Fiber(start_f), new ocl.Fiber(mid_f), new ocl.Fiber(stop_f))) { if (fw_step > min_sampling) { // not a flat segment, and we have not reached maximum sampling //C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created: //ORIGINAL LINE: yfiber_adaptive_sample(span, start_t, mid_t, start_f, mid_f); yfiber_adaptive_sample(span, start_t, mid_t, new ocl.Fiber(start_f), new ocl.Fiber(mid_f)); //C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created: //ORIGINAL LINE: yfiber_adaptive_sample(span, mid_t, stop_t, mid_f, stop_f); yfiber_adaptive_sample(span, mid_t, stop_t, new ocl.Fiber(mid_f), new ocl.Fiber(stop_f)); } } else { yfibers.Add(stop_f); } }
public new void run(Fiber f) { pushCutter2(f); }
/// CCPoint calculation and interval update for push-cutter //C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: bool calcCCandUpdateInterval(double t, double u, const Point& q, const Point& p1, const Point& p2, const Fiber& f, Interval& i, double height, CCType cctyp) const protected bool calcCCandUpdateInterval(double t, double u, Point q, Point p1, Point p2, Fiber f, Interval i, double height, CCType cctyp) { CCPoint cc_tmp = new CCPoint(q + u * (p2 - p1)); cc_tmp.type = cctyp; return(i.update_ifCCinEdgeAndTrue(t, cc_tmp, p1, p2, (cc_tmp.z >= height))); }
/// adaptive waterline algorithm protected void adaptive_sampling_run() { minx = surf.bb.minpt.x - 2 * cutter.getRadius(); maxx = surf.bb.maxpt.x + 2 * cutter.getRadius(); miny = surf.bb.minpt.y - 2 * cutter.getRadius(); maxy = surf.bb.maxpt.y + 2 * cutter.getRadius(); Line line = new Line(new Point(minx, miny, zh), new Point(maxx, maxy, zh)); Span linespan = new LineSpan(line); #if _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#: // #pragma omp parallel sections { //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#: // #pragma omp section // Replace OMP Task by Parallel sections { // first child #else //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#: //#pragma omp parallel { //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#: //#pragma omp single nowait { // initial root task //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#: //#pragma omp task { // first child task #endif // _WIN32 xfibers.Clear(); Point xstart_p1 = new Point(minx, linespan.getPoint(0.0).y, zh); Point xstart_p2 = new Point(maxx, linespan.getPoint(0.0).y, zh); Point xstop_p1 = new Point(minx, linespan.getPoint(1.0).y, zh); Point xstop_p2 = new Point(maxx, linespan.getPoint(1.0).y, zh); Fiber xstart_f = new Fiber(xstart_p1, xstart_p2); Fiber xstop_f = new Fiber(xstop_p1, xstop_p2); subOp[0].run(xstart_f); subOp[0].run(xstop_f); xfibers.Add(xstart_f); Console.Write(" XFiber adaptive sample \n"); //C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created: //ORIGINAL LINE: xfiber_adaptive_sample(linespan, 0.0, 1.0, xstart_f, xstop_f); xfiber_adaptive_sample(linespan, 0.0, 1.0, new ocl.Fiber(xstart_f), new ocl.Fiber(xstop_f)); #if _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP } //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#: // #pragma omp section { // second child #else } //C++ TO C# CONVERTER TODO TASK: There is no equivalent to most C++ 'pragma' directives in C#: //#pragma omp task { // second child task #endif // _WIN32 yfibers.Clear(); Point ystart_p1 = new Point(linespan.getPoint(0.0).x, miny, zh); Point ystart_p2 = new Point(linespan.getPoint(0.0).x, maxy, zh); Point ystop_p1 = new Point(linespan.getPoint(1.0).x, miny, zh); Point ystop_p2 = new Point(linespan.getPoint(1.0).x, maxy, zh); Fiber ystart_f = new Fiber(ystart_p1, ystart_p2); Fiber ystop_f = new Fiber(ystop_p1, ystop_p2); subOp[1].run(ystart_f); subOp[1].run(ystop_f); yfibers.Add(ystart_f); Console.Write(" YFiber adaptive sample \n"); //C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created: //ORIGINAL LINE: yfiber_adaptive_sample(linespan, 0.0, 1.0, ystart_f, ystop_f); yfiber_adaptive_sample(linespan, 0.0, 1.0, new ocl.Fiber(ystart_f), new ocl.Fiber(ystop_f)); #if _WIN32 // OpenMP task not supported with the version 2 of VS2013 OpenMP } } // end omp parallel #else } } } // end omp parallel #endif // _WIN32 if (line != null) { line.Dispose(); } if (linespan != null) { linespan.Dispose(); } }
/// when horizEdgePush and shaftEdgePush fail we must call this general edge-push function. /// here we do not assume that the p1-p2 edge is oriented in a special direction //C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: virtual bool generalEdgePush(const Fiber& f, Interval& i, const Point& p1, const Point& p2) const protected virtual bool generalEdgePush(Fiber f, Interval i, Point p1, Point p2) { return(false); }
/// push cutter with given normal/center/xy_length into contact with Triangle facet // general purpose facetPush //C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: bool generalFacetPush(double normal_length, double center_height, double xy_normal_length, const Fiber& fib, Interval& i, const Triangle& t) const protected bool generalFacetPush(double normal_length, double center_height, double xy_normal_length, Fiber fib, Interval i, Triangle t) { bool result = false; Point normal = t.upNormal(); // facet surface normal, pointing up if (normal.zParallel()) // normal points in z-dir { return(result); //can't push against horizontal plane, stop here. } normal.normalize(); Point xy_normal = new Point(normal); xy_normal.z = 0; xy_normal.xyNormalize(); // find a point on the plane from which radius2*normal+radius1*xy_normal lands on the fiber+radius2*Point(0,0,1) // (u,v) locates a point on the triangle facet v0+ u*(v1-v0)+v*(v2-v0) u,v in [0,1] // t locates a point along the fiber: p1 + t*(p2-p1) t in [0,1] // // facet-point + r2 * n + r1* xy_n = fiber-point + r2*Point(0,0,1) // => // v0+ u*(v1-v0)+v*(v2-v0) + r2 * n + r1* xy_n = p1 + t*(p2-p1) + r2*Point(0,0,1) // // v0x + u*(v1x-v0x) + v*(v2x-v0x) + r2*nx + r1*xy_n.x = p1x + t*(p2x-p1x) p2x-p1x==0 for Y-fiber // v0y + u*(v1y-v0y) + v*(v2y-v0y) + r2*ny + r1*xy_n.y = p1y + t*(p2y-p1y) p2y-p1y==0 for X-fiber // v0z + u*(v1z-v0z) + v*(v2z-v0z) + r2*nz = p1z + t*(p2z-p1z) + r2 (p2z-p1z)==0 for XY-fibers!! // X-fiber: // v0x + u*(v1x-v0x) + v*(v2x-v0x) + r2*nx + r1*xy_n.x = p1x + t*(p2x-p1x) // v0y + u*(v1y-v0y) + v*(v2y-v0y) + r2*ny + r1*xy_n.y = p1y solve these two for (u,v) // v0z + u*(v1z-v0z) + v*(v2z-v0z) + r2*nz = p1z + r2 and substitute above for t // or // [ (v1y-v0y) (v2y-v0y) ] [ u ] = [ -v0y - r2*ny - r1*xy_n.y + p1y ] // [ (v1z-v0z) (v2z-v0z) ] [ v ] = [ -v0z - r2*nz + p1z + r2 ] // // Y-fiber: // [ (v1x-v0x) (v2x-v0x) ] [ u ] = [ -v0x - r2*nx - r1*xy_n.x + p1x ] double a; double b; double c = t.p[1].z - t.p[0].z; double d = t.p[2].z - t.p[0].z; double e; double f = -t.p[0].z - normal_length * normal.z + fib.p1.z + center_height; // note: the xy_normal does not have a z-component, so omitted here. double u = 0; // u and v are coordinates of the cc-point within the triangle facet double v = 0; // a,b,e depend on the fiber: if (fib.p1.y == fib.p2.y) { // XFIBER a = t.p[1].y - t.p[0].y; b = t.p[2].y - t.p[0].y; e = -t.p[0].y - normal_length * normal.y - xy_normal_length * xy_normal.y + fib.p1.y; if (!GlobalMembers.two_by_two_solver(a, b, c, d, e, f, ref u, ref v)) { return(result); } CCPoint cc = new CCPoint(t.p[0] + u * (t.p[1] - t.p[0]) + v * (t.p[2] - t.p[0])); cc.type = CCType.FACET; if (!cc.isInside(t)) { return(result); } // v0x + u*(v1x-v0x) + v*(v2x-v0x) + r2*nx + r1*xy_n.x = p1x + t*(p2x-p1x) // => // t = 1/(p2x-p1x) * ( v0x + r2*nx + r1*xy_n.x - p1x + u*(v1x-v0x) + v*(v2x-v0x) ) Debug.Assert(!GlobalMembers.isZero_tol(fib.p2.x - fib.p1.x)); // guard against division by zero double tval = (1.0 / (fib.p2.x - fib.p1.x)) * (t.p[0].x + normal_length * normal.x + xy_normal_length * xy_normal.x - fib.p1.x + u * (t.p[1].x - t.p[0].x) + v * (t.p[2].x - t.p[0].x)); if (tval < 0.0 || tval > 1.0) { Console.Write("MillingCutter::facetPush() tval= "); Console.Write(tval); Console.Write(" error!?\n"); //std::cout << " cutter: " << *this << "\n"; Console.Write(" triangle: "); Console.Write(t); Console.Write("\n"); Console.Write(" fiber: "); Console.Write(fib); Console.Write("\n"); } Debug.Assert(tval > 0.0 && tval < 1.0); i.update(tval, cc); result = true; } else if (fib.p1.x == fib.p2.x) { // YFIBER a = t.p[1].x - t.p[0].x; b = t.p[2].x - t.p[0].x; e = -t.p[0].x - normal_length * normal.x - xy_normal_length * xy_normal.x + fib.p1.x; if (!GlobalMembers.two_by_two_solver(a, b, c, d, e, f, ref u, ref v)) { return(result); } CCPoint cc = new CCPoint(t.p[0] + u * (t.p[1] - t.p[0]) + v * (t.p[2] - t.p[0])); cc.type = CCType.FACET; if (!cc.isInside(t)) { return(result); } Debug.Assert(!GlobalMembers.isZero_tol(fib.p2.y - fib.p1.y)); double tval = (1.0 / (fib.p2.y - fib.p1.y)) * (t.p[0].y + normal_length * normal.y + xy_normal_length * xy_normal.y - fib.p1.y + u * (t.p[1].y - t.p[0].y) + v * (t.p[2].y - t.p[0].y)); if (tval < 0.0 || tval > 1.0) { Console.Write("MillingCutter::facetPush() tval= "); Console.Write(tval); Console.Write(" error!?\n"); Console.Write(" (most probably a user error, the fiber is too short compared to the STL model?)\n"); } Debug.Assert(tval > 0.0 && tval < 1.0); i.update(tval, cc); result = true; } else { Debug.Assert(false); } return(result); }
/// push cutter along Fiber f into contact with facet of Triangle t, and update Interval i /// calls generalFacetPush() //C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: virtual bool facetPush(const Fiber& fib, Interval& i, const Triangle& t) const public virtual bool facetPush(Fiber fib, Interval i, Triangle t) { return(generalFacetPush(this.normal_length, this.center_height, this.xy_normal_length, fib, i, t)); }
/// add a fiber input to a push-cutter type operation public virtual void appendFiber(Fiber f) { }
/// run push-cutter type algorithm on input Fiber public virtual void run(Fiber f) { Debug.Assert(false); }