ccx07
(Karlos)
July 3, 2020, 10:29pm
1
Hi All,
In one example calculate the solid volumes.
How do I calculate the surface area on a solid ?
CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
CRhinoGetObject go;
go.SetCommandPrompt(L"Select surface or polysurface");
go.EnableSubObjectSelect(FALSE);
go.EnableGroupSelect(TRUE);
go.GetObjects(1, 0);
if (go.CommandResult() != CRhinoCommand::success) return go.CommandResult();
for (int i = 0; i < go.ObjectCount(); i++)
{
const CRhinoObjRef& ref = go.Object(i);
const CRhinoObject* pObject = ref.Object();
if (0 == pObject) continue;
ON_SimpleArray<ON_COMPONENT_INDEX> subidxs;
pObject->GetSelectedSubObjects(subidxs);
for (int su = 0; su < subidxs.Count(); su++) {
if (subidxs[su].m_type == ON_COMPONENT_INDEX::brep_face) {
if (const ON_Surface* srf = ON_Surface::Cast(pObject->Geometry())) {
ON_SimpleArray<ON_MassProperties> MassProp(1);
ON_MassProperties* mp = &MassProp.AppendNew();
srf->AreaMassProperties(*mp, true, false, false, false);
::RhinoApp().Print(L"Object[%d] Area[%d] = %f\n", i, su, mp->Area());
}
}
}
}
return CRhinoCommand::success;
}
How ?
β Karlos
menno
(Menno Deij - van Rijswijk)
July 4, 2020, 4:13pm
2
ccx07
(Karlos)
July 11, 2020, 9:25pm
3
Hi Menno.
CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
CRhinoGetObject go;
go.EnablePreSelect();
go.SetCommandPrompt(L"Select surface or polysurface");
go.SetGeometryFilter(CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object);
go.EnableSubObjectSelect(FALSE);
go.EnableGroupSelect(TRUE);
go.GetObjects(1, 0);
if (go.CommandResult() != CRhinoCommand::success) return go.CommandResult();
ON_SimpleArray<const ON_Brep*> Breps;
for (int i = 0; i < go.ObjectCount(); i++)
{
::RhinoApp().ActiveDoc()->UnselectAll();
const CRhinoObjRef& ref = go.Object(i);
const CRhinoObject* obj = ref.Object();
const ON_Brep* brep = ref.Brep();
if (!obj | !brep) continue;
Breps.Append(brep);
}
int Bn = 0;
Bn = Breps.Count();
if (Bn > 0)
{
::RhinoApp().Print(L"for (int j = 0; j < Breps.Count(%d); j++)\t\n\{\n", Bn);
for (int j = 0; j < Bn; j++)
{
const ON_Brep* brep = Breps[j];
if (brep)
{
if (brep->m_S.Count() > 0)
{
int n = 0;
n = brep->m_S.Count();
::RhinoApp().Print(L"\tfor (int k = 0; k < brep->m_S.Count(%d); k++)\t( Brep[%d] )\n\t\{\n", n, j);
for (int k = 0; k < n; k++) {
::RhinoApp().Print(L"\t\tSurface[%d]", k);
const ON_Surface* brep_srf = brep->m_S[k];
if (!brep_srf) continue;
ON_Surface* dup_brep_srf = brep->m_S[k]->DuplicateSurface();
if (!dup_brep_srf) continue;
if (dup_brep_srf->IsCone()) ::RhinoApp().Print(L"\tIsCone()\t");
if (dup_brep_srf->IsCylinder()) ::RhinoApp().Print(L"\tIsCylinder()\t");
if (dup_brep_srf->IsPlanar()) ::RhinoApp().Print(L"\tIsPlanar()\t");
if (dup_brep_srf->IsSolid()) ::RhinoApp().Print(L"\tIsSolid()\t");
if (dup_brep_srf->IsSphere()) ::RhinoApp().Print(L"\tIsSphere()\t");
if (dup_brep_srf->IsTorus()) ::RhinoApp().Print(L"\tIsTorus()\t");
if (brep_srf) {
::RhinoApp().Print(L"\tbrep[%d] m_S[%d]\t", j, k);
ON_SimpleArray<ON_MassProperties> MassProp(1);
ON_MassProperties* mp = &MassProp.AppendNew();
if (brep_srf->AreaMassProperties(*mp, true, false, false, false))
{
::RhinoApp().Print(L"\tArea[%d] = %f\n", k, mp->Area());
CRhinoSurfaceObject* srf_obj = new CRhinoSurfaceObject();
srf_obj->SetSurface(dup_brep_srf);
if (context.m_doc.AddObject(srf_obj))
context.m_doc.Redraw();
else
{
delete srf_obj;
srf_obj = NULL;
}
}
}
}
}
}
::RhinoApp().Print(L"\t\}\n");
}
::RhinoApp().Print(L"\}\n");
}
return CRhinoCommand::success;
}
why does the area of a planar surface read the surface of a rectangle ?
?
β Karlos
menno
(Menno Deij - van Rijswijk)
July 12, 2020, 3:14pm
4
What youβre doing is getting the underlying surfaces from the m_S
array. These surfaces are not trimmed, and form part of the ON_Brep
data structure. More info on that data structure can be found here https://developer.rhino3d.com/guides/cpp/brep-data-structure/
What you should do is when you loop over the selected BReps, is calculate the mass properties on the whole thing, not each surface:
// these need to come from the document or you need to choose an absolute and a relative tolerance
double abs_tolerance = TODO;
double rel_tolerance = TODO;
for (int j = 0; j < Bn; j++)
{
const ON_Brep* brep = Breps[j];
if (brep)
{
ON_MassProperties mp;
// get the area-mass-properties for the whole b-rep:
if (brep->AreaMassProperties(mp, true, false, false, false, abs_tolerance, rel_tolerance))
{
// do stuff
}
}
}
ccx07
(Karlos)
July 15, 2020, 7:26pm
5
CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
CRhinoGetObject go;
go.EnablePreSelect();
go.SetCommandPrompt(L"Select surface or polysurface");
go.SetGeometryFilter(CRhinoGetObject::surface_object | CRhinoGetObject::polysrf_object);
go.EnableSubObjectSelect(FALSE);
go.EnableGroupSelect(TRUE);
go.GetObjects(1, 0);
if (go.CommandResult() != CRhinoCommand::success) return go.CommandResult();
ON_SimpleArray<const ON_Brep*> Breps;
for (int i = 0; i < go.ObjectCount(); i++)
{
::RhinoApp().ActiveDoc()->UnselectAll();
const CRhinoObjRef& ref = go.Object(i);
const CRhinoObject* obj = ref.Object();
const ON_Brep* brep = ref.Brep();
if (!obj | !brep) continue;
Breps.Append(brep);
}
int Bn = 0;
Bn = Breps.Count();
if (Bn > 0)
{
::RhinoApp().Print(L"for (int j = 0; j < Breps.Count(%d); j++)\t\n\{\n", Bn);
// these need to come from the document or you need to choose an absolute and a relative tolerance
double abs_tolerance = 1.0e-6;
double rel_tolerance = 1.0e-6;
for (int j = 0; j < Bn; j++)
{
const ON_Brep* brep = Breps[j];
if (brep)
{
//Given a brep and a face index
const int face_index = 0;
const ON_BrepFace* face = brep->Face(face_index);
if (0 == face)
return CRhinoCommand::failure;
int BFn = brep->m_F.Count();
::RhinoApp().Print(L"\tBFn[%d]\n", BFn);
if (brep->m_F.Count() > 0)
{
::RhinoApp().Print(L"\tfor (int fi = 0; fi < brep->m_F.Count(%d); fi++)\t( Brep[%d] )\n\t\{\n", brep->m_F.Count(), j);
for (int fi = 0; fi < brep->m_F.Count(); fi++)
{
::RhinoApp().Print(L"\t\tSurface[%d]", fi);
ON_MassProperties mp_F;
// get the area-mass-properties for the whole b-rep:
if (brep->m_F[fi].AreaMassProperties(mp_F, true, false, false, false, abs_tolerance, rel_tolerance))
{
ON_Surface* dup_brep_srf = brep->m_F[fi].DuplicateSurface();
if (!dup_brep_srf) continue;
if (dup_brep_srf->IsCone()) ::RhinoApp().Print(L"\tIsCone()\t");
if (dup_brep_srf->IsCylinder()) ::RhinoApp().Print(L"\tIsCylinder()\t");
if (dup_brep_srf->IsPlanar()) ::RhinoApp().Print(L"\tIsPlanar()\t");
if (dup_brep_srf->IsSolid()) ::RhinoApp().Print(L"\tIsSolid()\t");
if (dup_brep_srf->IsSphere()) ::RhinoApp().Print(L"\tIsSphere()\t");
if (dup_brep_srf->IsTorus()) ::RhinoApp().Print(L"\tIsTorus()\t");
::RhinoApp().Print(L"\tbrep[%d] m_F[%d]\t\tArea[%d] = %f\n", j, fi, fi, mp_F.Area());
CRhinoSurfaceObject* srf_obj = new CRhinoSurfaceObject();
srf_obj->SetSurface(dup_brep_srf);
if (context.m_doc.AddObject(srf_obj))
context.m_doc.Redraw();
else
{
delete srf_obj;
srf_obj = NULL;
}
}
}
}
}
::RhinoApp().Print(L"\t\}\n");
}
::RhinoApp().Print(L"\}\n");
}
return CRhinoCommand::success;
}
1 Like
ccx07
(Karlos)
July 15, 2020, 7:39pm
6
Thank you very much, Menno.
How can I correctly get all the surfaces separately for analysis?
β Karlos
ccx07
(Karlos)
July 16, 2020, 8:35pm
8
Thank you very much Dale.
Thank you very much Menno.
β Karlos
1 Like