/*
Description:
  Selects point cloud points using a 2D selection region.
Parameters:
  view     - [in]  The view in which the selection region was defined.
  cloud    - [in]  The point cloud to test.
  points3d - [in]  The 2D (screen) points that define the selection region.
  indices  - [out] The indices of the points in the point cloud
                   that lie inside of the selection region.
Returns:
  The number of indices added to the output array.
*/
static int RhRegionSelectPointCloudPoints(
    CRhinoView* view,
    const ON_PointCloud& cloud,
    ON_SimpleArray<CPoint>& points2d,
    ON_SimpleArray<int>& indices
)
{
    if( 0 == view )
        return 0;

    const int index_count = indices.Count();

    CRgn rgn;
    if( rgn.CreatePolygonRgn(points2d.Array(), points2d.Count(), WINDING) )
    {
        ON_Xform w2s;
        view->ActiveViewport().VP().GetXform( ON::world_cs, ON::screen_cs, w2s );

        int i;
        ON_3dPoint point;

        for( i = 0; i < cloud.m_P.Count(); i++ )
        {
            point = cloud.m_P[i];
            point.Transform( w2s );
            if( rgn.PtInRegion((int)point.x, (int)point.y) )
                indices.Append( i );
        }
    }

    return indices.Count() - index_count;
}
Ejemplo n.º 2
0
static void DumpDistanceABHelper( ON_TextLog& text_log, ON_3dPoint A0, ON_3dPoint B0, ON_3dPoint A1, ON_3dPoint B1 )
{
  if ( A0.DistanceTo(B0) <= A1.DistanceTo(B0) )
    DumpDistanceABHelper( text_log, A0, B0 );
  else
    DumpDistanceABHelper( text_log, A1, B1 );
}
bool ON_BezierCageMorph::Create(
    ON_3dPoint P0,
    ON_3dPoint P1,
    ON_3dPoint P2,
    ON_3dPoint P3,
    int point_countX,
    int point_countY,
    int point_countZ
    )
{
  if ( point_countX < 2 || point_countY < 2 || point_countZ < 2 
      || !P0.IsValid()
      || !P1.IsValid()
      || !P2.IsValid()
      || !P3.IsValid() )
  {
    ON_ERROR("ON_BezierCageMorph::Create - invalid input");
  }

  m_bValid = false;
  ON_3dVector X = P1-P0;
  ON_3dVector Y = P2-P0;
  ON_3dVector Z = P3-P0;
  ON_Xform xform(1.0);
  xform[0][0] = X.x;
  xform[1][0] = X.y;
  xform[2][0] = X.z;
  xform[0][1] = Y.x;
  xform[1][1] = Y.y;
  xform[2][1] = Y.z;
  xform[0][2] = Z.x;
  xform[1][2] = Z.y;
  xform[2][2] = Z.z;
  xform[0][3] = P0.x;
  xform[1][3] = P0.y;
  xform[2][3] = P0.z;
  double min_pivot = 0.0;
  m_bValid = xform.Invert(&min_pivot);
  if (m_bValid)
  {
    ON_3dPoint box_corners[8];
    box_corners[0] = P0;
    box_corners[1] = P1;
    box_corners[2] = P0+X+Y;
    box_corners[3] = P2;
    box_corners[4] = P3;
    box_corners[5] = P3+X;
    box_corners[6] = P3+X+Y;
    box_corners[7] = P3+Y;
    m_bValid = m_rst2xyz.Create(box_corners,point_countX,point_countY,point_countZ);
    m_xyz2rst = xform;
  }
  else
  {
    ON_ERROR("ON_BezierCageMorph::Create - invalid input - P0,P1,P2,P3 are coplanar");
    m_rst2xyz.Destroy();
  }
  return m_bValid;
}
Ejemplo n.º 4
0
/**
 * \return Point on spline at given position t (0..1).
 */
