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