Fem: Move functions to Tools class
This commit is contained in:
@@ -147,18 +147,6 @@ float Constraint::getScaleFactor() const
|
||||
return Scale.getValue() * sizeFactor;
|
||||
}
|
||||
|
||||
void setSubShapeLocation(const Part::Feature* feat, TopoDS_Shape& sh)
|
||||
{
|
||||
// subshape placement is not necessarily the same as the
|
||||
// feature placement.
|
||||
Base::Matrix4D matrix = Part::TopoShape::convert(sh.Location().Transformation());
|
||||
Base::Placement shPla {matrix};
|
||||
Base::Placement featlPlaInv = feat->Placement.getValue().inverse();
|
||||
Base::Placement shGlobalPla = feat->globalPlacement() * featlPlaInv * shPla;
|
||||
|
||||
sh.Location(Part::Tools::fromPlacement(shGlobalPla));
|
||||
}
|
||||
|
||||
constexpr int CONSTRAINTSTEPLIMIT = 50;
|
||||
|
||||
void Constraint::onChanged(const App::Property* prop)
|
||||
@@ -177,26 +165,20 @@ void Constraint::onChanged(const App::Property* prop)
|
||||
for (std::size_t i = 0; i < Objects.size(); i++) {
|
||||
App::DocumentObject* obj = Objects[i];
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(obj);
|
||||
const Part::TopoShape& toposhape = feat->Shape.getShape();
|
||||
if (!toposhape.getShape().IsNull()) {
|
||||
sh = toposhape.getSubShape(SubElements[i].c_str(), !execute);
|
||||
|
||||
if (!sh.IsNull() && sh.ShapeType() == TopAbs_FACE) {
|
||||
setSubShapeLocation(feat, sh);
|
||||
|
||||
// Get face normal in center point
|
||||
TopoDS_Face face = TopoDS::Face(sh);
|
||||
BRepGProp_Face props(face);
|
||||
gp_Vec normal;
|
||||
gp_Pnt center;
|
||||
double u1, u2, v1, v2;
|
||||
props.Bounds(u1, u2, v1, v2);
|
||||
props.Normal((u1 + u2) / 2.0, (v1 + v2) / 2.0, center, normal);
|
||||
normal.Normalize();
|
||||
NormalDirection.setValue(normal.X(), normal.Y(), normal.Z());
|
||||
// One face is enough...
|
||||
break;
|
||||
}
|
||||
sh = Tools::getFeatureSubShape(feat, SubElements[i].c_str(), !execute);
|
||||
if (!sh.IsNull() && sh.ShapeType() == TopAbs_FACE) {
|
||||
// Get face normal in center point
|
||||
TopoDS_Face face = TopoDS::Face(sh);
|
||||
BRepGProp_Face props(face);
|
||||
gp_Vec normal;
|
||||
gp_Pnt center;
|
||||
double u1, u2, v1, v2;
|
||||
props.Bounds(u1, u2, v1, v2);
|
||||
props.Normal((u1 + u2) / 2.0, (v1 + v2) / 2.0, center, normal);
|
||||
normal.Normalize();
|
||||
NormalDirection.setValue(normal.X(), normal.Y(), normal.Z());
|
||||
// One face is enough...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,22 +256,15 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
|
||||
TopoDS_Shape sh;
|
||||
|
||||
for (std::size_t i = 0; i < Objects.size(); i++) {
|
||||
App::DocumentObject* obj = Objects[i];
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(obj);
|
||||
const Part::TopoShape& toposhape = feat->Shape.getShape();
|
||||
if (toposhape.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sh = toposhape.getSubShape(SubElements[i].c_str(), true);
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(Objects[i]);
|
||||
sh = Tools::getFeatureSubShape(feat, SubElements[i].c_str(), true);
|
||||
if (sh.IsNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setSubShapeLocation(feat, sh);
|
||||
// Scale by bounding box of the object
|
||||
Bnd_Box box;
|
||||
BRepBndLib::Add(toposhape.getShape(), box);
|
||||
BRepBndLib::Add(feat->Shape.getShape().getShape(), box);
|
||||
double l = sqrt(box.SquareExtent() / 3.0);
|
||||
*scale = this->calcSizeFactor(l);
|
||||
|
||||
@@ -471,40 +446,6 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Constraint::getCylinder(double& radius,
|
||||
double& height,
|
||||
Base::Vector3d& base,
|
||||
Base::Vector3d& axis) const
|
||||
{
|
||||
std::vector<App::DocumentObject*> Objects = References.getValues();
|
||||
std::vector<std::string> SubElements = References.getSubValues();
|
||||
if (Objects.empty()) {
|
||||
return false;
|
||||
}
|
||||
App::DocumentObject* obj = Objects[0];
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(obj);
|
||||
const Part::TopoShape& toposhape = feat->Shape.getShape();
|
||||
if (toposhape.isNull()) {
|
||||
return false;
|
||||
}
|
||||
TopoDS_Shape sh = toposhape.getSubShape(SubElements[0].c_str());
|
||||
|
||||
TopoDS_Face face = TopoDS::Face(sh);
|
||||
BRepAdaptor_Surface surface(face);
|
||||
gp_Cylinder cyl = surface.Cylinder();
|
||||
gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter());
|
||||
gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter());
|
||||
height = start.Distance(end);
|
||||
radius = cyl.Radius();
|
||||
|
||||
gp_Pnt b = cyl.Location();
|
||||
base = Base::Vector3d(b.X(), b.Y(), b.Z());
|
||||
gp_Dir dir = cyl.Axis().Direction();
|
||||
axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Base::Vector3d Constraint::getBasePoint(const Base::Vector3d& base,
|
||||
const Base::Vector3d& axis,
|
||||
const App::PropertyLinkSub& location,
|
||||
|
||||
@@ -198,16 +198,6 @@ protected:
|
||||
std::vector<Base::Vector3d>& normals,
|
||||
double* scale) const;
|
||||
|
||||
/**
|
||||
* @brief Extract properties of cylindrical face.
|
||||
*
|
||||
* @note
|
||||
* This method is very specific and doesn't require access to member
|
||||
* variables. It should be rewritten at a different place.
|
||||
*/
|
||||
bool
|
||||
getCylinder(double& radius, double& height, Base::Vector3d& base, Base::Vector3d& axis) const;
|
||||
|
||||
/**
|
||||
* @brief Calculate point of cylindrical face where to render widget.
|
||||
*
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "FemConstraintBearing.h"
|
||||
|
||||
#include "FemTools.h"
|
||||
|
||||
using namespace Fem;
|
||||
|
||||
@@ -74,9 +74,17 @@ void ConstraintBearing::onChanged(const App::Property* prop)
|
||||
|
||||
if (prop == &References) {
|
||||
// Find data of cylinder
|
||||
std::vector<App::DocumentObject*> ref = References.getValues();
|
||||
std::vector<std::string> subRef = References.getSubValues();
|
||||
if (ref.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(ref.front());
|
||||
TopoDS_Shape sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true);
|
||||
double radius, height;
|
||||
Base::Vector3d base, axis;
|
||||
if (!getCylinder(radius, height, base, axis)) {
|
||||
if (!Tools::getCylinderParams(sh, base, axis, height, radius)) {
|
||||
return;
|
||||
}
|
||||
Radius.setValue(radius);
|
||||
@@ -113,12 +121,19 @@ void ConstraintBearing::onChanged(const App::Property* prop)
|
||||
}
|
||||
}
|
||||
|
||||
double radius, height;
|
||||
Base::Vector3d base, axis;
|
||||
if (!getCylinder(radius, height, base, axis)) {
|
||||
std::vector<App::DocumentObject*> ref = References.getValues();
|
||||
std::vector<std::string> subRef = References.getSubValues();
|
||||
if (ref.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
feat = static_cast<Part::Feature*>(ref.front());
|
||||
sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true);
|
||||
double radius, height;
|
||||
Base::Vector3d base, axis;
|
||||
if (!Tools::getCylinderParams(sh, base, axis, height, radius)) {
|
||||
return;
|
||||
}
|
||||
base = getBasePoint(base + axis * height / 2, axis, Location, Dist.getValue());
|
||||
BasePoint.setValue(base);
|
||||
BasePoint.touch();
|
||||
}
|
||||
|
||||
@@ -27,16 +27,19 @@
|
||||
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TColgp_Array2OfPnt.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Cylinder.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Lin.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
@@ -44,6 +47,8 @@
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
#include <Mod/Part/App/Tools.h>
|
||||
|
||||
#include "FemTools.h"
|
||||
|
||||
@@ -322,3 +327,74 @@ std::string Fem::Tools::checkIfBinaryExists(std::string prefSection,
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Base::Placement Fem::Tools::getSubShapeGlobalLocation(const Part::Feature* feat,
|
||||
const TopoDS_Shape& sh)
|
||||
{
|
||||
Base::Matrix4D matrix = Part::TopoShape::convert(sh.Location().Transformation());
|
||||
Base::Placement shPla {matrix};
|
||||
Base::Placement featlPlaInv = feat->Placement.getValue().inverse();
|
||||
Base::Placement shGlobalPla = feat->globalPlacement() * featlPlaInv * shPla;
|
||||
|
||||
return shGlobalPla;
|
||||
}
|
||||
|
||||
void Fem::Tools::setSubShapeGlobalLocation(const Part::Feature* feat, TopoDS_Shape& sh)
|
||||
{
|
||||
Base::Placement pla = getSubShapeGlobalLocation(feat, sh);
|
||||
sh.Location(Part::Tools::fromPlacement(pla));
|
||||
}
|
||||
|
||||
|
||||
TopoDS_Shape
|
||||
Fem::Tools::getFeatureSubShape(const Part::Feature* feat, const char* subName, bool silent)
|
||||
{
|
||||
TopoDS_Shape sh;
|
||||
const Part::TopoShape& toposhape = feat->Shape.getShape();
|
||||
if (toposhape.isNull()) {
|
||||
return sh;
|
||||
}
|
||||
|
||||
sh = toposhape.getSubShape(subName, silent);
|
||||
if (sh.IsNull()) {
|
||||
return sh;
|
||||
}
|
||||
|
||||
setSubShapeGlobalLocation(feat, sh);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
bool Fem::Tools::getCylinderParams(const TopoDS_Shape& sh,
|
||||
Base::Vector3d& base,
|
||||
Base::Vector3d& axis,
|
||||
double& height,
|
||||
double& radius)
|
||||
{
|
||||
TopoDS_Face face = TopoDS::Face(sh);
|
||||
BRepAdaptor_Surface surface(face);
|
||||
if (!(surface.GetType() == GeomAbs_Cylinder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Cylinder cyl = surface.Cylinder();
|
||||
gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter());
|
||||
gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter());
|
||||
|
||||
Handle(Geom_Curve) handle = new Geom_Line(cyl.Axis());
|
||||
GeomAPI_ProjectPointOnCurve proj(start, handle);
|
||||
gp_XYZ startProj = proj.NearestPoint().XYZ();
|
||||
proj.Perform(end);
|
||||
gp_XYZ endProj = proj.NearestPoint().XYZ();
|
||||
|
||||
gp_XYZ ax(endProj - startProj);
|
||||
gp_XYZ center = (startProj + endProj) / 2.0;
|
||||
gp_Dir dir(ax);
|
||||
|
||||
height = ax.Modulus();
|
||||
radius = cyl.Radius();
|
||||
base = Base::Vector3d(center.X(), center.Y(), center.Z());
|
||||
axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,22 @@
|
||||
#ifndef FEM_TOOLS_H
|
||||
#define FEM_TOOLS_H
|
||||
|
||||
#include <Base/Placement.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Mod/Fem/FemGlobal.h>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
class TopoDS_Shape;
|
||||
class TopoDS_Edge;
|
||||
class TopoDS_Face;
|
||||
|
||||
namespace Part
|
||||
{
|
||||
|
||||
class Feature;
|
||||
|
||||
}
|
||||
|
||||
namespace Fem
|
||||
{
|
||||
|
||||
@@ -75,6 +83,27 @@ public:
|
||||
static std::string checkIfBinaryExists(std::string prefSection,
|
||||
std::string prefBinaryPath,
|
||||
std::string prefBinaryName);
|
||||
|
||||
/*!
|
||||
Subshape placement is not necessarily the same as the
|
||||
feature placement
|
||||
*/
|
||||
static Base::Placement getSubShapeGlobalLocation(const Part::Feature* feat,
|
||||
const TopoDS_Shape& sh);
|
||||
static void setSubShapeGlobalLocation(const Part::Feature* feat, TopoDS_Shape& sh);
|
||||
/*!
|
||||
Get subshape from Part Feature. The subShape is returned with global location
|
||||
*/
|
||||
static TopoDS_Shape
|
||||
getFeatureSubShape(const Part::Feature* feat, const char* subName, bool silent);
|
||||
/*!
|
||||
Get cylinder parameters. Base is located at the center of the cylinder
|
||||
*/
|
||||
static bool getCylinderParams(const TopoDS_Shape& sh,
|
||||
Base::Vector3d& base,
|
||||
Base::Vector3d& axis,
|
||||
double& height,
|
||||
double& radius);
|
||||
};
|
||||
|
||||
} // namespace Fem
|
||||
|
||||
Reference in New Issue
Block a user