Пример #1
0
RH_C_FUNCTION ON_MassProperties* ON_Curve_AreaMassProperties(const ON_Curve* pCurve, double rel_tol, double abs_tol, double curve_planar_tol)
{
  ON_MassProperties* rc = NULL;
  if( pCurve )
  {
    ON_Plane plane;
    if( pCurve->IsPlanar(&plane, curve_planar_tol) && pCurve->IsClosed() )
    {
      ON_BoundingBox bbox = pCurve->BoundingBox();
      ON_3dPoint basepoint = bbox.Center();
      basepoint = plane.ClosestPointTo(basepoint);
      rc = new ON_MassProperties();
      bool getresult = pCurve->AreaMassProperties(basepoint, plane.Normal(), *rc, true, true, true, true, rel_tol, abs_tol);
      if( getresult )
      {
        rc->m_mass = fabs(rc->m_mass);
      }
      else
      {
        delete rc;
        rc = NULL;
      }
    }
  }
  return rc;
}
Пример #2
0
bool ON_Circle::Create( const ON_3dPoint& C, double r )
{
  ON_Plane p = ON_xy_plane;
  p.origin = C;
  p.UpdateEquation();
  return Create( p, r );
}
Пример #3
0
bool ON_Arc::Create( // arc is parallel to XY plane
  const ON_3dPoint& center, // center
  double r,            // radius
  double angle_radians // angle in radians
  )
{
  ON_Plane p;
  p.CreateFromNormal( center, ON_zaxis );
  return Create( ON_Circle(p,r), ON_Interval( 0.0, angle_radians ) );
}
Пример #4
0
bool ON_PlaneSurface::CreatePseudoInfinitePlane( 
        const ON_Plane& plane,
        int point_count,
        const ON_3dPoint* point_list,
        double padding
        )
{
  if ( !plane.IsValid() )
    return false;
  if ( point_count < 1 )
    return false;
  if ( 0 == point_list )
    return false;
  if ( !ON_IsValid(padding) || padding < 0.0 )
    return false;

  ON_Interval plane_domain[2];
  double s, t;
  s = ON_UNSET_VALUE;
  t = ON_UNSET_VALUE;
  if ( !plane.ClosestPointTo( point_list[0], &s, &t ) || !ON_IsValid(s) || !ON_IsValid(t) )
    return 0;
  plane_domain[0].m_t[1] = plane_domain[0].m_t[0] = s;
  plane_domain[1].m_t[1] = plane_domain[1].m_t[0] = t;
  
  for ( int i = 1; i < point_count; i++ )
  {
    s = ON_UNSET_VALUE;
    t = ON_UNSET_VALUE;
    if ( !plane.ClosestPointTo( point_list[i], &s, &t ) || !ON_IsValid(s) || !ON_IsValid(t) )
      return 0;
    if ( s < plane_domain[0].m_t[0] ) plane_domain[0].m_t[0] = s; else if ( s > plane_domain[0].m_t[1] ) plane_domain[0].m_t[1] = s;
    if ( t < plane_domain[1].m_t[0] ) plane_domain[1].m_t[0] = t; else if ( t > plane_domain[1].m_t[1] ) plane_domain[1].m_t[1] = t;
  }

  s = padding*plane_domain[0].Length() + padding;
  if ( !(s > 0.0) && !plane_domain[0].IsIncreasing() )
    s = 1.0;
  plane_domain[0].m_t[0] -= s;
  plane_domain[0].m_t[1] += s;

  t = padding*plane_domain[1].Length() + padding;
  if ( !(t > 0.0) && !plane_domain[1].IsIncreasing() )
    t = 1.0;
  plane_domain[1].m_t[0] -= t;
  plane_domain[1].m_t[1] += t;

  m_plane = plane;
  m_domain[0] = plane_domain[0];
  m_domain[1] = plane_domain[1];
  m_extents[0] = plane_domain[0];
  m_extents[1] = plane_domain[1];

  return IsValid()?true:false;
}
Пример #5
0
RH_C_FUNCTION ON_MassProperties* ON_Geometry_AreaMassProperties(const ON_SimpleArray<const ON_Geometry*>* pConstGeometryArray, double relativeTolerance, double absoluteTolerance)
{
  ON_MassProperties* rc = NULL;
  if( pConstGeometryArray && pConstGeometryArray->Count() > 0 )
  {
    ON_BoundingBox bbox;
    for( int i = 0; i < pConstGeometryArray->Count(); i++ )
    {
      const ON_Geometry* geo = (*pConstGeometryArray)[i];
      if( NULL==geo )
        continue;
      geo->GetBoundingBox(bbox,TRUE);
    }
    ON_3dPoint basepoint = bbox.Center();


    // Aggregate all mass properties
    for( int i = 0; i < pConstGeometryArray->Count(); i++ )
    {
      const ON_Geometry* geo = (*pConstGeometryArray)[i];
      if( NULL==geo )
        continue;

      bool success = false;
      ON_MassProperties mp;

      const ON_Brep* pBrep = ON_Brep::Cast(geo);
      if( pBrep )
        success = pBrep->AreaMassProperties(mp, true, true, true, true, relativeTolerance, absoluteTolerance);

      const ON_Surface* pSurface = success?0:ON_Surface::Cast(geo);
      if( pSurface )
        success = pSurface->AreaMassProperties(mp, true, true, true, true, relativeTolerance, absoluteTolerance);

      const ON_Mesh* pMesh = success?0:ON_Mesh::Cast(geo);
      if( pMesh )
        success = pMesh->AreaMassProperties(mp, true, true, true, true);

      const ON_Curve* pCurve = success?0:ON_Curve::Cast(geo);
      ON_Plane plane;
      if( pCurve && pCurve->IsPlanar(&plane, absoluteTolerance) && pCurve->IsClosed() )
        success = pCurve->AreaMassProperties(basepoint, plane.Normal(), mp, true, true, true, true, relativeTolerance, absoluteTolerance);

      if( success )
      {
        if( NULL==rc )
          rc = new ON_MassProperties(mp);
        else
          rc->Sum(1, &mp, true);
      }
    }
  }
  return rc;
}
Пример #6
0
bool ON_Arc::Create(        // arc parallel to a plane
  const ON_Plane& pl,       // circle will be parallel to this plane
  const ON_3dPoint& center, // center
  double r,                 // radius
  double angle_radians      // angle in radians
  )
{
  ON_Plane p = pl;
  p.origin = center;
  p.UpdateEquation();
  return Create( ON_Circle( p, r), ON_Interval( 0.0, angle_radians ) );
}
Пример #7
0
ON_BOOL32
ON_LineCurve::IsInPlane(
      const ON_Plane& plane, // plane to test
      double tolerance // tolerance to use when checking linearity
      ) const
{
  ON_BOOL32 rc = false;
  double d = fabs( plane.DistanceTo( PointAtStart() ));
  if ( d <= tolerance ) {
    d = fabs( plane.DistanceTo( PointAtEnd() ));
    if ( d <= tolerance )
      rc = true;
  }
  return rc;
}
Пример #8
0
ON_BOOL32 ON_Surface::FrameAt( double u, double v, ON_Plane& frame) const
{
  ON_BOOL32 rc = false;
  ON_3dPoint origin;
  ON_3dVector udir, vdir, normal;
  if( EvNormal( u, v, origin, udir, vdir, normal))
  {
    if ( udir.Unitize() )
      vdir = ON_CrossProduct( normal, udir);
    else if ( vdir.Unitize() )
      udir = ON_CrossProduct( vdir, normal);
    frame.CreateFromFrame( origin, udir, vdir);
    rc = frame.IsValid();
  }
  return rc;
}
void COrientOnCrvXform::MakeNormalPlane( const ON_3dPoint origin, const ON_3dVector& normal, ON_Plane& plane )
{
  plane.origin = origin;

  ON_3dVector up( normal.x, normal.y, normal.z + 1.0 );
  plane.xaxis = ON_CrossProduct( up, normal );
  if( plane.xaxis.IsTiny() )
  {
    if( normal.z < 0.0 )
    {
      plane.xaxis = ON_3dVector( 1.0, 0.0, 0.0 );
      plane.yaxis = ON_3dVector( 0.0, -1.0, 0.0 );
    }
    else
    {
      plane.xaxis = ON_3dVector( 1.0, 0.0, 0.0 );
      plane.yaxis = ON_3dVector( 0.0, 1.0, 0.0 );
    }
  }
  else
  {
    plane.xaxis.Unitize();
    plane.yaxis = ON_CrossProduct( normal, plane.xaxis );
    plane.yaxis.Unitize();
  }

  plane.UpdateEquation();
}
CRhinoCommand::result CCommandSampleOrientOnCrv::GetBasePlane( ON_Plane& base_plane )
{
  CRhinoGetPoint get;
  get.SetCommandPrompt( L"Base point" );
  get.AcceptNothing();
  get.GetPoint();

  CRhinoCommand::result rc = get.CommandResult();
  if( rc == CRhinoCommand::success )
  {
    base_plane = get.View()->Viewport().ConstructionPlane().m_plane;
    base_plane.origin = get.Point();
    base_plane.UpdateEquation();
    if( !base_plane.IsValid() )
      rc = CRhinoCommand::cancel;
  }

  return rc;
}
bool ON_Quaternion::GetRotation(ON_Plane& plane) const
{
  plane.xaxis.x = a*a + b*b - c*c - d*d;
  plane.xaxis.y = 2.0*(a*d + b*c);
  plane.xaxis.z = 2.0*(b*d - a*c);

  plane.yaxis.x = 2.0*(b*c - a*d);
  plane.yaxis.y = a*a - b*b + c*c - d*d;
  plane.yaxis.z = 2.0*(a*b + c*d);

  plane.zaxis.x = 2.0*(a*c + b*d);
  plane.zaxis.y = 2.0*(c*d - a*b);
  plane.zaxis.z = a*a - b*b - c*c + d*d;

  plane.xaxis.Unitize();
  plane.yaxis.Unitize();
  plane.zaxis.Unitize();
  plane.origin.Set(0.0,0.0,0.0);
  plane.UpdateEquation();

  return plane.IsValid();
}
void CTestPreviewDialog::OnBnClickedPreview()
{
  UpdateData( TRUE );

  ON_3dPoint point( m_center_x, m_center_y, m_center_z );

  ON_Plane plane = ON_xy_plane;
  plane.SetOrigin( point );

  ON_Circle circle( plane, m_radius );
  if( circle.IsValid() )
  {
    m_preview.m_circle = circle;

    if( !m_preview.IsEnabled() )
      m_preview.Enable();

    CRhinoDoc* doc = RhinoApp().ActiveDoc();
    if( doc )
      doc->Regen();
  }
}
Пример #13
0
int ON_Intersect( // returns 0 = no intersections, 
                  // 1 = intersection = single point, 
                  // 2 = intersection = circle
                  // If 0 is returned, returned circle has radius=0
                  // and center = point on sphere closest to plane.
                  // If 1 is returned, intersection is a single
                  // point and returned circle has radius=0
                  // and center = intersection point on sphere.
                 const ON_Plane& plane, const ON_Sphere& sphere, ON_Circle& circle
                  )
{
  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;

  circle.plane = plane;

  ON_3dPoint plane_center = plane.ClosestPointTo(sphere_center);
  double d = plane_center.DistanceTo(sphere_center);

  if ( d >= sphere_radius-tol ) {
    rc = ( d <= sphere_radius-tol ) ? 1 : 0;
    circle.plane.origin = sphere.ClosestPointTo(plane_center);
    circle.plane.UpdateEquation();
    circle.radius = 0.0;
  }
  else {
    d /= sphere_radius;
    circle.radius = sphere_radius*sqrt(1.0 - d*d);
    if ( circle.radius <= ON_ZERO_TOLERANCE ) {
      circle.radius = 0.0;
      rc = 1;
    }
    else
      rc = 2;
  }
  //circle.UpdatePoints();    
  return rc;
}
Пример #14
0
bool ON_Line::InPlane( ON_Plane& plane, double tolerance ) const
{
  const ON_3dVector v = to-from;
  const bool bTinyX = fabs(v.x) <= tolerance;
  const bool bTinyY = fabs(v.y) <= tolerance;
  const bool bTinyZ = fabs(v.z) <= tolerance;
  bool rc = true;
  ON_3dVector X;
  ON_3dVector Y;
  if ( bTinyZ && ( !bTinyX || !bTinyY ) )
  {
    X = ON_xaxis;
    Y = ON_yaxis;
  }
  else if ( bTinyX && ( !bTinyY || !bTinyZ ) )
  {
    X = ON_yaxis;
    Y = ON_zaxis;
  }
  else if ( bTinyY && ( !bTinyZ || !bTinyX ) )
  {
    X = ON_zaxis;
    Y = ON_xaxis;
  }
  else
  {
    X = v;
    X.Unitize();
    Y.PerpendicularTo(X);
    if ( bTinyX && bTinyY && bTinyZ )
    {
      rc = false;
      if ( X.IsZero() )
      {
        X = ON_xaxis;
        Y = ON_yaxis;
      }
    }
  }
  plane.CreateFromFrame( from, X, Y );
  return rc;
}
Пример #15
0
bool ON_Plane::Morph( const ON_SpaceMorph& morph )
{
  ON_Plane mp;
  double s = sqrt( fabs(origin.MaximumCoordinate())*ON_SQRT_EPSILON + ON_ZERO_TOLERANCE );
  mp.xaxis = morph.MorphVector(origin,s*xaxis);
  mp.yaxis = morph.MorphVector(origin,s*yaxis);
  mp.zaxis = morph.MorphVector(origin,s*zaxis);
  origin = morph.MorphPoint(origin);
  UpdateEquation();
  bool bx = mp.xaxis.Unitize();
  bool by = mp.yaxis.Unitize();
  bool bz = mp.zaxis.Unitize();
  if (!bx)
  {
    mp.xaxis = ON_CrossProduct(mp.yaxis,mp.zaxis);
    bx = mp.xaxis.Unitize();
  }
  if (!by)
  {
    mp.yaxis = ON_CrossProduct(mp.zaxis,mp.xaxis);
    by = mp.yaxis.Unitize();
  }
  if (!bz)
  {
    mp.zaxis = ON_CrossProduct(mp.xaxis,mp.yaxis);
    bz = mp.zaxis.Unitize();
  }

  mp.origin.Set(0.0,0.0,0.0);
  mp.UpdateEquation();
  bool rc = mp.IsValid();
  ON_3dVector x, y, z;
  if ( rc )
  {
    x = mp.xaxis;
    y = mp.yaxis;
    z = mp.zaxis;
  }
  else
  {
    x = ON_CrossProduct(mp.yaxis,mp.zaxis);
    y = ON_CrossProduct(mp.zaxis,mp.xaxis);
    z = ON_CrossProduct(mp.xaxis,mp.yaxis);
    x.Unitize();
    y.Unitize();
    z.Unitize();
    x = mp.xaxis + x;
    y = mp.yaxis + y;
    z = mp.zaxis + z;
    x.Unitize();
    y.Unitize();
    z.Unitize();
    rc = mp.CreateFromFrame(ON_origin,x,y);
    if (rc)
    {
      x = mp.xaxis;
      y = mp.yaxis;
      z = mp.zaxis;
    }
    else
    {
      rc = mp.CreateFromFrame(ON_origin,y,z);
      if ( rc )
      {
        y = mp.xaxis;
        z = mp.yaxis;
        x = mp.zaxis;
      }
      else
      {
        rc = mp.CreateFromFrame(ON_origin,z,x);
        if (rc)
        {
          z = mp.xaxis;
          x = mp.yaxis;
          y = mp.zaxis;
        }
        else
        {
          rc = mp.CreateFromNormal(ON_origin,z);
          if (rc)
          {
            x = mp.xaxis;
            y = mp.yaxis;
            z = mp.zaxis;
          }
        }
      }
    }
  }

  if (rc)
  {
    xaxis = x;
    yaxis = y;
    zaxis = z;
    UpdateEquation();
  }

  return rc;
}
Пример #16
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;
}
int
negative_polygon(struct subbrep_object_data *data)
{
    int io_state = 0;
    int all_faces_cnt = 0;
    std::vector<int> all_faces;
    int *final_faces = NULL;
    std::set<int> fol_faces;

    /* This will get reused for all faces, so make it once */
    point_t *all_verts = (point_t *)bu_calloc(data->brep->m_V.Count(), sizeof(point_t), "bot verts");
    for (int vi = 0; vi < data->brep->m_V.Count(); vi++) {
        VMOVE(all_verts[vi], data->brep->m_V[vi].Point());
    }

    array_to_set(&fol_faces, data->fol, data->fol_cnt);

    // Check each face to see if it is fil or fol - the first fol face, stash its
    // normal - don't even need the triangle face normal, we can just use the face's normal and
    // a point from the center of one of the fol triangles on that particular face.
    ON_3dPoint origin_pnt;
    ON_3dVector triangle_normal;
    int have_hit_pnt = 0;

    /* Get triangles from the faces */
    ON_BoundingBox vert_bbox;
    ON_MinMaxInit(&vert_bbox.m_min, &vert_bbox.m_max);
    for (int i = 0; i < data->loops_cnt; i++) {
	const ON_BrepLoop *b_loop = &(data->brep->m_L[data->loops[i]]);
	int *ffaces = NULL;
	int num_faces = subbrep_polygon_tri(data->brep, all_verts, (int *)&(b_loop->m_loop_index), 1, &ffaces);
	if (!num_faces) {
	    bu_log("Error - triangulation failed for loop %d!\n", b_loop->m_loop_index);
	    return 0;
	}
	if (!have_hit_pnt) {
	    const ON_BrepFace *b_face = b_loop->Face();
	    if (fol_faces.find(b_face->m_face_index) != fol_faces.end()) {
		ON_3dPoint p1 = data->brep->m_V[ffaces[0]].Point();
		ON_3dPoint p2 = data->brep->m_V[ffaces[1]].Point();
		ON_3dPoint p3 = data->brep->m_V[ffaces[2]].Point();
		ON_Plane fp;
		ON_Surface *ts = b_face->SurfaceOf()->Duplicate();
		(void)ts->IsPlanar(&fp, BREP_PLANAR_TOL);
		delete ts;
		triangle_normal = fp.Normal();
		if (b_face->m_bRev) triangle_normal = triangle_normal * -1;
		origin_pnt = (p1 + p2 + p3) / 3;
		have_hit_pnt = 1;
	    }
	}

	for (int f_ind = 0; f_ind < num_faces*3; f_ind++) {
	    all_faces.push_back(ffaces[f_ind]);
	    vert_bbox.Set(data->brep->m_V[ffaces[f_ind]].Point(), true);
	}
	if (ffaces) bu_free(ffaces, "free polygon face array");
	all_faces_cnt += num_faces;

    }

    /* Now we can build the final faces array */
    final_faces = (int *)bu_calloc(all_faces_cnt * 3, sizeof(int), "final bot verts");
    for (int i = 0; i < all_faces_cnt*3; i++) {
	final_faces[i] = all_faces[i];
    }

    // Scale bounding box to make sure corners are away from the volume
    vert_bbox.m_min = vert_bbox.m_min * 1.1;
    vert_bbox.m_max = vert_bbox.m_max * 1.1;

    // Pick a ray direction
    ON_3dVector rdir;
    ON_3dPoint box_corners[8];
    vert_bbox.GetCorners(box_corners);
    int have_dir = 0;
    int corner = 0;
    double dotp;
    while (!have_dir && corner < 8) {
	rdir = box_corners[corner] - origin_pnt;
	dotp = ON_DotProduct(triangle_normal, rdir);
	(NEAR_ZERO(dotp, 0.01)) ? corner++ : have_dir = 1;
    }
    if (!have_dir) {
	bu_log("Error: NONE of the corners worked??\n");
	return 0;
    }
    point_t origin, dir;
    VMOVE(origin, origin_pnt);
    VMOVE(dir, rdir);
#if 0
    std::cout << "working: " << bu_vls_addr(data->key) << "\n";
    bu_log("in origin.s sph %f %f %f 1\n", origin[0], origin[1], origin[2]);
    bu_log("in triangle_normal.s rcc %f %f %f %f %f %f 1 \n", origin_pnt.x, origin_pnt.y, origin_pnt.z, triangle_normal.x, triangle_normal.y, triangle_normal.z);
    bu_log("in ray.s rcc %f %f %f %f %f %f 1 \n", origin[0], origin[1], origin[2], dir[0], dir[1], dir[2]);
#endif
    // Test the ray against the triangle set
    int hit_cnt = 0;
    point_t p1, p2, p3, isect;
    ON_3dPointArray hit_pnts;
    for (int i = 0; i < all_faces_cnt; i++) {
	ON_3dPoint onp1, onp2, onp3, hit_pnt;
	VMOVE(p1, all_verts[all_faces[i*3+0]]);
	VMOVE(p2, all_verts[all_faces[i*3+1]]);
	VMOVE(p3, all_verts[all_faces[i*3+2]]);
	onp1.x = p1[0];
	onp1.y = p1[1];
	onp1.z = p1[2];
	onp2.x = p2[0];
	onp2.y = p2[1];
	onp2.z = p2[2];
	onp3.x = p3[0];
	onp3.y = p3[1];
	onp3.z = p3[2];
	ON_Plane fplane(onp1, onp2, onp3);
	int is_hit = bg_isect_tri_ray(origin, dir, p1, p2, p3, &isect);
	VMOVE(hit_pnt, isect);
	// Don't count the point on the ray origin
	if (hit_pnt.DistanceTo(origin_pnt) < 0.0001) is_hit = 0;
	if (is_hit) {
	    // No double-counting
	    for (int j = 0; j < hit_pnts.Count(); j++) {
		if (hit_pnts[j].DistanceTo(hit_pnt) < 0.001) is_hit = 0;
	    }
	    if (is_hit) {
		//bu_log("in hit_cnt%d.s sph %f %f %f 0.1\n", hit_pnts.Count()+1, isect[0], isect[1], isect[2]);
		hit_pnts.Append(hit_pnt);
	    }
	}
    }
    hit_cnt = hit_pnts.Count();
    //bu_log("hit count: %d\n", hit_cnt);
    //bu_log("dotp : %f\n", dotp);

    // Final inside/outside determination
    if (hit_cnt % 2) {
	io_state = (dotp > 0) ? -1 : 1;
    } else {
	io_state = (dotp < 0) ? -1 : 1;
    }

    //bu_log("inside out state: %d\n", io_state);

    bu_free(all_verts, "free top level vertex array");
    bu_free(final_faces, "free face array");
    return io_state;
}
Пример #18
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();
}
Пример #19
0
RH_C_FUNCTION ON_MassProperties* ON_GeometryMassProperties(bool bArea, ON_SimpleArray<const ON_Geometry*>* pGeometry, double relativeTolerance, double absoluteTolerance)
{
  ON_MassProperties* rc = NULL;
  if( pGeometry && pGeometry->Count() > 0 )
  {
    // Compute base-point of all geometry boundingboxes
    ON_3dPoint basePoint(0,0,0);
    if( !bArea )
    {
      for( int i = 0; i < pGeometry->Count(); i++ )
      {
        const ON_Geometry* geo = pGeometry->Array()[i];
        ON_BoundingBox box = geo->BoundingBox();
        basePoint += box.Center();
      }
      basePoint /= pGeometry->Count();
    }

    // Aggregate all mass properties
    rc = new ON_MassProperties();
    for( int i = 0; i < pGeometry->Count(); i++ )
    {
      const ON_Geometry* geo = pGeometry->Array()[i];

      bool success = false;
      ON_MassProperties mp;

      ON::object_type type = pGeometry->Array()[i]->ObjectType();

      const ON_Brep* pBrep;
      const ON_Surface* pSurface;
      const ON_Mesh* pMesh;
      const ON_Curve* pCurve;

      switch (type)
      {
      case ON::brep_object:
        pBrep = ON_Brep::Cast(geo);
        if( bArea )
          success = pBrep->AreaMassProperties(mp, true, true, true, true, relativeTolerance, absoluteTolerance);
        else
          success = pBrep->VolumeMassProperties(mp, true, true, true, true, basePoint, relativeTolerance, absoluteTolerance);
        break;

      case ON::surface_object:
        pSurface = ON_Surface::Cast(geo);
        if( bArea )
          success = pSurface->AreaMassProperties(mp, true, true, true, true, relativeTolerance, absoluteTolerance);
        else
          success = pSurface->VolumeMassProperties(mp, true, true, true, true, basePoint, relativeTolerance, absoluteTolerance);
        break;

      case ON::mesh_object:
        pMesh = ON_Mesh::Cast(geo);
        if( bArea )
          success = pMesh->AreaMassProperties(mp, true, true, true, true);
        else
          success = pMesh->VolumeMassProperties(mp, true, true, true, true, basePoint);
        break;

      case ON::curve_object:
        if (bArea)
        {
          pCurve = ON_Curve::Cast(geo);
          ON_Plane plane;
          if( pCurve->IsPlanar(&plane, absoluteTolerance) && pCurve->IsClosed() )
          {
            success = pCurve->AreaMassProperties(basePoint, plane.Normal(), mp, true, true, true, true, relativeTolerance, absoluteTolerance);
            if (success )
            {
              mp.m_mass = fabs(mp.m_mass);
            }
          }
        }
        break;
      }

      if( success )
      {
        rc->Sum(1, &mp, true);
      }
    }
  }
  return rc;
}
Пример #20
0
CRhinoCommand::result CTraslRuota::RunCommand( const CRhinoCommandContext& context )
{
		Cscript1PlugIn& plugin = script1PlugIn();
		if( !plugin.IsDlgVisible() )
		{
			return CRhinoCommand::nothing;
		}

		/*GET A REFERENCE TO THE LAYER TABLE*/
	  CRhinoLayerTable& layer_table = context.m_doc.m_layer_table;
	  


	  ON_Layer currentLayer;
		  int numLayers = layer_table.LayerCount();
		 
		  for(int i = 0; i < numLayers; i++)
	{
			  
				  currentLayer = layer_table[i];
				  const CRhinoLayer& layer = layer_table[i];

				  currentLayer.SetVisible(true);
				  
				  layer_table.ModifyLayer(currentLayer, i);
				  layer_table.SetCurrentLayerIndex(i);
				  
			  
		  
		  
		  
		  
		  const CRhinoLayer& current_layer = layer_table.CurrentLayer();

		  int layer_index = layer_table.CurrentLayerIndex();
		  const CRhinoLayer& layer2 = layer_table[layer_index];

		  ON_SimpleArray<CRhinoObject*> obj_list;
		  int j, obj_count = context.m_doc.LookupObject( layer2, obj_list );
		  for( j = 0; j < obj_count; j++ )
		  {
				  CRhinoObject* obj = obj_list[j];
				  if( obj && obj->IsSelectable() )
					  obj->Select();
				  if( obj_count )
					context.m_doc.Redraw();
		  }
		  
	}  

		  context.m_doc.Redraw();

			//inizio rotazione
		  
		  double m_angle=(_wtof(plugin.m_dialog->ValoreRotazione));
		  ON_Plane plane = RhinoActiveCPlane();
		  
		CRhinoGetObject go1;
		  go1.GetObjects( 1, 0 );
		  int numero1 = go1.ObjectCount();
		for( int k = 0; k < go1.ObjectCount(); k++ )
		{
		 // Get an object reference
			const CRhinoObjRef& ref = go1.Object(k);
 
			// Get the real object
			const CRhinoObject* obj = ref.Object();
			if( !obj )
			continue;

			ON_Xform xform;
    xform.Rotation( m_angle * ON_PI / 180.0, plane.zaxis, plane.Origin() );
	context.m_doc.TransformObject( obj, xform, true, true, true );
	context.m_doc.Redraw();
		}

		//fine rotazione


			//inizio traslazione		 
		  CRhinoGetObject go;
		  int numero = go.ObjectCount();
		  go.GetObjects( 1, 0 );
		  
		for( int i = 0; i < go.ObjectCount(); i++ )
		{
		 // Get an object reference
			const CRhinoObjRef& ref = go.Object(i);
 
			// Get the real object
			const CRhinoObject* obj = ref.Object();
			if( !obj )
			continue;

			ON_Xform xform;
    xform.Rotation( m_angle * ON_PI / 180.0, plane.zaxis, plane.Origin() );
	//context.m_doc.TransformObject( obj, xform, true, true, true );
	context.m_doc.Redraw();
	xform.Translation((_wtof(plugin.m_dialog->ValoreTraslazione)),0,0);
	context.m_doc.TransformObject( obj, xform, true, true, true );
	context.m_doc.Redraw();
		}
			// fine traslazione

		
		 context.m_doc.Redraw();




return CRhinoCommand::success;


}
Пример #21
0
CRhinoCommand::result CGenPianoVis::RunCommand( const CRhinoCommandContext& context )
{

  Cscript1PlugIn& plugin = script1PlugIn();

  if( !plugin.IsDlgVisible() )
  {
    return CRhinoCommand::nothing;
  }


  /*GET THE LAYER NAME*/
  CRhinoGetString gs;
  gs.SetCommandPrompt( L"NAME OF LAYER WHICH CONTAINS VISIONAL PLANE : " );
  gs.GetString();
  if( gs.CommandResult() != CRhinoCommand::success )
  {
	  return gs.CommandResult();
  }
  /*VALIDATE THE STRING*/
  ON_wString layer_name = gs.String();
  layer_name.TrimLeftAndRight();
  if( layer_name.IsEmpty() )
  {
	  return CRhinoCommand::cancel;
  }
    
  /*GET A REFERENCE TO THE LAYER TABLE*/
  CRhinoLayerTable& layer_table = context.m_doc.m_layer_table;
 
  /*FIND THE LAYER*/ 
  int layer_index = layer_table.FindLayer(layer_name );
  if( layer_index < 0 )
  {
    RhinoApp().Print( L"LAYER \"%s\" DOES NOT EXIST.\n", layer_name );
	
  }
  else
  {
	  ON_Layer currentLayer;
	  int numLayers = layer_table.LayerCount();
	  layer_table.SetCurrentLayerIndex(layer_index);
	  for(int i = 0; i < numLayers; i++)
	  {
		  if(i != layer_index)
		  {
			  currentLayer = layer_table[i];
			  currentLayer.SetVisible(false);
			  layer_table.ModifyLayer(currentLayer, i);
		  }
	  }
	  context.m_doc.Redraw();
	  const CRhinoLayer& layer = context.m_doc.m_layer_table[layer_index];
	  ON_SimpleArray<CRhinoObject*> obj_list;

	 
	  
      int object_count = context.m_doc.LookupObject( layer, obj_list );
      if( object_count > 0 )
      {
		 /********************************************************************/
		 //CRhinoObject* obj = obj_list[0];
		 //if( obj && obj->IsSelectable() )
		 //{
			// obj->Select(true);
			// obj->Highlight(true);
			// m_doc.Redraw();
		 //}
		 /********************************************************************/
		 //aniello gegin
		 // Disable redrawing
		 //CRhinoView::EnableDrawing( FALSE ); meglio tenerlo disabilitato altrimenti la schermata non si aggiorna.
 
         // Get the next runtime object serial number before scripting
		 unsigned int first_sn = CRhinoObject::NextRuntimeObjectSerialNumber();
	     //aniello end
	     /////////////////////
		  
		 CRhinoGetObject gc;
		 gc.SetCommandPrompt( L"SELECT LINE TO EXTEND" );
         gc.SetGeometryFilter( CRhinoGetObject::curve_object );
         gc.GetObjects( 1, 1 );
		 if(gc.CommandResult() == CRhinoCommand::success )
		 {
			const CRhinoObjRef& objref = gc.Object(0);
            const ON_Curve* pC = ON_Curve::Cast( objref.Geometry() );
			ON_Curve* crv0 = pC->DuplicateCurve();
			
			bool rc0 = RhinoExtendCurve(crv0, CRhinoExtend::Line, 1, 5);
			bool rc1 = RhinoExtendCurve(crv0, CRhinoExtend::Line, 0, 15);
			context.m_doc.ReplaceObject(objref, *crv0 );
            context.m_doc.Redraw();

			///// begin prova memorizzazione id o name linea pv
		////ON_UUID uuid1 = gc->Attributes().m_uuid;
		////	ON_UUID uuid1 = objref.ObjectUuid();
		//	//ON_UuidToString( uuid1, cvrPrima );
		//	 const CRhinoObject* obj5 = objref.Object();
  //          ON_UUID uuid1 = obj5->Attributes().m_uuid;

		//	pvcurva =  uuid1;
		//	ON_3dmObjectAttributes obj_attribs = obj5->Attributes();
		//	CRhinoGetString gs;
  //gs.SetCommandPrompt( L"New object name" );
  //gs.SetDefaultString( obj_attribs.m_name );
  //gs.AcceptNothing( TRUE );
  //gs.GetString();
  //if( gs.CommandResult() != CRhinoCommand::success )
  //  return gs.CommandResult();
 
  //// Get the string entered by the user
  //ON_wString obj_name = gs.String();
  //obj_name.TrimLeftAndRight();
 
  //// Is name the same?
  //if( obj_name.Compare(obj_attribs.m_name) == 0 )
  //  return CRhinoCommand::nothing;

		//	//ON_wString obj_name = (L"stringanome");
		//	obj_attribs.m_name = obj_name;
		//	context.m_doc.ModifyObjectAttributes( objref, obj_attribs );

///// end prova memorizzazione id o name linea pv



			
			ON_3dPoint p0 = crv0->PointAtStart();
            ON_3dPoint p1 = crv0->PointAtEnd();
 
			CRhinoGetNumber gn;
			//double default_value = 30;
			gn.SetCommandPrompt( L"ENTER ANTERIOR ANGLE FOR EXTENSION in grad: " );
			gn.SetCommandPromptDefault(L"30");
			gn.SetDefaultNumber(30);
			//gn.AcceptNothing(true);
			gn.GetNumber();
			double alphaAngle = gn.Number();
			
			

			gn.SetCommandPrompt( L"ENTER ANTERIOR LENGTH FOR EXTENSION in mm: " );
			gn.SetCommandPromptDefault(L"80");
			gn.SetDefaultNumber(80);
			gn.GetNumber();
			double antLen = gn.Number();

			gn.SetCommandPrompt( L"ENTER ANTERIOR FILLET RADIUS in mm: " );
			gn.SetCommandPromptDefault(L"6");
			gn.SetDefaultNumber(6);
			gn.GetNumber();
			double antRad = gn.Number();

			gn.SetCommandPrompt( L"ENTER POSTERIOR ANGLE FOR EXTENSION default <ALPHA + 10°= 40°> : " );
			gn.SetCommandPromptDefault(L"40");
			gn.SetDefaultNumber(40);
			gn.GetNumber();
			double betaAngle = gn.Number();

			gn.SetCommandPrompt( L"ENTER POSTERIOR LENGTH FOR EXTENSION in mm: " );
			gn.SetCommandPromptDefault(L"80");
			gn.SetDefaultNumber(80);
			gn.GetNumber();
			double posLen = gn.Number();

			gn.SetCommandPrompt( L"ENTER POSTERIOR FILLET RADIUS in mm: " );
			gn.SetCommandPromptDefault(L"13");
			gn.SetDefaultNumber(13);
			gn.GetNumber();
			double posRad = gn.Number();

		
			ON_3dPoint pointStart;
            ON_3dPoint pointEnd;
		 
			//// Fillet radius
			//double radius = 1.0;
		 
			// Do the fillet calculation
			double t0 = 0.0, t1 = 0.0;
 
			ON_Plane plane;
			plane.plane_equation.y = 1.0;

			pointStart = crv0->PointAtStart();
			
			pointEnd   = crv0->PointAtEnd();

			ON_3dPoint point0((pointStart.x - posLen*cos(betaAngle*acos(-1.0)/180.0)), 0.0, (pointStart.z + posLen*sin(betaAngle*acos(-1.0)/180.0)));
			ON_3dPoint point1((pointEnd.x + antLen*cos(alphaAngle*acos(-1.0)/180.0)), 0.0, (pointEnd.z - antLen*sin(alphaAngle*acos(-1.0)/180.0)));

			/**********************************/
			/*CREATE THE LINE CURVES TO FILLET*/ 
			/**********************************/
			ON_LineCurve curve0( pointStart, point0 ); //LINEA A SINISTRA IN FRONT VIEW
			ON_LineCurve curve1( point1, pointEnd );   //LINEA A DESTRA IN FRONT VIEW 

			
			/***************************************************/
			/*FILLET AT THE END/START POINTS OF THE LINE CURVES*/ 
			/***************************************************/
			double curve0_t = crv0->Domain().Max();
			double curve1_t = curve1.Domain().Min();
			ON_3dPoint PuntoAltezzaTacco = curve1.m_line.to;
			AltezzaTacco = PuntoAltezzaTacco;
			
			
			
			if( RhinoGetFilletPoints(curve1,  *crv0, antRad, curve1_t, curve0_t, t1, t0, plane) )
			{
				/*******************************/
				/*TRIM BACK THE TWO LINE CURVES*/ 
				/*******************************/
				ON_Interval domain1( curve1.Domain().Min(), t1 );
				curve1.Trim( domain1 );
		 
				ON_Interval domain0( crv0->Domain().Min(), t0 );
				crv0->Trim( domain0 );

		        /**************************/
				/*COMPUTE THE FILLET CURVE*/ 
				/**************************/
				ON_3dVector radial0 = curve1.PointAt(t1) - plane.Origin();
				radial0.Unitize();
		 
				ON_3dVector radial1 = crv0->PointAt(t0) - plane.Origin();
				radial1.Unitize();
		 
				double angle = acos( radial0 * radial1 );
				ON_Plane fillet_plane( plane.Origin(), radial0, radial1 );
				ON_Arc fillet( fillet_plane, plane.Origin(), antRad, angle );
		 
				/******************/
				/*ADD THE GEOMETRY*/
				/******************/
				context.m_doc.AddCurveObject( curve1 );
				context.m_doc.ReplaceObject(objref, *crv0 );
				context.m_doc.AddCurveObject( fillet );
				context.m_doc.Redraw();
			}
			

			t0 = 0.0, t1 = 0.0;
			/*FILLET AT THE START POINTS OF THE LINE CURVES*/
			curve0_t = crv0->Domain().Min();
			curve1_t = curve0.Domain().Min();

			if( RhinoGetFilletPoints(curve0, *crv0, posRad, curve1_t, curve0_t, t1, t0, plane) )
			{
				// Trim back the two line curves
				ON_Interval domain0( t1, curve0.Domain().Max() );
				curve0.Trim( domain0 );
		 
				ON_Interval domain1( t0, crv0->Domain().Max() );
				crv0->Trim( domain1 );
				

				/*COMPUTE THE FILLET CURVE*/ 
				ON_3dVector radial0 = curve0.PointAt(t1) - plane.Origin();
				radial0.Unitize();
		 
				ON_3dVector radial1 = crv0->PointAt(t0) - plane.Origin();
				radial1.Unitize();
		 
				double angle = acos( radial0 * radial1 );
				ON_Plane fillet_plane( plane.Origin(), radial0, radial1 );
				ON_Arc fillet( fillet_plane, plane.Origin(), posRad, angle );
		 
				/*ADD THE GEOMETRY*/ 
				context.m_doc.AddCurveObject( curve0 );
				context.m_doc.ReplaceObject(objref, *crv0 );
				context.m_doc.AddCurveObject( fillet );
				context.m_doc.Redraw();
			}
			/******************/
			/*CLEAN UP OR LEAK*/ 
			/******************/
			delete crv0;
			crv0 = 0;

			
			// code temp
// aniello begin
// Get the next runtime object serial number after scripting
  unsigned int next_sn = CRhinoObject::NextRuntimeObjectSerialNumber();

 
  // Enable redrawing
  //CRhinoView::EnableDrawing( TRUE );
 
  // if the two are the same, then nothing happened
 /* if( first_sn == next_sn )
    //return CRhinoCommand::nothing;
	return;
*/ //commento questo per far compilare :-)
 
  // The the pointers of all of the objects that were added during scripting
  ON_SimpleArray<const CRhinoObject*> objects;
  for( unsigned int sn = first_sn; sn < next_sn; sn++ )
  {
    const CRhinoObject* obj = context.m_doc.LookupObjectByRuntimeSerialNumber( sn );
    if( obj && !obj->IsDeleted() )
      objects.Append( obj );
  }
 
  /*
  // Sort and cull the list, as there may be duplicates
  if( objects.Count() > 1 )
  {
    objects.HeapSort( CompareObjectPtr );
    const CRhinoObject* last_obj = objects[objects.Count()-1];
    for( int i = objects.Count()-2; i >= 0; i-- )
    {
      const CRhinoObject* prev_obj = objects[i];
     if( last_obj == prev_obj )
        objects.Remove(i);
      else
        last_obj = prev_obj;
    }
  }
	*/
  // Do something with the list...
  for( int i = 0; i < objects.Count(); i++ )
  {
    const CRhinoObject* obj = objects[i];
    if( obj->IsSelectable(true) )
      obj->Select( true );
  }
//aniello end
			//end code temp

  			/*********************/
			/*JOIN LINES TOGETHER*/
			/*********************/
			ON_SimpleArray<const ON_Curve*> lines;
			ON_SimpleArray<CRhinoObject*> objectsLine;
			ON_SimpleArray<ON_Curve*> output;
			double tolerance = context.m_doc.AbsoluteTolerance();
			int LinesCount = context.m_doc.LookupObject( layer, objectsLine);

			if( LinesCount > 0 )
			{
				for(int i = 0; i < LinesCount; i++)
				{
					const CRhinoCurveObject* curve_obj = CRhinoCurveObject::Cast( objectsLine[i] );
					if( curve_obj )
					{
						lines.Append(curve_obj->Curve());
					}
				}
			}
		    if( RhinoMergeCurves(lines, output, tolerance) )
		    {
				for(int i = 0; i < output.Count(); i++ )
				{
					CRhinoCurveObject* crv = new CRhinoCurveObject;
					crv->SetCurve( output[i] );
					if( context.m_doc.AddObject(crv) )
					{
						crv->Select();
					}
					else
					{
						delete crv;
					}
				}
		    }
			/************************/
			/*DELETE CHILDREN CURVES*/
			/************************/
			for(int i = 0; i < LinesCount; i++ )
			{
				context.m_doc.DeleteObject(objectsLine[i]);
			}
			context.m_doc.Redraw();

			/*************************/
			/*END JOIN LINES TOGETHER*/
			/*************************/
	     }
	  }/*CHIUSURA IF( OBJECT_COUNT > 0 )*/
  }/*CHIUSURA ELSE*/

  return CRhinoCommand::success;
}
Пример #22
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");
}
Пример #23
0
// Copied from opennurbs_intersect.cpp but with a bug fix.
// We can remove it once the bug is fixed in OpenNurbs and once 
// Grasshopper has dropped Rhino4 support.
int PS_Intersect(
        const ON_Plane& plane,
        const ON_Sphere& sphere, 
        ON_Circle& circle
        )
{
  // 16 April 2011 Dale Lear
  //   Prior to this date, this function did not return the correct answer.

  int rc = 0;
  const double sphere_radius = fabs(sphere.radius);
  double tol = sphere_radius*ON_SQRT_EPSILON;
  if ( !(tol >= ON_ZERO_TOLERANCE) )
    tol = ON_ZERO_TOLERANCE;
  const ON_3dPoint sphere_center = sphere.Center();
  ON_3dPoint circle_center = plane.ClosestPointTo(sphere_center);
  double d = circle_center.DistanceTo(sphere_center);

  circle.radius = 0.0;

  if ( ON_IsValid(sphere_radius) && ON_IsValid(d) && d <= sphere_radius + tol )
  {
    if ( sphere_radius > 0.0 )
    {
      d /= sphere_radius;
      d = 1.0 - d*d;
      // The d > 4.0*ON_EPSILON was picked by testing spheres with
      // radius = 1 and center = (0,0,0).  Do not make 4.0*ON_EPSILON 
      // any smaller and please discuss changes with Dale Lear.
      circle.radius = (d > 4.0*ON_EPSILON) ? sphere_radius*sqrt(d) : 0.0;
    }
    else
      circle.radius = 0.0;

    if ( circle.radius <= ON_ZERO_TOLERANCE )
    {
      // return a single point
      rc = 1;
      
      circle.radius = 0.0;

      //  When tolerance is in play, put the point on the sphere.
      //  If the caller prefers the plane, then they can adjust the
      //  returned answer to get the plane.
      ON_3dVector R = circle_center - sphere_center;
      double r0 = R.Length();
      if ( r0 > 0.0 )
      {
        R.Unitize();
        ON_3dPoint C1 = sphere_center + sphere_radius*R;
        double r1 = C1.DistanceTo(sphere_center);
        if ( fabs(sphere.radius-r1) < fabs(sphere.radius-r0) )
          circle_center = C1;
      }
    }
    else 
    {
      // return a circle
      rc = 2;
    }
  }

  // Update circle's plane here in case the input plane 
  // is the circle's plane member.
  circle.plane = plane;
  circle.plane.origin = circle_center;
  circle.plane.UpdateEquation();

  return rc;
}