2018-08-23
08:14 AM
- last edited on
2022-11-30
10:47 AM
by
Daniel Kassai
Solved! Go to Solution.
2018-08-23 09:40 AM
#include "ACAPinc.h"
#include "basicgeometry.h"
#include "Polygon2D.hpp"
static double CalculateProjectedAreaOfElem (const API_Guid& elemGuid)
{
double calculatedArea = 0.;
GSErrCode err = NoError;
Geometry::Plane floorPlanPlane;
API_Elem_Head elemHead = {};
elemHead.guid = elemGuid;
API_ElemInfo3D info3D;
err = ACAPI_Element_Get3DInfo (elemHead, &info3D);
if (DBERROR (err != NoError))
return 0;
Geometry::MultiPolygon2D projectedPolygon2DArray;
for (Int32 ibody = info3D.fbody; ibody <= info3D.lbody; ++ibody) {
API_Component3D component = {};
component.header.typeID = API_BodyID;
component.header.index = ibody;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
Int32 nPgon = component.body.nPgon;
API_Tranmat tm = component.body.tranmat;
for (Int32 iPgon = 1; iPgon <= nPgon; ++iPgon) {
component.header.typeID = API_PgonID;
component.header.index = iPgon;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
GS::Array<Coord> pgonCoordsProjectedToFloorPlan;
for (Int32 iEdge = component.pgon.fpedg; iEdge <= component.pgon.lpedg; ++iEdge) {
component.header.typeID = API_EdgeID;
component.header.index = iEdge;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
component.header.typeID = API_VertID;
component.header.index = component.edge.vert1;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
Geometry::Coord3D worldCoord;
worldCoord.x = tm.tmx[0]*component.vert.x + tm.tmx[1]*component.vert.y + tm.tmx[2]*component.vert.z + tm.tmx[3];
worldCoord.y = tm.tmx[4]*component.vert.x + tm.tmx[5]*component.vert.y + tm.tmx[6]*component.vert.z + tm.tmx[7];
worldCoord.z = tm.tmx[8]*component.vert.x + tm.tmx[9]*component.vert.y + tm.tmx[10]*component.vert.z + tm.tmx[11];
Geometry::Coord3D projectedCoord = floorPlanPlane.ProjectToPlane (worldCoord);
pgonCoordsProjectedToFloorPlan.PushNew (projectedCoord.x, projectedCoord.y);
}
Geometry::MultiPolygon2D polygon2DArray;
Geometry::Polygon2D::Create (pgonCoordsProjectedToFloorPlan, 0, polygon2DArray);
projectedPolygon2DArray.Append (polygon2DArray);
}
}
projectedPolygon2DArray.Unify (Geometry::WithoutHoles);
for (const Geometry::Polygon2D& polygon2D : projectedPolygon2DArray)
calculatedArea += polygon2D.CalcArea ();
return calculatedArea;
}
This is based on Ralph's idea.
2018-08-23 08:28 AM
2018-08-23 08:40 AM
Ralph wrote:Hi Ralph,
Could you clarify whether you mean the total surface area of the 3D body or the area visible in the 3D window?
2018-08-23 09:10 AM
2018-08-23 09:40 AM
#include "ACAPinc.h"
#include "basicgeometry.h"
#include "Polygon2D.hpp"
static double CalculateProjectedAreaOfElem (const API_Guid& elemGuid)
{
double calculatedArea = 0.;
GSErrCode err = NoError;
Geometry::Plane floorPlanPlane;
API_Elem_Head elemHead = {};
elemHead.guid = elemGuid;
API_ElemInfo3D info3D;
err = ACAPI_Element_Get3DInfo (elemHead, &info3D);
if (DBERROR (err != NoError))
return 0;
Geometry::MultiPolygon2D projectedPolygon2DArray;
for (Int32 ibody = info3D.fbody; ibody <= info3D.lbody; ++ibody) {
API_Component3D component = {};
component.header.typeID = API_BodyID;
component.header.index = ibody;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
Int32 nPgon = component.body.nPgon;
API_Tranmat tm = component.body.tranmat;
for (Int32 iPgon = 1; iPgon <= nPgon; ++iPgon) {
component.header.typeID = API_PgonID;
component.header.index = iPgon;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
GS::Array<Coord> pgonCoordsProjectedToFloorPlan;
for (Int32 iEdge = component.pgon.fpedg; iEdge <= component.pgon.lpedg; ++iEdge) {
component.header.typeID = API_EdgeID;
component.header.index = iEdge;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
component.header.typeID = API_VertID;
component.header.index = component.edge.vert1;
err = ACAPI_3D_GetComponent (&component);
if (DBERROR (err != NoError))
continue;
Geometry::Coord3D worldCoord;
worldCoord.x = tm.tmx[0]*component.vert.x + tm.tmx[1]*component.vert.y + tm.tmx[2]*component.vert.z + tm.tmx[3];
worldCoord.y = tm.tmx[4]*component.vert.x + tm.tmx[5]*component.vert.y + tm.tmx[6]*component.vert.z + tm.tmx[7];
worldCoord.z = tm.tmx[8]*component.vert.x + tm.tmx[9]*component.vert.y + tm.tmx[10]*component.vert.z + tm.tmx[11];
Geometry::Coord3D projectedCoord = floorPlanPlane.ProjectToPlane (worldCoord);
pgonCoordsProjectedToFloorPlan.PushNew (projectedCoord.x, projectedCoord.y);
}
Geometry::MultiPolygon2D polygon2DArray;
Geometry::Polygon2D::Create (pgonCoordsProjectedToFloorPlan, 0, polygon2DArray);
projectedPolygon2DArray.Append (polygon2DArray);
}
}
projectedPolygon2DArray.Unify (Geometry::WithoutHoles);
for (const Geometry::Polygon2D& polygon2D : projectedPolygon2DArray)
calculatedArea += polygon2D.CalcArea ();
return calculatedArea;
}
This is based on Ralph's idea.
2018-08-23 10:14 AM