Skip to content

Commit 356fe85

Browse files
Measurement: Added support for cylindrical surfaces (FreeCAD#27044)
* Added support for cylindrical surfaces * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Removed unnessecary sign * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Reverted change --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent c904113 commit 356fe85

File tree

3 files changed

+55
-15
lines changed

3 files changed

+55
-15
lines changed

src/Mod/Measure/App/MeasureDiameter.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ bool MeasureDiameter::isValidSelection(const App::MeasureSelection& selection)
6969
return false;
7070
}
7171

72-
if (type != App::MeasureElementType::CIRCLE && type != App::MeasureElementType::ARC) {
72+
if (type != App::MeasureElementType::CIRCLE && type != App::MeasureElementType::ARC
73+
&& type != App::MeasureElementType::CYLINDER) {
7374
return false;
7475
}
7576

@@ -85,7 +86,8 @@ bool MeasureDiameter::isPrioritizedSelection(const App::MeasureSelection& select
8586
auto element = selection.front();
8687
auto type = App::MeasureManager::getMeasureElementType(element);
8788

88-
if (type == App::MeasureElementType::CIRCLE || type == App::MeasureElementType::ARC) {
89+
if (type == App::MeasureElementType::CIRCLE || type == App::MeasureElementType::ARC
90+
|| type == App::MeasureElementType::CYLINDER) {
8991
return true;
9092
}
9193

src/Mod/Measure/App/MeasureRadius.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ bool MeasureRadius::isValidSelection(const App::MeasureSelection& selection)
7878
return false;
7979
}
8080

81-
if (type != App::MeasureElementType::CIRCLE && type != App::MeasureElementType::ARC) {
81+
if (type != App::MeasureElementType::CIRCLE && type != App::MeasureElementType::ARC
82+
&& type != App::MeasureElementType::CYLINDER) {
8283
return false;
8384
}
8485

@@ -96,7 +97,8 @@ bool MeasureRadius::isPrioritizedSelection(const App::MeasureSelection& selectio
9697
auto element = selection.front();
9798
auto type = App::MeasureManager::getMeasureElementType(element);
9899

99-
if (type == App::MeasureElementType::CIRCLE || type == App::MeasureElementType::ARC) {
100+
if (type == App::MeasureElementType::CIRCLE || type == App::MeasureElementType::ARC
101+
|| type == App::MeasureElementType::CYLINDER) {
100102
return true;
101103
}
102104

src/Mod/Part/App/MeasureClient.cpp

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <Geom_BezierCurve.hxx>
4040
#include <Geom_BSplineCurve.hxx>
4141
#include <TopExp.hxx>
42+
#include <TopExp_Explorer.hxx>
4243
#include <GProp_GProps.hxx>
4344
#include <ShapeAnalysis_Edge.hxx>
4445
#include <gp_Circ.hxx>
@@ -97,6 +98,14 @@ static float getRadius(TopoDS_Shape& edge)
9798
gp_Circ circle = adapt.Circle();
9899
return circle.Radius();
99100
}
101+
if (edge.ShapeType() == TopAbs_FACE) {
102+
BRepAdaptor_Surface adapt(TopoDS::Face(edge));
103+
if (adapt.GetType() != GeomAbs_Cylinder) {
104+
return 0.0;
105+
}
106+
gp_Cylinder cylinder = adapt.Cylinder();
107+
return cylinder.Radius();
108+
}
100109
return 0.0;
101110
}
102111

@@ -336,36 +345,63 @@ MeasureLengthInfoPtr MeasureLengthHandler(const App::SubObjectT& subject)
336345
MeasureRadiusInfoPtr MeasureRadiusHandler(const App::SubObjectT& subject)
337346
{
338347
Base::Placement placement; // curve center + orientation
339-
Base::Vector3d pointOnCurve;
348+
Base::Vector3d centerPoint;
349+
;
340350

341351
TopoDS_Shape shape = getLocatedShape(subject);
342352

343353
if (shape.IsNull()) {
344-
return std::make_shared<MeasureRadiusInfo>(false, 0.0, pointOnCurve, placement);
354+
return std::make_shared<MeasureRadiusInfo>(false, 0.0, centerPoint, placement);
345355
}
346356
TopAbs_ShapeEnum sType = shape.ShapeType();
347357

348-
if (sType != TopAbs_EDGE) {
349-
return std::make_shared<MeasureRadiusInfo>(false, 0.0, pointOnCurve, placement);
358+
if (sType != TopAbs_EDGE && sType != TopAbs_FACE) {
359+
return std::make_shared<MeasureRadiusInfo>(false, 0.0, centerPoint, placement);
350360
}
351361

352-
// Get Center of mass as the attachment point of the label
353362
GProp_GProps gprops;
354-
BRepGProp::LinearProperties(shape, gprops);
363+
TopoDS_Edge edge;
364+
TopoDS_Face face;
365+
gp_Pnt center;
366+
367+
if (sType == TopAbs_EDGE) {
368+
BRepGProp::LinearProperties(shape, gprops);
369+
edge = TopoDS::Edge(shape);
370+
BRepAdaptor_Curve adapt(edge);
371+
if (adapt.GetType() == GeomAbs_Circle) {
372+
center = adapt.Circle().Location();
373+
}
374+
}
375+
else if (sType == TopAbs_FACE) {
376+
BRepGProp::SurfaceProperties(shape, gprops);
377+
face = TopoDS::Face(shape);
378+
TopExp_Explorer exp(face, TopAbs_EDGE);
379+
if (exp.More()) {
380+
edge = TopoDS::Edge(exp.Current());
381+
}
382+
if (edge.IsNull()) {
383+
return std::make_shared<MeasureRadiusInfo>(false, 0.0, centerPoint, placement);
384+
}
385+
386+
BRepAdaptor_Surface surf(face);
387+
if (surf.GetType() == GeomAbs_Cylinder) {
388+
center = surf.Cylinder().Location();
389+
}
390+
}
391+
// Get Center of mass as the attachment point of the label
355392
auto origin = gprops.CentreOfMass();
356393

357-
TopoDS_Edge edge = TopoDS::Edge(shape);
358-
gp_Pnt firstPoint = BRep_Tool::Pnt(TopExp::FirstVertex(edge));
359-
pointOnCurve = Base::Vector3d(firstPoint.X(), firstPoint.Y(), firstPoint.Z());
394+
centerPoint = Base::Vector3d(center.X(), center.Y(), center.Z());
395+
360396
// a somewhat arbitrary radius from center -> point on curve
361-
auto dir = (firstPoint.XYZ() - origin.XYZ()).Normalized();
397+
auto dir = (center.XYZ() - origin.XYZ()).Normalized();
362398
Base::Vector3d elementDirection(dir.X(), dir.Y(), dir.Z());
363399
Base::Vector3d axisUp(0.0, 0.0, 1.0);
364400
Base::Rotation rot(axisUp, elementDirection);
365401

366402
placement = Base::Placement(Base::Vector3d(origin.X(), origin.Y(), origin.Z()), rot);
367403

368-
return std::make_shared<MeasureRadiusInfo>(true, getRadius(shape), pointOnCurve, placement);
404+
return std::make_shared<MeasureRadiusInfo>(true, getRadius(shape), centerPoint, placement);
369405
}
370406

371407

0 commit comments

Comments
 (0)