Attacher: Orient normals correctly for Midpoint
Co-authored-by: Max Wilfinger <max@wilfinger.de>
This commit is contained in:
committed by
Benjamin Nauck
parent
7e0d2d21f7
commit
6f3f0b1d0d
@@ -1969,32 +1969,38 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
|
||||
case TopAbs_FACE: {
|
||||
auto surface = freecad_cast<GeomSurface*>(geom.get());
|
||||
|
||||
auto face = TopoDS::Face(shape->getShape());
|
||||
auto adaptorSurface = BRepAdaptor_Surface(face, true);
|
||||
|
||||
auto u1 = adaptorSurface.FirstUParameter();
|
||||
auto u2 = adaptorSurface.LastUParameter();
|
||||
auto v1 = adaptorSurface.FirstVParameter();
|
||||
auto v2 = adaptorSurface.LastVParameter();
|
||||
|
||||
auto midU = (u1 + u2) / 2;
|
||||
auto midV = (v1 + v2) / 2;
|
||||
|
||||
if (auto sphere = freecad_cast<GeomSphere*>(geom.get())) {
|
||||
placement.setPosition(sphere->getLocation());
|
||||
} else if (auto cone = freecad_cast<GeomCone*>(geom.get())) {
|
||||
placement.setPosition(cone->getApex());
|
||||
} else if (auto point = surface->point(midU, midV)) {
|
||||
placement.setPosition(*point);
|
||||
} else if (auto com = shape->centerOfGravity()) {
|
||||
placement.setPosition(*com);
|
||||
} else {
|
||||
placement.setPosition(shape->getBoundBox().GetCenter());
|
||||
}
|
||||
|
||||
if (auto rotation = surface->getRotation()) {
|
||||
placement.setRotation(*rotation);
|
||||
} else {
|
||||
auto adaptorSurface = BRepAdaptor_Surface(TopoDS::Face(shape->getShape()), true);
|
||||
// calculate the normal at midpoint of the surface and use it as Z axis
|
||||
gp_Dir dir;
|
||||
surface->normal(midU, midV, dir);
|
||||
|
||||
auto u1 = adaptorSurface.FirstUParameter();
|
||||
auto u2 = adaptorSurface.LastUParameter();
|
||||
auto v1 = adaptorSurface.FirstVParameter();
|
||||
auto v2 = adaptorSurface.LastVParameter();
|
||||
|
||||
// calculate the normal at midpoint of the surface and use it as Z axis
|
||||
gp_Dir dir;
|
||||
surface->normal((u1 + u2) / 2, (v1 + v2) / 2, dir);
|
||||
|
||||
placement.setRotation(Base::Rotation::fromNormalVector(Base::convertTo<Base::Vector3d>(-dir)));
|
||||
if (face.Orientation() == TopAbs_REVERSED) {
|
||||
dir = -dir;
|
||||
}
|
||||
|
||||
placement.setRotation(Base::Rotation::fromNormalVector(Base::convertTo<Base::Vector3d>(dir)));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -4884,12 +4884,19 @@ bool GeomSurface::normal(double u, double v, gp_Dir& dir) const
|
||||
|
||||
Tools::getNormal(s, u, v, Precision::Confusion(), dir, done);
|
||||
|
||||
if (done)
|
||||
if (done) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<Base::Vector3d> GeomSurface::point(double u, double v) const
|
||||
{
|
||||
Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle());
|
||||
return Base::convertTo<Base::Vector3d>(s->Value(u, v));
|
||||
}
|
||||
|
||||
gp_Vec GeomSurface::getDN(double u, double v, int Nu, int Nv) const
|
||||
{
|
||||
Handle(Geom_Surface) s = Handle(Geom_Surface)::DownCast(handle());
|
||||
|
||||
@@ -889,6 +889,8 @@ public:
|
||||
bool tangentU(double u, double v, gp_Dir& dirU) const;
|
||||
bool tangentV(double u, double v, gp_Dir& dirV) const;
|
||||
bool normal(double u, double v, gp_Dir& dir) const;
|
||||
std::optional<Base::Vector3d> point(double u, double v) const;
|
||||
|
||||
/*!
|
||||
Computes the derivative of order Nu in the direction U and Nv
|
||||
in the direction V at the point P(U, V).
|
||||
|
||||
Reference in New Issue
Block a user