bool PointInPolyline( const ON_3dPoint& P, const ON_Polyline pline, double tol ) { if (!pline.IsClosed(tol)) { /* no inside to speak of */ return false; } /* First we need to find a point that's in the plane and outside the polyline */ ON_BoundingBox bbox; PolylineBBox(pline, &bbox); ON_3dPoint adder; int i; for (i = 0; i < pline.Count(); i++) { adder = P - pline[i]; if (!VNEAR_ZERO(adder, tol)) { break; } } ON_3dPoint DistantPoint = P; int multiplier = 2; do { DistantPoint += adder*multiplier; multiplier = multiplier*multiplier; } while (bbox.IsPointIn(DistantPoint, false)); bool inside = false; int rv; ON_3dPoint result[2]; for (i = 0; i < pline.Count() - 1; i++) { rv = SegmentSegmentIntersect(P, DistantPoint, pline[i], pline[i + 1], result, tol); if (rv == 1) { inside = !inside; } else if (rv == 2) { bu_exit(-1, "This is very unlikely bug in PointInPolyline which needs to be fixed\n"); } } return inside; }
int TriIntersections::Faces( ON_ClassArray<ON_3dPoint[3]> UNUSED(faces) ) { if (intersections.Count() == 0) { return 0; } /* first we get an array of all the segments we can use to make * our faces. */ ON_SimpleArray<ON_Line> segments; /*the segments we have to make faces */ ON_SimpleArray<bool> flippable; /* whether or not the segment has direction */ ON_SimpleArray<bool> segexternal; /* whether or not the segment is from the edge */ for (int i = 0; i < intersections.Count(); i++) { segments.Append(intersections[i]); segments.Append(intersections[i]); flippable.Append(false); flippable.Append(false); segexternal.Append(false); segexternal.Append(false); } for (int i = 0; i < 3; i++) { if (edges[i].Count() == 2) { /* the edge was never intersected */ segments.Append(ON_Line(edges[i][0], edges[i][0])); flippable.Append(true); segexternal.Append(true); } else { for (int j = 0; j < (edges[i].Count() - 1); j++) { if (dir[i][j] == dir[i][j + 1]) { /* this indicates an error in the intersection data */ return -1; } else if (dir[i][j] == 0 || dir[i][j+1] == 1) { segments.Append(ON_Line(edges[i][j], edges[i][j+1])); flippable.Append(false); segexternal.Append(true); } else { segments.Append(ON_Line(edges[i][j+1], edges[i][j])); flippable.Append(false); segexternal.Append(true); } } } } /* Now that the segments are all set up it's time to make them * into faces. */ ON_ClassArray<ON_Polyline> outlines; ON_SimpleArray<bool> line_external; /* stores whether each polyline is internal */ ON_Polyline outline; while (segments.Count() != 0) { outline.Append(segments[0].from); outline.Append(segments[0].to); segments.Remove(0); int i = 0; bool ext = false; /* keeps track of the ternality of the path we're assembling */ while (!outline.IsClosed(tol)) { if (i >= segments.Count()) { return -1; } else if (VNEAR_EQUAL(segments[i].from, outline[outline.Count() - 1], tol)) { outline.Append(segments[i].to); } else if (VNEAR_EQUAL(segments[i].to, outline[0], tol)) { outline.Insert(0, segments[i].from); } else if (VNEAR_EQUAL(segments[i].from, outline[0], tol) && flippable[i]) { outline.Insert(0, segments[i].to); } else if (VNEAR_EQUAL(segments[i].to, outline[outline.Count() - 1], tol) && flippable[i]) { outline.Append(segments[i].from); } else { i++; continue; } /* only executed when we append edge i */ segments.Remove(i); flippable.Remove(i); ext &= segexternal[i]; segexternal.Remove(i); i = 0; } outlines.Append(outline); line_external.Append(ext); } /* XXX - now we need to setup the ternality tree for the paths */ return 0; }