RVector RSpline::getPointAt(double t) const {
    updateInternal();
#ifndef R_NO_OPENNURBS
    ON_3dPoint p = curve.PointAt(t);
    if (p.IsUnsetPoint()) {
        return RVector::invalid;
    }
    return RVector(p.x, p.y);
#else
    return RVector::invalid;
#endif
}
ON_2dPoint
BBNode::getClosestPointEstimate(const ON_3dPoint &pt, ON_Interval &u, ON_Interval &v)
{
    if (isLeaf()) {
	double uvs[5][2] = {{m_u.Min(), m_v.Min()}, {m_u.Max(), m_v.Min()},
	    {m_u.Max(), m_v.Max()}, {m_u.Min(), m_v.Max()},
	    {m_u.Mid(), m_v.Mid()}
	}; /* include the estimate */
	ON_3dPoint corners[5];
	const ON_Surface *surf = m_face->SurfaceOf();

	u = m_u;
	v = m_v;

	/* ??? pass these in from SurfaceTree::surfaceBBox() to avoid
	 * this recalculation?
	 */
	if (!surf->EvPoint(uvs[0][0], uvs[0][1], corners[0]) ||
	    !surf->EvPoint(uvs[1][0], uvs[1][1], corners[1]) ||
	    !surf->EvPoint(uvs[2][0], uvs[2][1], corners[2]) ||
	    !surf->EvPoint(uvs[3][0], uvs[3][1], corners[3]))
	{
	    throw new std::exception(); /* FIXME */
	}
	corners[4] = BBNode::m_estimate;

	/* find the point on the surface closest to pt */
	size_t mini = 0;
	double mindist = pt.DistanceTo(corners[mini]);
	double tmpdist;
	for (size_t i = 1; i < 5; i++) {
	    tmpdist = pt.DistanceTo(corners[i]);
	    TRACE("\t" << mindist << " < " << tmpdist);
	    if (tmpdist < mindist) {
		mini = i;
		mindist = tmpdist;
	    }
	}
	TRACE("Closest: " << mindist << "; " << PT2(uvs[mini]));
	return ON_2dPoint(uvs[mini][0], uvs[mini][1]);
    } else {
	if (m_children.size() > 0) {
	    BBNode *closestNode = m_children[0];
	    for (size_t i = 1; i < m_children.size(); i++) {
		closestNode = closer(pt, closestNode, m_children[i]);
		TRACE("\t" << PT(closestNode->m_estimate));
	    }
	    return closestNode->getClosestPointEstimate(pt, u, v);
	}
	throw new std::exception();
    }
}
Ejemplo n.º 6
0
double ON_Localizer::Value(ON_3dPoint P) const
{
  double v,s,t = m_d.m_t[1];

  switch ( m_type )
  {
  case cylinder_type:
    // t = distance from P to axis
    t = ON_CrossProduct( P-m_P, m_V ).Length();
    break;

  case plane_type:
    // t = distance above plane
    t = m_V.x*P.x + m_V.y*P.y + m_V.z*P.z + m_P.x;
    break;

  case sphere_type:
    // t = distance to P
    t = (P-m_P).Length();
    break;

  case curve_type:
    if ( !m_nurbs_curve )
      return 1.0;
    if ( !m_nurbs_curve->GetClosestPoint(P,&v) )
      return 1.0;
    t = P.DistanceTo(m_nurbs_curve->PointAt(v));
    break;

  case surface_type:
    if ( !m_nurbs_surface )
      return 1.0;
    if ( !m_nurbs_surface->GetClosestPoint(P,&s,&v) )
      return 1.0;
    t = P.DistanceTo(m_nurbs_surface->PointAt(s,v));
    break;

  case distance_type:
    // confused user should be calling Value(double)
    return 1.0; // default must be one
    break;

  default:
    return 1.0; // default must be one
  }

  return Value(t);
}
Ejemplo n.º 7
0
ON_BOOL32 ON_ArcCurve::SetEndPoint(ON_3dPoint end_point)
{
  if (IsCircle())
    return false;
  ON_BOOL32 rc = false;
  if ( m_dim == 3 || end_point.z == 0.0 )
  {
    ON_3dPoint P;
    ON_3dVector T;
    double t = Domain()[0];
    Ev1Der( t, P, T );
    ON_Arc a;
    rc = a.Create( P, T, end_point );
    if ( rc )
    {
      m_arc = a;
    }
    else {
      ON_3dPoint start_point = PointAt(Domain()[0]);
      if (end_point.DistanceTo(start_point) < ON_ZERO_TOLERANCE*m_arc.Radius()){
        //make arc into circle
        m_arc.plane.xaxis = start_point - m_arc.Center();
        m_arc.plane.xaxis.Unitize();
        m_arc.plane.yaxis = ON_CrossProduct(m_arc.Normal(), m_arc.plane.xaxis);
        m_arc.plane.yaxis.Unitize();
        m_arc.SetAngleRadians(2.0*ON_PI);
        rc = true;
      }
    }
  }
  return rc;  
}
Ejemplo n.º 8
0
ON_BOOL32 ON_LineCurve::Trim( const ON_Interval& domain )
{
  ON_BOOL32 rc = false;
  if ( domain.IsIncreasing() )
  {
    ON_3dPoint p = PointAt( domain[0] );
    ON_3dPoint q = PointAt( domain[1] );
		if( p.DistanceTo(q)>0){								// 2 April 2003 Greg Arden A successfull trim 
																					// should return an IsValid ON_LineCurve .
			m_line.from = p;
			m_line.to = q;
			m_t = domain;
			rc = true;
		}
  }
  return rc;
}
Ejemplo n.º 9
0
bool ON_Polyline::ClosestPointTo( const ON_3dPoint& point, double *t, int segment_index0, int segment_index1 ) const
{
    bool rc = false;
    int segment_index;
    double segment_t, segment_d, best_t, best_d;
    best_t = 0.0; // to keep lint quiet
    best_d = 0.0; // to keep lint quiet
    if ( t ) {
        if ( segment_index0 < 0 )
            segment_index0 = 0;
        if ( segment_index1 > SegmentCount() )
            segment_index1 = SegmentCount();
        for ( segment_index = segment_index0; segment_index < segment_index1; segment_index++ ) {
            double seg_length = m_a[segment_index].DistanceTo(m_a[segment_index + 1]);
            if (seg_length < ON_EPSILON)
                segment_t = 0.0;
            else {
                const ON_3dVector D = SegmentTangent(segment_index);
                const int i = ( point.DistanceTo(m_a[segment_index]) <= point.DistanceTo(m_a[segment_index+1]) ) ? 0 : 1;
                segment_t = (point - m_a[segment_index+i])*D/seg_length;
                if ( i ) {
                    segment_t = 1.0 + segment_t;
                }
                if ( segment_t < 0.0 )
                    segment_t = 0.0;
                else if (segment_t > 1.0 )
                    segment_t = 1.0;
            }
            segment_d = point.DistanceTo((1-segment_t)*m_a[segment_index] + segment_t*m_a[segment_index+1]);
            if ( !rc || segment_d < best_d )
            {
                best_t = segment_t + ((double)segment_index);
                best_d = segment_d;
            }
            rc = true;
        }
    }
    if (rc)
        *t = best_t;
    return rc;
}
Ejemplo n.º 10
0
bool ON_Line::ClosestPointTo( const ON_3dPoint& point, double *t ) const
{
  bool rc = false;
  if ( t ) {
    const ON_3dVector D = Direction();
    const double DoD = D.LengthSquared();
    if ( DoD > 0.0 ) {
      if ( point.DistanceTo(from) <= point.DistanceTo(to) ) {
        *t = ((point - from)*D)/DoD;
      }
      else {
        *t = 1.0 + ((point - to)*D)/DoD;
      }
      rc = true;
    }
    else {
      *t = 0.0;
    }
  }
  return rc;
}
Ejemplo n.º 11
0
bool ON_PlaneSurface::GetClosestPoint( const ON_3dPoint& test_point,
        double* s,double* t,  // parameters of local closest point returned here
        double maximum_distance,
        const ON_Interval* sdomain, // first parameter sub_domain
        const ON_Interval* tdomain  // second parameter sub_domain
        ) const
{
  double u = 0.0, v=0.0;

	ON_Interval sdom = Domain(0);
	ON_Interval tdom = Domain(1);
	if(sdomain==NULL)
		sdomain = &sdom;
	if(tdomain==NULL)
		tdomain = &tdom;

  bool rc = m_plane.ClosestPointTo( test_point, &u, &v );
  if ( rc ) 
  {
    // convert m_plane coordinates to ON_Surface coordinates
    if ( m_domain[0] != m_extents[0] )
    {
      u = m_domain[0].ParameterAt( m_extents[0].NormalizedParameterAt(u) );
    }
    if ( m_domain[1] != m_extents[1] )
    {
      v = m_domain[1].ParameterAt( m_extents[1].NormalizedParameterAt(v) );
    }

    if ( u < sdomain->Min() )
      u = sdomain->Min();
    else if ( u > sdomain->Max() )
      u = sdomain->Max();

    if ( v < tdomain->Min() )
      v = tdomain->Min();
    else if ( v > tdomain->Max() )
      v = tdomain->Max();

    if ( s )
      *s = u;
    if ( t )
      *t = v;
    if (maximum_distance > 0.0) 
    {
      ON_3dPoint pt = PointAt(u,v);
      if ( test_point.DistanceTo(pt) > maximum_distance )
        rc = false;
    }
  }
  return rc;
}
Ejemplo n.º 12
0
static
ON_NurbsSurface* ON_BrepExtrudeHelper_MakeConeSrf( const ON_3dPoint& apex_point,
                                                 const ON_BrepEdge& edge, ON_BOOL32 bRev )
{
  // The "s" parameter runs along the edge.
  // The "t" parameter is the ruling parameter;
  // t=0 is at the base_edge and t=max is at the apex.
  //   surface side    location
  //     south           base_edge
  //     east            line from bRev?START:END of edge to apex
  //     north           singular side at apex
  //     west            line from bRev?END:START of edge to apex.
  ON_NurbsSurface* cone_srf = new ON_NurbsSurface();
  if ( cone_srf->CreateConeSurface( apex_point, edge ) )
  {
    if ( bRev )
      cone_srf->Reverse(0);
    // get a decent interval for the ruling parameter
    double d = 0.0;
    ON_Interval edom = edge.Domain();
    ON_3dPoint pt;
    int i, hint=0;
    for ( i = 0; i <= 16; i++ )
    {
      if ( !edge.EvPoint( edom.ParameterAt(i/16.0), pt, 0, &hint ) )
        continue;
      if ( pt.DistanceTo(apex_point) > d )
        d = pt.DistanceTo(apex_point);
    }
    if ( d > ON_SQRT_EPSILON )
      cone_srf->SetDomain(1,0.0,d);
  }
  else
  {
    delete cone_srf;
    cone_srf = 0;
  }
  return cone_srf;
}
Ejemplo n.º 13
0
int CGetPolylinePoints::GetPoints()
{
  m_point_array.Empty();

  SetCommandPrompt( L"Start of polyline" );
  AcceptNothing();

  CRhinoGet::result res = GetPoint();

  if( res == CRhinoGet::point )
  {
    m_point_array.Append( Point() );

    SetCommandPrompt( L"Next point of polyline" );

    for( ;; )
    {
      SetBasePoint( Point() );

      res = GetPoint();

      if( res == CRhinoGet::point )
      {
        ON_3dPoint pt = Point();
        if( pt.DistanceTo(m_point_array[m_point_array.Count()-1]) > ON_ZERO_TOLERANCE )
          m_point_array.Append( Point() );
        continue;
      }

      if( res == CRhinoGet::nothing )
        break;

      return 0;
    }
  }

  return m_point_array.Count();
}
Ejemplo n.º 14
0
ON_BOOL32 ON_LineCurve::GetLocalClosestPoint( const ON_3dPoint& test_point,
        double seed_parameter,
        double* t,
        const ON_Interval* sub_domain
        ) const
{
  if ( sub_domain )
  {
    if ( seed_parameter < sub_domain->Min() )
      seed_parameter = sub_domain->Min();
    else if ( seed_parameter > sub_domain->Max() )
      seed_parameter = sub_domain->Max();
  }
  ON_BOOL32 rc = GetClosestPoint( test_point, t, 0.0, sub_domain );
  if ( rc 
       && t 
       && seed_parameter != *t
       && test_point.DistanceTo(PointAt(seed_parameter)) <= test_point.DistanceTo(PointAt(*t)) 
       )
  {
    *t = seed_parameter;
  }
  return rc;
}
Ejemplo n.º 15
0
bool ON_Localizer::CreateSphereLocalizer( ON_3dPoint P, double r0, double r1 )
{
  Destroy();
  if ( P.IsValid()
       && ON_IsValid(r0)
       && ON_IsValid(r1)
       && r0 > 0.0
       && r1 > 0.0
       && r0 != r1 )
  {
    m_P = P;
    m_V.Zero();
    m_d.Set(r0,r1);
    m_type = sphere_type;
  }
  return (sphere_type == m_type);
}
Ejemplo n.º 16
0
bool ON_GetClosestPointInPointList( 
          int point_count,
          const ON_3dPoint* point_list,
          ON_3dPoint P,
          int* closest_point_index
          )
{
  bool rc = false;
  if ( point_count>0 && 0 != point_list && closest_point_index )
  {
    double d = 1.0e300;
    double d2 = 1.0e300;
    double x,e;
    int i;
    int best_i = -1;
    //const double* pl = &point_list[0].x;
    for ( i = point_count; i--; point_list++ )
    {
      e = d2;
      x = point_list->x - P.x;
      e = x*x;
      if ( e >= d2 ) continue;
      x = point_list->y - P.y;
      e += x*x;
      if ( e >= d2 ) continue;
      x = point_list->z - P.z;
      e += x*x;
      if ( e >= d2 ) continue;
      d2 = (1.0+ON_SQRT_EPSILON)*e;
      e = P.DistanceTo(*point_list);
      if ( e < d )
      {
        d = e;
        best_i = point_count-i-1;
      }
    }
    if ( best_i >= 0 )
    {
      if ( closest_point_index )
        *closest_point_index = best_i;
      rc = true;
    }
  }
  return rc;
}
Ejemplo n.º 17
0
static void DumpDistanceABHelper( ON_TextLog& text_log, ON_3dPoint A, ON_3dPoint B )
{
  const double tinyd = 1.0e-14;
  double d = A.DistanceTo(B);
  text_log.Print("distance A to B");
  if ( !ON_IsValid(d) || d >= 1.0e-14 || d <= 0.0 )
  {
    text_log.Print(" = ");
  }
  else
  {
    // This prevents diff from compaining about tiny changes.
    text_log.Print(" < ");
    d = tinyd;
  }
  text_log.Print(d);
  text_log.Print("\n");
}
Ejemplo n.º 18
0
bool ON_Localizer::CreatePlaneLocalizer( ON_3dPoint P, ON_3dVector N, double h0, double h1 )
{
  Destroy();
  if ( P.IsValid()
       && N.IsValid()
       && N.Length() > 0.0
       && ON_IsValid(h0)
       && ON_IsValid(h1)
       && h0 != h1 )
  {
    m_V = N;
    m_V.Unitize();
    m_P.Set( -(m_V.x*P.x + m_V.y*P.y + m_V.z*P.z), 0.0, 0.0 );
    m_d.Set(h0,h1);
    m_type = plane_type;
  }
  return (plane_type == m_type);
}
Ejemplo n.º 19
0
int ON_Intersect( // returns 0 = no intersections, 
                  // 1 = one intersection, 
                  // 2 = 2 intersections
                  // If 0 is returned, first point is point 
                  // on line closest to sphere and 2nd point is the point
                  // on the sphere closest to the line.
                  // If 1 is returned, first point is obtained by evaluating
                  // the line and the second point is obtained by evaluating
                  // the sphere.
                 const ON_Line& line, const ON_Sphere& sphere,
                  ON_3dPoint& A, ON_3dPoint& B // intersection point(s) returned here
                  )
{
  int rc = 0;
  const ON_3dPoint sphere_center = sphere.plane.origin;
  const double sphere_radius = fabs(sphere.radius);
  double tol = sphere_radius*ON_SQRT_EPSILON;
  if ( tol < ON_ZERO_TOLERANCE )
    tol = ON_ZERO_TOLERANCE;
  ON_3dPoint line_center = line.ClosestPointTo(sphere_center);
  double d = line_center.DistanceTo(sphere_center);
  if ( d >= sphere_radius-tol ) {
    rc = ( d <= sphere_radius-tol ) ? 1 : 0;
    A = line_center;
    B = sphere.ClosestPointTo(line_center);
  }
  else {
    d /= sphere_radius;
    double h = sphere_radius*sqrt(1.0 - d*d);
    ON_3dVector V = line.Direction();
    V.Unitize();
    A = sphere.ClosestPointTo(line_center - h*V);
    B = sphere.ClosestPointTo(line_center + h*V);
    d = A.DistanceTo(B);
    if ( d <= ON_ZERO_TOLERANCE ) {
      A = line_center;
      B = sphere.ClosestPointTo(line_center);
      rc = 1;
    }
    else
      rc = 2;
  }
  return rc;
}
Ejemplo n.º 20
0
bool ON_Localizer::CreateCylinderLocalizer( ON_3dPoint P, ON_3dVector V, double r0, double r1 )
{
  Destroy();
  if (    P.IsValid() 
       && V.IsValid() 
       && V.Length() > 0.0 
       && ON_IsValid(r0) 
       && ON_IsValid(r1) 
       && r0 > 0.0
       && r1 > 0.0
       && r0 != r1 )
  {
    m_P = P;
    m_V = V;
    m_V.Unitize();
    m_d.Set(r0,r1);
    m_type = cylinder_type;
  }
  return (cylinder_type == m_type);
}
Ejemplo n.º 21
0
bool ON_3dPointArray::GetClosestPoint( 
          ON_3dPoint P,
          int* closest_point_index,
          double maximum_distance
          ) const
{
  int i;

  bool rc = ON_GetClosestPointInPointList( m_count, m_a , P, &i );

  if (rc)
  {
    if ( maximum_distance > 0.0 && P.DistanceTo(m_a[i]) > maximum_distance )
    {
      rc = false;
    }
    else if ( closest_point_index )
    {
      *closest_point_index = i;
    }
  }

  return rc;
}
Ejemplo n.º 22
0
int ON_Intersect( // returns 0 = no intersections, 
                  // 1 = one intersection, 
                  // 2 = 2 intersections
                  // 3 = line lies on cylinder
                  // If 0 is returned, first point is point 
                  // on line closest to cylinder and 2nd point is the point
                  // on the sphere closest to the line.
                  // If 1 is returned, first point is obtained by evaluating
                  // the line and the second point is obtained by evaluating
                  // the cylinder.
                  const ON_Line& line, 
                  const ON_Cylinder& cylinder, // if cylinder.height[0]==cylinder.height[1],
                                               // then infinite cyl is used.  Otherwise
                                               // finite cyl is used.
                  ON_3dPoint& A, ON_3dPoint& B // intersection point(s) returned here
                  )
{
  ON_BOOL32 bFiniteCyl = true;
  int rc = 0;
  const double cylinder_radius = fabs(cylinder.circle.radius);
  double tol = cylinder_radius*ON_SQRT_EPSILON;
  if ( tol < ON_ZERO_TOLERANCE )
    tol = ON_ZERO_TOLERANCE;

  ON_Line axis;
  axis.from = cylinder.circle.plane.origin + cylinder.height[0]*cylinder.circle.plane.zaxis;
  axis.to   = cylinder.circle.plane.origin + cylinder.height[1]*cylinder.circle.plane.zaxis;
  if ( axis.Length() <= tol ) {
    axis.to = cylinder.circle.plane.origin + cylinder.circle.plane.zaxis;
    bFiniteCyl = false;
  }


  //ON_BOOL32 bIsParallel = false;
  double line_t, axis_t;
  if ( !ON_Intersect(line,axis,&line_t,&axis_t) ) {
    axis.ClosestPointTo( cylinder.circle.plane.origin, &axis_t );
    line.ClosestPointTo( cylinder.circle.plane.origin, &line_t );
  }
  ON_3dPoint line_point = line.PointAt(line_t);
  ON_3dPoint axis_point = axis.PointAt(axis_t);
  double d = line_point.DistanceTo(axis_point);
  if ( bFiniteCyl ) {
    if ( axis_t < 0.0 )
      axis_t = 0.0;
    else if ( axis_t > 1.0 )
      axis_t = 1.0;
    axis_point = axis.PointAt(axis_t);
  }
  
  if ( d >= cylinder_radius-tol) {
    rc = ( d <= cylinder_radius+tol ) ? 1 : 0;
    A = line_point;
    ON_3dVector V = line_point - axis_point;
    if ( bFiniteCyl ) {
      V = V - (V*cylinder.circle.plane.zaxis)*cylinder.circle.plane.zaxis;
    }
    V.Unitize();
    B = axis_point + cylinder_radius*V;
    if ( rc == 1 ) {
      // check for overlap
      ON_3dPoint P = axis.ClosestPointTo(line.from);
      d = P.DistanceTo(line.from);
      if ( fabs(d-cylinder_radius) <= tol ) {
        P = axis.ClosestPointTo(line.to);
        d = P.DistanceTo(line.to);
        if ( fabs(d-cylinder_radius) <= tol ) {
          rc = 3;
          A = cylinder.ClosestPointTo(line.from);
          B = cylinder.ClosestPointTo(line.to);
        }
      }
    }
  }
  else {
    // transform to coordinate system where equation of cyl
    // is x^2 + y^2 = R^2 and solve for line parameter(s).
    ON_Xform xform;
    xform.Rotation( cylinder.circle.plane, ON_xy_plane );
    ON_Line L = line;
    L.Transform(xform);

    const double x0 = L.from.x;
    const double x1 = L.to.x;
    const double x1mx0 = x1-x0;
    double ax = x1mx0*x1mx0;
    double bx = 2.0*x1mx0*x0;
    double cx = x0*x0;

    const double y0 = L.from.y;
    const double y1 = L.to.y;
    const double y1my0 = y1-y0;
    double ay = y1my0*y1my0;
    double by = 2.0*y1my0*y0;
    double cy = y0*y0;

    double t0, t1;
    int qerc = ON_SolveQuadraticEquation(ax+ay, bx+by, cx+cy-cylinder_radius*cylinder_radius,
                                         &t0,&t1);
    if ( qerc == 2 ) {
      // complex roots - ignore (tiny) imaginary part caused by computational noise.
      t1 = t0;
    }
    A = cylinder.ClosestPointTo(line.PointAt(t0));
    B = cylinder.ClosestPointTo(line.PointAt(t1));

    d = A.DistanceTo(B);
    if ( d <= ON_ZERO_TOLERANCE ) {
      A = line_point;
      ON_3dVector V = line_point - axis_point;
      if ( bFiniteCyl ) {
        V = V - (V*cylinder.circle.plane.zaxis)*cylinder.circle.plane.zaxis;
      }
      V.Unitize();
      B = axis_point + cylinder_radius*V;
      rc = 1;
    }    
    else
      rc = 2;
  }
  return rc;
}
Ejemplo n.º 23
0
bool ON_Intersect( const ON_Line& lineA, const ON_Line& lineB, 
                double* lineA_parameter, 
                double* lineB_parameter
                )
{
  // If you are looking at this code because you don't like an
  // answer you are getting, then the first thing to try is
  // to read the header file comments and try calling 
  // ON_IntersectLineLine.
  bool rc = false;
  double M_zero_tol = 0.0;
  int i, rank;
  double pr_tolerance, pivot, X[2], Y[2];

  ON_3dVector A = lineA.Direction();
  ON_3dVector B = lineB.Direction();
  ON_3dVector C = lineB[0] - lineA[0];
  
  ON_Matrix M(2,2);
  M[0][0] =  ON_DotProduct( A, A );
  M[1][1] =  ON_DotProduct( B, B );
  M[0][1] = M[1][0] = -ON_DotProduct( A, B );

  // this swap done to get row+col pivot accuracy
  if ( M[0][0] < M[1][1] ) {
    M.SwapCols(0,1);
    i = 1;
  }
  else {
    i = 0;
  }
  pr_tolerance = fabs(M[1][1])*ON_SQRT_EPSILON;
  M_zero_tol = fabs(M[1][1])*ON_EPSILON;

  Y[0] =  ON_DotProduct( A, C );
  Y[1] = -ON_DotProduct( B, C );

  rank = M.RowReduce( M_zero_tol, Y, &pivot );
  if ( rank == 2 ) 
  {
    // 19 November 2003 Dale Lear and Chuck
    //   Added lineA.from/to == lineB.from/to tests
    //   so exact answer gets returned when people
    //   expect it.
    rc = true;
    if ( lineA.from == lineB.from )
    {
      if ( lineA_parameter )
        *lineA_parameter = 0.0;
      if ( lineB_parameter )
        *lineB_parameter = 0.0;
    }
    else if ( lineA.from == lineB.to )
    {
      if ( lineA_parameter )
        *lineA_parameter = 0.0;
      if ( lineB_parameter )
        *lineB_parameter = 1.0;
    }
    else if ( lineA.to == lineB.from )
    {
      if ( lineA_parameter )
        *lineA_parameter = 1.0;
      if ( lineB_parameter )
        *lineB_parameter = 0.0;
    }
    else if ( lineA.to == lineB.to )
    {
      if ( lineA_parameter )
        *lineA_parameter = 1.0;
      if ( lineB_parameter )
        *lineB_parameter = 1.0;
    }
    else
    {
      rc = M.BackSolve( 0.0, 2, Y, X );
      if ( rc ) 
      {
        if ( lineA_parameter )
          *lineA_parameter = X[i];
        if ( lineB_parameter )
          *lineB_parameter = X[1-i];
        if ( fabs(pivot) <= pr_tolerance ) 
        {
          // test answer because matrix was close to singular
          // (This test is slow but it is rarely used.)
          ON_3dPoint pA = lineA.PointAt(X[i]);
          ON_3dPoint pB = lineB.PointAt(X[1-i]);
          double d = pA.DistanceTo(pB);
          if ( d > pr_tolerance && d > ON_ZERO_TOLERANCE ) { 
            ON_3dPoint qA = lineA.ClosestPointTo(pB);
            ON_3dPoint qB = lineB.ClosestPointTo(pA);
            double dA = pA.DistanceTo(qB);
            double dB = pB.DistanceTo(qA);
            if ( 1.1*dA < d ) {
              rc = false;
            }
            else if ( 1.1*dB < d ) {
              rc = false;
            }
          }
        }
      }
    }
  }
  
  return rc;
}
Ejemplo n.º 24
0
bool ON_BrepExtrude( 
          ON_Brep& brep,
          const ON_Curve& path_curve,
          bool bCap
          )
{
  ON_Workspace ws;
  const int vcount0 = brep.m_V.Count();
  const int tcount0 = brep.m_T.Count();
  const int lcount0 = brep.m_L.Count();
  const int ecount0 = brep.m_E.Count();
  const int fcount0 = brep.m_F.Count();

  const ON_3dPoint PathStart = path_curve.PointAtStart();
  ON_3dPoint P = path_curve.PointAtEnd();
  if ( !PathStart.IsValid() || !P.IsValid() )
    return false;
  const ON_3dVector height = P - PathStart;
  if ( !height.IsValid() || height.Length() <= ON_ZERO_TOLERANCE )
    return false;

  ON_Xform tr;
  tr.Translation(height);

  // count number of new sides
  int side_count = 0;
  int i, vi, ei, fi;
  bool* bSideEdge = (bool*)ws.GetIntMemory(ecount0*sizeof(bSideEdge[0]));
  for ( ei = 0; ei < ecount0; ei++ )
  {
    const ON_BrepEdge& e = brep.m_E[ei];
    if ( 1 == e.m_ti.Count() )
    {
      side_count++;
      bSideEdge[ei] = true;
    }
    else
    {
      bSideEdge[ei] = false;
    }
  }

  brep.m_V.Reserve( 2*vcount0 );
  i = 4*side_count + (bCap?tcount0:0);
  brep.m_T.Reserve( tcount0 + i );
  brep.m_C2.Reserve( brep.m_C2.Count() + i );
  brep.m_L.Reserve( lcount0 + side_count + (bCap?lcount0:0) );
  i = side_count + (bCap?ecount0:side_count);
  brep.m_E.Reserve( ecount0 + i );
  brep.m_C3.Reserve( brep.m_C3.Count() + i );
  i = side_count + (bCap?fcount0:0);
  brep.m_F.Reserve( fcount0 + i );
  brep.m_S.Reserve( brep.m_S.Count() + i );

  bool bOK = true;

  // build top vertices
  int* topvimap = ws.GetIntMemory(vcount0);
  memset(topvimap,0,vcount0*sizeof(topvimap[0]));
  if ( bCap )
  {
    for ( vi = 0; vi < vcount0; vi++ )
    {
      const ON_BrepVertex& bottomv = brep.m_V[vi];
      ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
      topvimap[vi] = topv.m_vertex_index;
    }
  }
  else
  {
    for ( ei = 0; ei < ecount0; ei++ )
    {
      if ( bSideEdge[ei] )
      {
        const ON_BrepEdge& bottome = brep.m_E[ei];
        int bottomvi0 = bottome.m_vi[0];
        if ( bottomvi0 < 0 || bottomvi0 >= vcount0 )
        {
          bOK = false;
          break;
        }
        int bottomvi1 = bottome.m_vi[1];
        if ( bottomvi1 < 0 || bottomvi1 >= vcount0 )
        {
          bOK = false;
          break;
        }
        if ( !topvimap[bottomvi0] )
        {
          const ON_BrepVertex& bottomv = brep.m_V[bottomvi0];
          ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
          topvimap[bottomvi0] = topv.m_vertex_index;
        }
        if ( !topvimap[bottomvi1] )
        {
          const ON_BrepVertex& bottomv = brep.m_V[bottomvi1];
          ON_BrepVertex& topv = brep.NewVertex(bottomv.point+height,bottomv.m_tolerance);
          topvimap[bottomvi1] = topv.m_vertex_index;
        }
      }
    }
  }

  // build top edges
  int* topeimap = ws.GetIntMemory(ecount0);
  memset(topeimap,0,ecount0*sizeof(topeimap[0]));
  if ( bOK ) for ( ei = 0; ei < ecount0; ei++ )
  {
    if ( bCap || bSideEdge[ei] )
    {
      const ON_BrepEdge& bottome = brep.m_E[ei];
      ON_BrepVertex& topv0 = brep.m_V[topvimap[bottome.m_vi[0]]];
      ON_BrepVertex& topv1 = brep.m_V[topvimap[bottome.m_vi[1]]];
      ON_Curve* c3 = bottome.DuplicateCurve();
      if ( !c3 )
      {
        bOK = false;
        break;
      }
      c3->Transform(tr);
      int c3i = brep.AddEdgeCurve(c3);
      ON_BrepEdge& tope = brep.NewEdge(topv0,topv1,c3i,0,bottome.m_tolerance);
      topeimap[ei] = tope.m_edge_index;
    }
  }

  // build side edges
  int* sideveimap = ws.GetIntMemory(vcount0);
  memset(sideveimap,0,vcount0*sizeof(sideveimap[0]));
  if ( bOK ) for ( vi = 0; vi < vcount0; vi++ )
  {
    ON_BrepVertex& bottomv = brep.m_V[vi];
    for ( int vei = 0; vei < bottomv.m_ei.Count(); vei++ )
    {
      if ( bSideEdge[bottomv.m_ei[vei]] && topvimap[vi] )
      {
        ON_BrepVertex& topv = brep.m_V[topvimap[vi]];
        ON_Curve* c3 = path_curve.DuplicateCurve();
        if ( !c3 )
        {
          bOK = false;
        }
        else
        {
          ON_3dVector D = bottomv.point - PathStart;
          c3->Translate(D);
          int c3i = brep.AddEdgeCurve(c3);
          const ON_BrepEdge& e = brep.NewEdge(bottomv,topv,c3i,0,0.0);
          sideveimap[vi] = e.m_edge_index;
        }
        break;
      }
    }
  }

  if ( bOK && bCap )
  {
    // build top faces
    for (fi = 0; fi < fcount0; fi++ )
    {
      const ON_BrepFace& bottomf = brep.m_F[fi];
      ON_Surface* srf = bottomf.DuplicateSurface();
      if ( !srf )
      {
        bOK = false;
        break;
      }
      srf->Transform(tr);
      int si = brep.AddSurface(srf);
      ON_BrepFace& topf = brep.NewFace(si);
      topf.m_bRev = !bottomf.m_bRev;
      const int loop_count = bottomf.m_li.Count();
      topf.m_li.Reserve(loop_count);
      for ( int fli = 0; fli < loop_count; fli++ )
      {
        const ON_BrepLoop& bottoml = brep.m_L[bottomf.m_li[fli]];
        ON_BrepLoop& topl = brep.NewLoop(bottoml.m_type,topf);
        const int loop_trim_count = bottoml.m_ti.Count();
        topl.m_ti.Reserve(loop_trim_count);
        for ( int lti = 0; lti < loop_trim_count; lti++ )
        {
          const ON_BrepTrim& bottomt = brep.m_T[bottoml.m_ti[lti]];
          ON_NurbsCurve* c2 = ON_NurbsCurve::New();
          if ( !bottomt.GetNurbForm(*c2) )
          {
            delete c2;
            bOK = false;
            break;
          }
          int c2i = brep.AddTrimCurve(c2);
          ON_BrepTrim* topt = 0;
          if ( bottomt.m_ei >= 0 )
          {
            ON_BrepEdge& tope = brep.m_E[topeimap[bottomt.m_ei]];
            topt = &brep.NewTrim(tope,bottomt.m_bRev3d,topl,c2i);
          }
          else
          {
            // singular trim
            ON_BrepVertex& topv = brep.m_V[topvimap[bottomt.m_vi[0]]];
            topt = &brep.NewSingularTrim(topv,topl,bottomt.m_iso,c2i);
          }
          topt->m_tolerance[0] = bottomt.m_tolerance[0];
          topt->m_tolerance[1] = bottomt.m_tolerance[1];
          topt->m_pbox = bottomt.m_pbox;
          topt->m_type = bottomt.m_type;
          topt->m_iso = bottomt.m_iso;
        }
        topl.m_pbox = bottoml.m_pbox;
      }
    }
  }

  // build sides
  int bRev3d[4] = {0,0,1,1};
  int vid[4], eid[4];
  if( bOK ) for ( ei = 0; ei < ecount0; ei++ )
  {
    if ( bSideEdge[ei] && topeimap[ei] )
    {
      ON_BrepEdge& bottome = brep.m_E[ei];
      ON_BrepEdge& tope = brep.m_E[topeimap[ei]];
      vid[0] = bottome.m_vi[0];
      vid[1] = bottome.m_vi[1];
      vid[2] = topvimap[vid[1]];
      vid[3] = topvimap[vid[0]];
      if ( sideveimap[vid[0]] && sideveimap[vid[1]] )
      {
        ON_BrepEdge& leftedge = brep.m_E[sideveimap[vid[0]]];
        ON_BrepEdge& rightedge = brep.m_E[sideveimap[vid[1]]];
        ON_Curve* cx = bottome.DuplicateCurve();
        if ( !cx )
        {
          bOK = false;
          break;
        }
        ON_Curve* cy = leftedge.DuplicateCurve();
        if ( !cy )
        {
          delete cx;
          bOK = false;
          break;
        }
        ON_SumSurface* srf = new ON_SumSurface();
        srf->m_curve[0] = cx;
        srf->m_curve[1] = cy;
        srf->m_basepoint = srf->m_curve[1]->PointAtStart();
        srf->m_basepoint.x = -srf->m_basepoint.x;
        srf->m_basepoint.y = -srf->m_basepoint.y;
        srf->m_basepoint.z = -srf->m_basepoint.z;
        eid[0] = bottome.m_edge_index;
        eid[1] = rightedge.m_edge_index;
        eid[2] = tope.m_edge_index;
        eid[3] = leftedge.m_edge_index;
        ON_BrepFace* face = brep.NewFace(srf,vid,eid,bRev3d);
        if ( !face )
        {
          bOK = false;
          break;
        }
        else if ( bottome.m_ti.Count() == 2 )
        {
          const ON_BrepTrim& trim0 = brep.m_T[bottome.m_ti[0]];
          const ON_BrepTrim& trim1 = brep.m_T[bottome.m_ti[1]];
          const ON_BrepLoop& loop0 = brep.m_L[trim0.m_li];
          const ON_BrepLoop& loop1 = brep.m_L[trim1.m_li];
          bool bBottomFaceRev = brep.m_F[(loop0.m_fi != face->m_face_index) ? loop0.m_fi : loop1.m_fi].m_bRev;
          bool bSideFaceRev = ( trim0.m_bRev3d != trim1.m_bRev3d ) 
                            ? bBottomFaceRev 
                            : !bBottomFaceRev;
          face->m_bRev = bSideFaceRev;
        }
      }
    }
  }

  if ( !bOK )
  {
    for ( vi = brep.m_V.Count(); vi >= vcount0; vi-- )
    {
      brep.DeleteVertex(brep.m_V[vi]);
    }
  }

  return bOK;
}
Ejemplo n.º 25
0
double ON_Line::DistanceTo( ON_3dPoint test_point ) const
{
  return test_point.DistanceTo(ClosestPointTo(test_point));
}
Ejemplo n.º 26
0
bool ON_Mesh::EvaluatePoint( const class ON_ObjRef& objref, ON_3dPoint& P ) const
{
  // virtual function default
  P = ON_UNSET_POINT;
  ON_COMPONENT_INDEX ci = objref.m_component_index;

  switch ( ci.m_type )
  {
  case ON_COMPONENT_INDEX::mesh_vertex:
    if ( ci.m_index >= 0 && ci.m_index < m_V.Count() )
      P = m_V[ci.m_index];
    break;

  case ON_COMPONENT_INDEX::meshtop_vertex:
    if ( ci.m_index >= 0 && ci.m_index < m_top.m_topv.Count() )
    {
      const ON_MeshTopologyVertex& topv = m_top.m_topv[ci.m_index];
      if ( topv.m_v_count > 0 && topv.m_vi )
      {
        int vi = topv.m_vi[0];
        if ( vi >= 0 && vi < m_V.Count() )
          P = m_V[vi];
      }
    }
    break;

  case ON_COMPONENT_INDEX::meshtop_edge:
    if ( 5 == objref.m_evp.m_t_type 
         && fabs(objref.m_evp.m_t[0] + objref.m_evp.m_t[1] - 1.0) <= ON_SQRT_EPSILON )
    {
      ON_Line L = m_top.TopEdgeLine(ci.m_index);
      if ( L.IsValid() )
      {
        P = L.PointAt(objref.m_evp.m_t[0]);
      }
    }
    break;

  case ON_COMPONENT_INDEX::mesh_face:
    if ( 4 == objref.m_evp.m_t_type 
         && fabs(objref.m_evp.m_t[0] + objref.m_evp.m_t[1] + objref.m_evp.m_t[2] + objref.m_evp.m_t[3] - 1.0) <= ON_SQRT_EPSILON )
    {
      if ( ci.m_index >= 0 && ci.m_index < m_F.Count() )
      {
        const int* fvi = m_F[ci.m_index].vi;
        if ( fvi[0] < 0 || fvi[0] >= m_V.Count() )
          break;
        if ( fvi[1] < 0 || fvi[1] >= m_V.Count() )
          break;
        if ( fvi[2] < 0 || fvi[2] >= m_V.Count() )
          break;
        if ( fvi[3] < 0 || fvi[3] >= m_V.Count() )
          break;
        ON_3dPoint V[4];
        V[0] = m_V[fvi[0]];
        V[1] = m_V[fvi[1]];
        V[2] = m_V[fvi[2]];
        V[3] = m_V[fvi[3]];
        P = objref.m_evp.m_t[0]*V[0] + objref.m_evp.m_t[1]*V[1] + objref.m_evp.m_t[2]*V[2] + objref.m_evp.m_t[3]*V[3];
      }
    }
    break;

  default:
    // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values
    break;
  }

  return P.IsValid();
}
Ejemplo n.º 27
0
extern "C" void
rt_revolve_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol)
{
    struct rt_db_internal *tmp_internal;
    struct rt_revolve_internal *rip;
    struct rt_sketch_internal *eip;

    BU_ALLOC(tmp_internal, struct rt_db_internal);
    RT_DB_INTERNAL_INIT(tmp_internal);

    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    RT_REVOLVE_CK_MAGIC(rip);
    eip = rip->skt;
    RT_SKETCH_CK_MAGIC(eip);

    ON_3dPoint plane_origin;
    ON_3dVector plane_x_dir, plane_y_dir;

    bool full_revolve = true;
    if (rip->ang < 2*ON_PI && rip->ang > 0)
	full_revolve = false;

    //  Find plane in 3 space corresponding to the sketch.

    vect_t startpoint;
    VADD2(startpoint, rip->v3d, rip->r);
    plane_origin = ON_3dPoint(startpoint);
    plane_x_dir = ON_3dVector(eip->u_vec);
    plane_y_dir = ON_3dVector(eip->v_vec);
    const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir);

    //  For the brep, need the list of 3D vertex points.  In sketch, they
    //  are stored as 2D coordinates, so use the sketch_plane to define 3 space
    //  points for the vertices.
    for (size_t i = 0; i < eip->vert_count; i++) {
	(*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0);
    }

    // Create the brep elements corresponding to the sketch lines, curves
    // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment.
    // Will need to use the bboxes of each element to
    // build the overall bounding box for the face. Use bGrowBox to expand
    // a single box.
    struct line_seg *lsg;
    struct carc_seg *csg;
    struct bezier_seg *bsg;
    uint32_t *lng;
    for (size_t i = 0; i < (&eip->curve)->count; i++) {
	lng = (uint32_t *)(&eip->curve)->segment[i];
	switch (*lng) {
	    case CURVE_LSEG_MAGIC: {
		lsg = (struct line_seg *)lng;
		ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point());
		lsg3d->SetDomain(0.0, 1.0);
		(*b)->m_C3.Append(lsg3d);
	    }
		break;
	    case CURVE_CARC_MAGIC:
		csg = (struct carc_seg *)lng;
		if (csg->radius < 0) { {
		    ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point();
		    ON_3dPoint edgept = (*b)->m_V[csg->start].Point();
		    ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir);
		    ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept));
		    ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc);
		    c3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(c3d);
		}
		} else {
		    // need to calculated 3rd point on arc - look to sketch.c around line 581 for
		    // logic
		}
		break;
	    case CURVE_BEZIER_MAGIC:
		bsg = (struct bezier_seg *)lng;
		{
		    ON_3dPointArray bezpoints = ON_3dPointArray(bsg->degree + 1);
		    for (int j = 0; j < bsg->degree + 1; j++) {
			bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point());
		    }
		    ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints);
		    ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New();
		    bez3d.GetNurbForm(*beznurb3d);
		    beznurb3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(beznurb3d);
		}
		break;
	    default:
		bu_log("Unhandled sketch object\n");
		break;
	}
    }

    vect_t endpoint;
    VADD2(endpoint, rip->v3d, rip->axis3d);
    const ON_Line& revaxis = ON_Line(ON_3dPoint(rip->v3d), ON_3dPoint(endpoint));

    FindLoops(b, &revaxis, rip->ang);

    // Create the two boundary surfaces, if it's not a full revolution
    if (!full_revolve) {
	// First, deduce the transformation matrices to calculate the position of the end surface
	// The transformation matrices are to rotate an arbitrary point around an arbitrary axis
	// Let the point A = (x, y, z), the rotation axis is p1p2 = (x2,y2,z2)-(x1,y1,z1) = (a,b,c)
	// Then T1 is to translate p1 to the origin
	// Rx is to rotate p1p2 around the X axis to the plane XOZ
	// Ry is to rotate p1p2 around the Y axis to be coincident to Z axis
	// Rz is to rotate A with the angle around Z axis (the new p1p2)
	// RxInv, RyInv, T1Inv are the inverse transformation of Rx, Ry, T1, respectively.
	// The whole transformation is A' = A*T1*Rx*Ry*Rz*Ry*Inv*Rx*Inv = A*R
	vect_t end_plane_origin, end_plane_x_dir, end_plane_y_dir;
	mat_t R;
	MAT_IDN(R);
	mat_t T1, Rx, Ry, Rz, RxInv, RyInv, T1Inv;
	MAT_IDN(T1);
	VSET(&T1[12], -rip->v3d[0], -rip->v3d[1], -rip->v3d[2]);
	MAT_IDN(Rx);
	fastf_t v = sqrt(rip->axis3d[1]*rip->axis3d[1]+rip->axis3d[2]*rip->axis3d[2]);
	VSET(&Rx[4], 0, rip->axis3d[2]/v, rip->axis3d[1]/v);
	VSET(&Rx[8], 0, -rip->axis3d[1]/v, rip->axis3d[2]/v);
	MAT_IDN(Ry);
	fastf_t u = MAGNITUDE(rip->axis3d);
	VSET(&Ry[0], v/u, 0, -rip->axis3d[0]/u);
	VSET(&Ry[8], rip->axis3d[0]/u, 0, v/u);
	MAT_IDN(Rz);
	fastf_t C, S;
	C = cos(rip->ang);
	S = sin(rip->ang);
	VSET(&Rz[0], C, S, 0);
	VSET(&Rz[4], -S, C, 0);
	bn_mat_inv(RxInv, Rx);
	bn_mat_inv(RyInv, Ry);
	bn_mat_inv(T1Inv, T1);
	mat_t temp;
	bn_mat_mul4(temp, T1, Rx, Ry, Rz);
	bn_mat_mul4(R, temp, RyInv, RxInv, T1Inv);
	VEC3X3MAT(end_plane_origin, plane_origin, R);
	VADD2(end_plane_origin, end_plane_origin, &R[12]);
	VEC3X3MAT(end_plane_x_dir, plane_x_dir, R);
	VEC3X3MAT(end_plane_y_dir, plane_y_dir, R);

	// Create the start and end surface with rt_sketch_brep()
	struct rt_sketch_internal sketch;
	sketch = *(rip->skt);
	ON_Brep *b1 = ON_Brep::New();
	VMOVE(sketch.V, plane_origin);
	VMOVE(sketch.u_vec, plane_x_dir);
	VMOVE(sketch.v_vec, plane_y_dir);
	tmp_internal->idb_ptr = (void *)(&sketch);
	rt_sketch_brep(&b1, tmp_internal, tol);
	(*b)->Append(*b1->Duplicate());

	ON_Brep *b2 = ON_Brep::New();
	VMOVE(sketch.V, end_plane_origin);
	VMOVE(sketch.u_vec, end_plane_x_dir);
	VMOVE(sketch.v_vec, end_plane_y_dir);
	tmp_internal->idb_ptr = (void *)(&sketch);
	rt_sketch_brep(&b2, tmp_internal, tol);
	(*b)->Append(*b2->Duplicate());
	(*b)->FlipFace((*b)->m_F[(*b)->m_F.Count()-1]);
    }
    bu_free(tmp_internal, "free temporary rt_db_internal");
}
Ejemplo n.º 28
0
int ON_ArePointsOnPlane( // returns 0=no, 1 = yes, 2 = pointset is (to tolerance) a single point on the line
        int dim,     // 2 or 3
        int is_rat,
        int count, 
        int stride, const double* point,
        const ON_BoundingBox& bbox, // if needed, use ON_GetBoundingBox(dim,is_rat,count,stride,point)
        const ON_Plane& plane,  // line to test
        double tolerance
        )
{
  double w;
  int i, j, k;

  if ( count < 1 )
    return 0;
  if ( !plane.IsValid() )
  {
    ON_ERROR("plane parameter is not valid");
    return 0;
  }
  if ( !bbox.IsValid() )
  {
    ON_ERROR("bbox parameter is not valid");
    return 0;
  }
  if ( !ON_IsValid(tolerance) || tolerance < 0.0 )
  {
    ON_ERROR("tolerance must be >= 0.0");
    return 0;
  }
  if ( dim < 2 || dim > 3 )
  {
    ON_ERROR("dim must be 2 or 3");
    return 0;
  }
  if ( stride < (is_rat?(dim+1):dim) )
  {
    ON_ERROR("stride parameter is too small");
    return 0;
  }
  if ( 0 == point )
  {
    ON_ERROR("point parameter is null");
    return 0;
  }

  int rc = 0;

  if ( tolerance == 0.0 ) {
    tolerance = bbox.Tolerance();
  }

  ON_3dPoint Q;

  // test bounding box to quickly detect the common coordinate axis cases
  rc = (count == 1 || bbox.Diagonal().Length() <= tolerance) ? 2 : 1;
  for ( i = 0; rc && i < 2; i++ ) {
    Q.x = bbox[i].x;
    for ( j = 0; rc && j < 2; j++) {
      Q.y = bbox[j].y;
      for ( k = 0; rc && k < 2; k++) {
        Q.z = bbox[k].z;
        if ( Q.DistanceTo( plane.ClosestPointTo( Q ) ) > tolerance )
          rc = 0;
      }
    }
  }

  if ( !rc ) {
    // test points one by one
    Q.Zero();
    rc = (count == 1 || bbox.Diagonal().Length() <= tolerance) ? 2 : 1;
    if ( is_rat ) {
      for ( i = 0; i < count; i++ ) {
        w = point[dim];
        if ( w == 0.0 ) {
          ON_ERROR("rational point has zero weight");
          return 0;
        }
        ON_ArrayScale( dim, 1.0/w, point, &Q.x );
        if ( Q.DistanceTo( plane.ClosestPointTo( Q ) ) > tolerance ) {
          rc = 0;
          break;
        }
        point += stride;
      }
    }
    else {
      for ( i = 0; i < count; i++ ) {
        memcpy( &Q.x, point, dim*sizeof(Q.x) );
        if ( Q.DistanceTo( plane.ClosestPointTo( Q ) ) > tolerance ) {
          rc = 0;
          break;
        }
        point += stride;
      }
    }
  }

  return rc;
}
Ejemplo n.º 29
0
extern "C" void
rt_sketch_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *UNUSED(tol))
{
    struct rt_sketch_internal *eip;

    RT_CK_DB_INTERNAL(ip);
    eip = (struct rt_sketch_internal *)ip->idb_ptr;
    RT_SKETCH_CK_MAGIC(eip);

    ON_3dPoint plane_origin;
    ON_3dVector plane_x_dir, plane_y_dir;

    //  Find plane in 3 space corresponding to the sketch.

    plane_origin = ON_3dPoint(eip->V);
    plane_x_dir = ON_3dVector(eip->u_vec);
    plane_y_dir = ON_3dVector(eip->v_vec);
    const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir);

    //  For the brep, need the list of 3D vertex points.  In sketch, they
    //  are stored as 2D coordinates, so use the sketch_plane to define 3 space
    //  points for the vertices.
    for (size_t i = 0; i < eip->vert_count; i++) {
	(*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0);
    }

    // Create the brep elements corresponding to the sketch lines, curves
    // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment.
    // Will need to use the bboxes of each element to
    // build the overall bounding box for the face. Use bGrowBox to expand
    // a single box.
    struct line_seg *lsg;
    struct carc_seg *csg;
    struct bezier_seg *bsg;
    uint32_t *lng;
    for (size_t i = 0; i < (&eip->curve)->count; i++) {
	lng = (uint32_t *)(&eip->curve)->segment[i];
	switch (*lng) {
	    case CURVE_LSEG_MAGIC:
		{
		    lsg = (struct line_seg *)lng;
		    ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point());
		    lsg3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(lsg3d);
		}
		break;
	    case CURVE_CARC_MAGIC:
		csg = (struct carc_seg *)lng;
		if (csg->radius < 0) {
		    ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point();
		    ON_3dPoint edgept = (*b)->m_V[csg->start].Point();
		    ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir);
		    ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept));
		    ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc);
		    c3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(c3d);
		} else {
		    // need to calculated 3rd point on arc - look to sketch.c around line 581 for
		    // logic
		}
		break;
	    case CURVE_BEZIER_MAGIC:
		bsg = (struct bezier_seg *)lng;
		{
		    ON_3dPointArray bezpoints(bsg->degree + 1);
		    for (int j = 0; j < bsg->degree + 1; j++) {
			bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point());
		    }
		    ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints);
		    ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New();
		    bez3d.GetNurbForm(*beznurb3d);
		    beznurb3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(beznurb3d);
		}
		break;
	    default:
		bu_log("Unhandled sketch object\n");
		break;
	}
    }

    // Create the plane surface and brep face.
    ON_PlaneSurface *sketch_surf = new ON_PlaneSurface(sketch_plane);
    (*b)->m_S.Append(sketch_surf);
    int surfindex = (*b)->m_S.Count();
    ON_BrepFace& face = (*b)->NewFace(surfindex - 1);

    // For the purposes of BREP creation, it is necessary to identify
    // loops created by sketch segments.  This information is not stored
    // in the sketch data structures themselves, and thus must be deduced
    FindLoops(b);
    const ON_BrepLoop* tloop = (*b)->m_L.First();
    sketch_surf->SetDomain(0, tloop->m_pbox.m_min.x, tloop->m_pbox.m_max.x);
    sketch_surf->SetDomain(1, tloop->m_pbox.m_min.y, tloop->m_pbox.m_max.y);
    sketch_surf->SetExtents(0, sketch_surf->Domain(0));
    sketch_surf->SetExtents(1, sketch_surf->Domain(1));
    (*b)->SetTrimIsoFlags(face);
    (*b)->FlipFace(face);
    (*b)->Compact();
}