コード例 #1
0
/**
 * 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;
    }
}
コード例 #2
0
CRhinoCommand::result CCommandSamplePolyline::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoCommand::result rc = CRhinoCommand::nothing;
  ON_Polyline pline;

  if( context.IsInteractive() )
  {
    // Our way...
	  CGetPolylinePoints gp;
    int count = gp.GetPoints();
    if( count > 1 )
    {
      pline = gp.m_point_array;
      if( pline.IsValid() )
        rc = CRhinoCommand::success;
    }
  }
  else
  {
    // The Rhino way...
    CArgsRhinoGetPolyline args;
    args.SetFirstPointPrompt( L"Start of polyline" );
    args.SetSecondPointPrompt( L"Next point of polyline" );
    rc = RhinoGetPolyline( args, pline );
  }

  if( rc == CRhinoCommand::success )
  {
    context.m_doc.AddCurveObject( pline );
    context.m_doc.Redraw();
  }

	return rc;
}
コード例 #3
0
CRhinoCommand::result CCommandTestCustomGrips::RunCommand( const CRhinoCommandContext& context )
{
  ON_3dPoint rect[5];
  
  CArgsRhinoGetPlane args;
  args.SetCornerMode( CArgsRhinoGetPlane::mode_corners );
  args.SetAllowRounded( FALSE );
  args.SetAllowDeformable( FALSE );
 
  CRhinoCommand::result rc = RhinoGetRectangle( args, rect );
  
  if( rc == CRhinoCommand::success)
  {
    ON_Polyline pline;
    rect[4] = rect[0];
    pline.Create( 3, FALSE, 5, 3, (double*)&rect );

    ON_PolylineCurve* pline_curve = new ON_PolylineCurve( pline );
    
    CRhinoRectangleObject* rect_object = new CRhinoRectangleObject();
    rect_object->SetCurve( pline_curve );

    if( context.m_doc.AddObject(rect_object) )
      context.m_doc.Redraw();
    else
      delete rect_object;
  }

  return CRhinoCommand::success;
}
コード例 #4
0
CRhinoCommand::result CCommandSampleTriangulatePolygon::RunCommand( const CRhinoCommandContext& context )
{
  CRhinoGetObject go;
  go.SetCommandPrompt( L"Select closed planar polygon to triangulate" );
  go.SetGeometryFilter( CRhinoGetObject::curve_object );
  go.SetGeometryFilter( CRhinoGetObject::closed_curve );
  go.EnableSubObjectSelect( FALSE );
  go.GetObjects( 1, 1 );
  if( go.CommandResult() != CRhinoCommand::success )
    return go.CommandResult();

  const CRhinoObjRef& ref = go.Object(0);

  ON_3dPointArray vertices;

  const ON_PolylineCurve* pc = ON_PolylineCurve::Cast( ref.Curve() );
  if( pc )
  {
    vertices = pc->m_pline;
  }
  else
  {
    const ON_NurbsCurve* nc = ON_NurbsCurve::Cast( ref.Curve() );
    if( nc )
      nc->IsPolyline( &vertices );
  }

  if( vertices.Count() < 5 )
  {
    RhinoApp().Print( L"Curve not polygon with at least four sides.\n" );
    return CRhinoCommand::nothing;
  }

  int* triangles = (int*)onmalloc( (vertices.Count()-3) * sizeof(int) * 3 );
  if( 0 == triangles )
    return CRhinoCommand::failure; // out of memory
  
  memset( triangles, 0, (vertices.Count()-3) * sizeof(int) * 3 );

  int rc = RhinoTriangulate3dPolygon( vertices.Count()-1, 3, (const double*)vertices.Array(), 3, triangles);
  if( 0 == rc )
  {
    int i;
    for( i = 0; i < vertices.Count()-3; i++ )
    {
      ON_Polyline pline;
      pline.Append( vertices[triangles[i * 3]] );
      pline.Append( vertices[triangles[i * 3 + 1]] );
      pline.Append( vertices[triangles[i * 3 + 2]] );
      pline.Append( pline[0] );
      context.m_doc.AddCurveObject( pline );
    }
    context.m_doc.Redraw();
  }

  onfree( triangles );

  return CRhinoCommand::success;
}
コード例 #5
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);
}
コード例 #6
0
// 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;
}
コード例 #7
0
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);
}
コード例 #8
0
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;
}
コード例 #9
0
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;
}
コード例 #10
0
RH_C_FUNCTION ON_SimpleArray<ON_Polyline*>* ON_Intersect_MeshMesh1(const ON_Mesh* pConstMeshA, const ON_Mesh* pConstMeshB, int* polyline_count, double tolerance)
{
  ON_SimpleArray<ON_Polyline*>* rc = NULL;
  if( polyline_count ) *polyline_count = 0;
  if( pConstMeshA && pConstMeshB && polyline_count )
  {
    ON_ClassArray<ON_MMX_Polyline> plines;
    ON_ClassArray<ON_MMX_Polyline> overlapplines;
    if(::ON_MeshMeshIntersect(pConstMeshA, pConstMeshB, plines, overlapplines, tolerance, tolerance))
    {
      rc = new ON_SimpleArray<ON_Polyline*>();
      for( int i=0; i<plines.Count(); i++ )
      {
        ON_Polyline* pl = new ON_Polyline();
        const ON_MMX_Polyline& mmxpoly = plines[i];
        int c = mmxpoly.Count();
        for( int j=0; j<c; j++ )
          pl->Append(mmxpoly[j].m_A.m_P);
        pl->Clean(ON_ZERO_TOLERANCE);
        if( !pl->IsValid() )
        {
          delete pl;
          continue;
        }
        rc->Append(pl);
      }
      for( int i=0; i<overlapplines.Count(); i++ )
      {
        ON_Polyline* pl = new ON_Polyline();
        const ON_MMX_Polyline& mmxpoly = overlapplines[i];
        int c = mmxpoly.Count();
        for( int j=0; i<c; i++ )
          pl->Append(mmxpoly[j].m_A.m_P);
        pl->Clean(ON_ZERO_TOLERANCE);
        if( !pl->IsValid() )
        {
          delete pl;
          continue;
        }
        rc->Append(pl);
      }
      *polyline_count = rc->Count();
    }
  }
  return rc;
}
コード例 #11
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;
}
コード例 #12
0
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;
}
コード例 #13
0
void CRhinoRectangleGrips::UpdateRectangle()
{
  if ( m_bNewLocation )
  {
    // Update rectangle from grip locations
    int i;
    m_rectangle.Reserve(5);
    m_rectangle.SetCount(5);

    // If anything moved this time, the ones that didn't move will
    // be inactive for the rest of the drag
    for ( i = 0; i < 8; i++ )
    {
      if ( m_rectangle_grips[i].m_bActive && m_rectangle_grips[i].GripMoved() )
      {
        for ( i = 0; i < 8; i++ )
        {
          if ( !m_rectangle_grips[i].GripMoved() )
            m_rectangle_grips[i].m_bActive = false;
        }        
        break;
      }
    }

    // first check corners
    for ( i = 0; i < 8; i += 2 )
    {
      if ( m_rectangle_grips[i].m_bActive && m_rectangle_grips[i].GripMoved() )
      {
        // if corner moves, middles are inactive for this drag
        m_rectangle_grips[(i+1)%8].m_bActive = false;
        m_rectangle_grips[(i+7)%8].m_bActive = false;
      }
    }

    // second check middles
    for ( i = 1; i < 8; i += 2 )
    {
      if ( m_rectangle_grips[i].m_bActive && m_rectangle_grips[i].GripMoved() )
      {
        // if middle moves, corners are inactive for this drag
        m_rectangle_grips[(i+1)%8].m_bActive = false;
        m_rectangle_grips[(i+7)%8].m_bActive = false;
      }
    }

    // 
    double x0 = m_rectangle[0].x;
    if ( m_rectangle_grips[0].m_bActive && m_rectangle_grips[0].GripMoved() )
      x0 = m_rectangle_grips[0].GripLocation().x;
    else if ( m_rectangle_grips[6].m_bActive && m_rectangle_grips[6].GripMoved() )
      x0 = m_rectangle_grips[6].GripLocation().x;
    else if ( m_rectangle_grips[7].m_bActive && m_rectangle_grips[7].GripMoved() )
      x0 = m_rectangle_grips[7].GripLocation().x;

    double x1 = m_rectangle[2].x;
    if ( m_rectangle_grips[4].m_bActive && m_rectangle_grips[4].GripMoved() )
      x1 = m_rectangle_grips[4].GripLocation().x;
    else if ( m_rectangle_grips[2].m_bActive && m_rectangle_grips[2].GripMoved() )
      x1 = m_rectangle_grips[2].GripLocation().x;
    else if ( m_rectangle_grips[3].m_bActive && m_rectangle_grips[3].GripMoved() )
      x1 = m_rectangle_grips[3].GripLocation().x;

    double y0 = m_rectangle[0].y;
    if ( m_rectangle_grips[0].m_bActive && m_rectangle_grips[0].GripMoved() )
      y0 = m_rectangle_grips[0].GripLocation().y;
    else if ( m_rectangle_grips[2].m_bActive && m_rectangle_grips[2].GripMoved() )
      y0 = m_rectangle_grips[2].GripLocation().y;
    else if ( m_rectangle_grips[1].m_bActive && m_rectangle_grips[1].GripMoved() )
      y0 = m_rectangle_grips[1].GripLocation().y;

    double y1 = m_rectangle[2].y;
    if ( m_rectangle_grips[4].m_bActive && m_rectangle_grips[4].GripMoved() )
      y1 = m_rectangle_grips[4].GripLocation().y;
    else if ( m_rectangle_grips[6].m_bActive && m_rectangle_grips[6].GripMoved() )
      y1 = m_rectangle_grips[6].GripLocation().y;
    else if ( m_rectangle_grips[5].m_bActive && m_rectangle_grips[5].GripMoved() )
      y1 = m_rectangle_grips[5].GripLocation().y;

    m_rectangle[0].x = m_rectangle[3].x = x0;
    m_rectangle[1].x = m_rectangle[2].x = x1;
    m_rectangle[0].y = m_rectangle[1].y = y0;
    m_rectangle[2].y = m_rectangle[3].y = y1;

    m_rectangle[4] = m_rectangle[0];

    // apply rectangular constraints to grip locations
    ON_Line L;
    for ( i = 0; i < 4; i++ )
    {
      int gi = 2*i;
      L.from = m_rectangle[i];
      L.to = m_rectangle[i+1];
      m_rectangle_grips[gi].SetPoint( L.from );
      m_rectangle_grips[gi+1].SetPoint( 0.5*L.from + 0.5*L.to );
    }

    m_bDrawRectangle = true;
    m_bNewLocation = false;
  }
}