/** * checks whether two Polylines are inside one another. * * XXX It's the caller's responsibility to make sure the polylines are * coplanar. * * Returns: * 1 if the first is inside the second * -1 if the second is inside the first * 0 if the two intersect at some point or one of them isn't closed */ int PolylinePolylineInternal( ON_Polyline P, ON_Polyline Q, double tol ) { int i; for (i = 0; i < P.Count(); i++) { if (!PointInPolyline(P[i], Q, tol)) { break; } } if (i == P.Count()) { return 1; } for (i = 0; i < Q.Count(); i++) { if (!PointInPolyline(Q[i], P, tol)) { break; } } if (i == Q.Count()) { return -1; } else { return 0; } }
RH_C_FUNCTION void ON_Intersect_MeshPlanes3(ON_SimpleArray<ON_Polyline*>* pPolylines, int i, int point_count, /*ARRAY*/ON_3dPoint* points) { if( NULL==pPolylines || i<0 || i>=pPolylines->Count() || point_count<0 || NULL==points || NULL==*points) return; ON_Polyline* polyline = (*pPolylines)[i]; if( NULL==polyline || polyline->Count()!=point_count ) return; const ON_3dPoint* source = polyline->Array(); ::memcpy(points, source, sizeof(ON_3dPoint) * point_count); }
// return number of points in a certain polyline RH_C_FUNCTION int ON_Intersect_MeshPlanes2(ON_SimpleArray<ON_Polyline*>* pPolylines, int i) { int rc = 0; if( pPolylines && i>=0 && i<pPolylines->Count() ) { ON_Polyline* polyline = (*pPolylines)[i]; if( polyline ) rc = polyline->Count(); } return rc; }
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; }
void CRhinoRectangleGrips::Draw( CRhinoDrawGripsSettings& dgs ) { UpdateRectangle(); if ( m_bDrawRectangle && dgs.m_bDrawDynamicStuff ) { const int count = m_rectangle.Count(); const ON_3dPoint* P = m_rectangle.Array(); int i; for( i = 1; i < count; i++ ) dgs.m_vp.DrawLine( P[i-1],P[i] ); } CRhinoObjectGrips::Draw(dgs); }
int PolylineBBox( const ON_Polyline& pline, ON_BoundingBox* bbox ) { ON_3dPoint min = pline[0], max = pline[0]; for (int i = 1; i < pline.Count(); i++) { VMINMAX(min, max, pline[i]); } bbox->m_min = min; bbox->m_max = max; return 0; }
/** * uses iteration of SegmentSegmentIntersect. * * returns the number of intersections it finds */ int SegmentPolylineIntersect( const ON_3dPoint& P, const ON_3dPoint& Q, const ON_Polyline& pline, ON_SimpleArray<ON_3dPoint> out, double tol ) { int rv = 0; int my_rv = 0; /* what this function will return at the end */ ON_3dPoint result[2]; for (int i = 0; i < (pline.Count() - 1); i++) { rv = SegmentSegmentIntersect(P, Q, pline[i], pline[i+1], result, tol); if (out) { /* the output field can be made null to use the function to check for intersections but not return them */ for (int j = 0; j < rv; j++) { out.Append(result[j]); } } my_rv += rv; } return my_rv; }
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; }