예제 #1
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;
}
예제 #2
0
RH_C_FUNCTION double ON_Brep_Area(const ON_Brep* pBrep, double relativeTolerance, double absoluteTolerance)
{
  double area = 0.0;
  if( pBrep )
  {
    ON_MassProperties rc;
    bool success = false;
    success = pBrep->AreaMassProperties(rc, true, false, false, false, relativeTolerance, absoluteTolerance);
    area = rc.Area();
  }
  return area;
}
예제 #3
0
RH_C_FUNCTION double ON_Brep_Volume(const ON_Brep* pBrep, double relativeTolerance, double absoluteTolerance)
{
  double volume = 0.0;
  if( pBrep )
  {
    ON_MassProperties rc;
    bool success = false;
    success = pBrep->VolumeMassProperties(rc, true, false, false, false, ON_UNSET_POINT, relativeTolerance, absoluteTolerance);
    volume = rc.Volume();
  }
  return volume;
}
예제 #4
0
RH_C_FUNCTION ON_MassProperties* ON_Hatch_AreaMassProperties(const ON_Hatch* pConstHatch, double rel_tol, double abs_tol)
{
  ON_MassProperties* rc = NULL;
  if( pConstHatch )
  {
    ON_BoundingBox bbox = pConstHatch->BoundingBox();
    ON_3dPoint basepoint = bbox.Center();
    basepoint = pConstHatch->Plane().ClosestPointTo(basepoint);

    ON_ClassArray<ON_MassProperties> list;

    for( int i=0; i<pConstHatch->LoopCount(); i++ )
    {
      const ON_HatchLoop* pLoop = pConstHatch->Loop(i);
      if( NULL==pLoop )
        continue;
      ON_Curve* pCurve = pConstHatch->LoopCurve3d(i);
      if( NULL==pCurve )
        continue;
      
      ON_MassProperties mp;
      if( pCurve->AreaMassProperties(basepoint, pConstHatch->Plane().Normal(), mp, true, true, true, true, rel_tol, abs_tol) )
      {
        mp.m_mass = fabs(mp.m_mass);
        if( pLoop->Type() == ON_HatchLoop::ltInner )
          mp.m_mass = -mp.m_mass;

        list.Append(mp);
      }
      delete pCurve;
    }

    if( list.Count()==1 )
    {
      rc = new ON_MassProperties();
      *rc = list[0];
    }
    else if( list.Count()>1 )
    {
      int count = list.Count();
      const ON_MassProperties* pieces = list.Array();
      rc = new ON_MassProperties();
      if( !rc->Sum(count, pieces) )
      {
        delete rc;
        rc = NULL;
      }
    }
  }
  return rc;
}
예제 #5
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;
}