[TD]fix area calculation
This commit is contained in:
committed by
Yorik van Havre
parent
6c85c37b38
commit
1de4dc600d
@@ -34,6 +34,7 @@
|
||||
#include <BRepGProp.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeVertex.hxx>
|
||||
@@ -47,6 +48,7 @@
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <Geom2d_Curve.hxx>
|
||||
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
|
||||
#include <ShapeAnalysis.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
@@ -224,6 +226,11 @@ DrawViewDimension::DrawViewDimension()
|
||||
UnderTolerance.setStatus(App::Property::ReadOnly, true);
|
||||
FormatSpecUnderTolerance.setStatus(App::Property::ReadOnly, true);
|
||||
|
||||
// legacy behaviour if this is false
|
||||
ADD_PROPERTY_TYPE(UseActualArea, (true), "Area", App::Prop_Output,
|
||||
"If true, area dimensions return the area of the face minus the areas of any enclosed faces. \
|
||||
If false, the area of the face's outer boundary is returned.");
|
||||
|
||||
measurement = new Measure::Measurement();
|
||||
// TODO: should have better initial datumLabel position than (0, 0) in the DVP?? something
|
||||
// closer to the object being measured?
|
||||
@@ -277,6 +284,7 @@ void DrawViewDimension::resetArea()
|
||||
{
|
||||
m_areaPoint.center = Base::Vector3d(0, 0, 0);
|
||||
m_areaPoint.area = 0.0;
|
||||
m_areaPoint.actualArea = 0.0;
|
||||
}
|
||||
|
||||
void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
@@ -686,7 +694,6 @@ double DrawViewDimension::getDimValue()
|
||||
//! retrieve the dimension value for "true" dimensions. The returned value is in internal units (mm).
|
||||
double DrawViewDimension::getTrueDimValue() const
|
||||
{
|
||||
// Base::Console().Message("DVD::getTrueDimValue()\n");
|
||||
double result = 0.0;
|
||||
|
||||
if (Type.isValue("Distance") || Type.isValue("DistanceX") || Type.isValue("DistanceY")) {
|
||||
@@ -763,7 +770,17 @@ double DrawViewDimension::getProjectedDimValue() const
|
||||
result = legAngle;
|
||||
}
|
||||
else if (Type.isValue("Area")) {
|
||||
result = m_areaPoint.area / scale / scale;
|
||||
// 2d reference makes scaled values in areaPoint
|
||||
// 3d reference makes actual values in areaPoint :p
|
||||
double divisor{scale / scale};
|
||||
if (has3DReferences()) {
|
||||
divisor = 1.0;
|
||||
}
|
||||
if (UseActualArea.getValue()) {
|
||||
result = m_areaPoint.actualArea / divisor;
|
||||
} else {
|
||||
result = m_areaPoint.area / divisor;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1383,27 +1400,71 @@ areaPoint DrawViewDimension::getAreaParameters(ReferenceVector references)
|
||||
ssMessage << getNameInDocument() << " can not find geometry for 2d reference (4)";
|
||||
throw Base::RuntimeError(ssMessage.str());
|
||||
}
|
||||
auto dvp = static_cast<DrawViewPart*>(refObject);
|
||||
|
||||
pts.area = face->getArea();
|
||||
pts.center = face->getCenter();
|
||||
auto filteredFaces = GeometryUtils::findHolesInFace(dvp, references.front().getSubName());
|
||||
auto perforatedFace = GeometryUtils::makePerforatedFace(face, filteredFaces);
|
||||
|
||||
// these areas are scaled because the source geometry is scaled, but it makes no sense to
|
||||
// report a scaled area.
|
||||
auto unscale = getViewPart()->getScale() * getViewPart()->getScale();
|
||||
pts.area = face->getArea() / unscale; // this will be the 2d area as projected onto the page? not really filled area?
|
||||
pts.actualArea = getActualArea(perforatedFace) / unscale;
|
||||
pts.center = getFaceCenter(perforatedFace);
|
||||
pts.invertY(); // geometry class is over, back to -Y up/.
|
||||
}
|
||||
else {
|
||||
// this is a 3d reference
|
||||
// this is a 3d reference. perforations should be handled for us by OCC
|
||||
TopoDS_Shape geometry = references[0].getGeometry();
|
||||
if (geometry.IsNull() || geometry.ShapeType() != TopAbs_FACE) {
|
||||
throw Base::RuntimeError("Geometry for dimension reference is null.");
|
||||
}
|
||||
const TopoDS_Face& face = TopoDS::Face(geometry);
|
||||
|
||||
GProp_GProps props;
|
||||
BRepGProp::SurfaceProperties(face, props);
|
||||
pts.area = props.Mass();
|
||||
pts.center = DrawUtil::toVector3d(props.CentreOfMass());
|
||||
// these areas are unscaled as the source is 3d geometry.
|
||||
pts.area = getFilledArea(face);
|
||||
pts.actualArea = getActualArea(face);
|
||||
pts.center = getFaceCenter(face);
|
||||
pts.move(getViewPart()->getCurrentCentroid());
|
||||
pts.project(getViewPart());
|
||||
}
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
//! returns the center of mass of a face (density = k)
|
||||
Base::Vector3d DrawViewDimension::getFaceCenter(const TopoDS_Face& face)
|
||||
{
|
||||
GProp_GProps props;
|
||||
BRepGProp::SurfaceProperties(face, props);
|
||||
auto center = DrawUtil::toVector3d(props.CentreOfMass());
|
||||
return center;
|
||||
}
|
||||
|
||||
|
||||
//! returns the "net" area of a face (area of the face's outer boundary less the area of any holes)
|
||||
double DrawViewDimension::getActualArea(const TopoDS_Face& face)
|
||||
{
|
||||
GProp_GProps props;
|
||||
BRepGProp::SurfaceProperties(face, props);
|
||||
return props.Mass();
|
||||
}
|
||||
|
||||
|
||||
//! returns the "gross" area of a face (area of the face's outer boundary)
|
||||
double DrawViewDimension::getFilledArea(const TopoDS_Face& face)
|
||||
{
|
||||
TopoDS_Wire outerwire = ShapeAnalysis::OuterWire(face);
|
||||
if (outerwire.IsNull()) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double area = ShapeAnalysis::ContourArea(outerwire);
|
||||
return area;
|
||||
}
|
||||
|
||||
|
||||
DrawViewPart* DrawViewDimension::getViewPart() const
|
||||
{
|
||||
if (References2D.getValues().empty()) {
|
||||
|
||||
Reference in New Issue
Block a user