You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AppFlow/FITK_Component/FITKGeoCompOCC/FITKOCCReferencePlane.cpp

179 lines
7.3 KiB
C++

#include "FITKOCCReferencePlane.h"
#include <FITK_Interface/FITKInterfaceGeometry/FITKGeoEnum.h>
#include <FITK_Interface/FITKInterfaceGeometry/FITKVirtualTopoManager.h>
#include "FITKOCCVirtualTopoCreator.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoCommandList.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoInterfaceFactory.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoModelSurface.h"
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <Geom_Plane.hxx>
#include <BRep_Tool.hxx>
#include <gp_Vec.hxx>
#include <BRepOffset_MakeOffset.hxx>
#include <TopoDS_Shell.hxx>
#include <TopExp_Explorer.hxx>
#include <gce_MakePln.hxx>
namespace OCC {
bool FITKOCCReferencePlane::update()
{
return false;
}
bool FITKOCCReferenceOffsetPlane::update()
{
auto geoCmdList = FITKGLODATA->getGeometryData<Interface::FITKGeoCommandList>();
if (m_SourceSurface.isDatumObj()) {
auto datumManager = geoCmdList->getDatumManager();
auto datumPlane = dynamic_cast<FITKAbsGeoDatumPlane*>(datumManager->getDataByID(m_SourceSurface.datumId()));
if (datumPlane == nullptr) return false;
double xyz[3];
datumPlane->getNormal(xyz);
gp_Dir normalDir(xyz[0], xyz[1], xyz[2]);
gp_Dir direction(m_Direction[0], m_Direction[1], m_Direction[2]);
if (!normalDir.IsParallel(direction, Precision::Angular())) {
printLog(tr("The offset direction must be parallel to the source plane normal."), 3);
return false;
}
setNormal(m_Direction[0], m_Direction[1], m_Direction[2]);
gp_Vec vec(m_Direction[0], m_Direction[1], m_Direction[2]);
if (vec.Magnitude() < Precision::Confusion()) {
printLog(tr("The normal vector cannot be zero."), 3);
return false;
}
vec = vec / vec.Magnitude() * m_Offset;
datumPlane->getUp(xyz);
setUp(xyz[0], xyz[1], xyz[2]);
datumPlane->getPosition(xyz);
setPosition(xyz[0] + vec.X(), xyz[1] + vec.Y(), xyz[2] + vec.Z());
return true;
}
else {
auto cmd = geoCmdList->getDataByID(m_SourceSurface.cmdId());
if (cmd == nullptr) return false;
auto vshape = cmd->getShapeT<FITKOCCTopoShape>(Interface::FITKGeoEnum::VTopoShapeType::VSFace, m_SourceSurface.virtualTopoId());
if (vshape == nullptr) return false;
auto topoShape = vshape->getTopoShape();
if (topoShape.IsNull() || topoShape.ShapeType() != TopAbs_FACE) return false;
Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(topoShape));
if (surface.IsNull() || surface->DynamicType() != STANDARD_TYPE(Geom_Plane)) return false;
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surface);
auto dir = plane->Position().Direction();
gp_Dir normalDir(dir.X(), dir.Y(), dir.Z());
gp_Dir direction(m_Direction[0], m_Direction[1], m_Direction[2]);
if (!normalDir.IsParallel(direction, Precision::Angular())) {
printLog(tr("The offset direction must be parallel to the source plane normal."), 3);
return false;
}
// 反向
if (normalDir.IsOpposite(direction, Precision::Angular())) {
m_Offset *= -1;
}
BRepOffset_MakeOffset offsetSurface(topoShape, m_Offset, 1e-6);
auto newShape = offsetSurface.Shape();
if (newShape.IsNull()) return false;
if (newShape.ShapeType() == TopAbs_FACE)
{
TopoDS_Face face = TopoDS::Face(newShape);
if (face.IsNull()) return false;
Handle(Geom_Surface) surface = BRep_Tool::Surface(face);
auto type = surface->DynamicType();
if (surface.IsNull() || surface->DynamicType() != STANDARD_TYPE(Geom_Plane)) return false;
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surface);
auto pos = plane->Position();
auto loc = plane->Position().Location();
auto direction = plane->Position().Direction();
auto yDirection = plane->Position().YDirection();
setPosition(loc.X(), loc.Y(), loc.Z());
setNormal(direction.X(), direction.Y(), direction.Z());
setUp(yDirection.X(), yDirection.Y(), yDirection.Z());
return true;
}
else if (newShape.ShapeType() == TopAbs_SHELL)
{
TopoDS_Shell shell = TopoDS::Shell(newShape);
if (shell.IsNull()) return false;
TopExp_Explorer exp;
for (exp.Init(shell, TopAbs_FACE); exp.More(); exp.Next()) {
if (exp.Current().ShapeType() != TopAbs_FACE) continue;
TopoDS_Face face = TopoDS::Face(exp.Current());
if (face.IsNull()) continue;
Handle(Geom_Surface) surface = BRep_Tool::Surface(face);
if (surface.IsNull() || surface->DynamicType() != STANDARD_TYPE(Geom_Plane)) continue;
Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surface);
auto pos = plane->Position();
auto loc = plane->Position().Location();
auto direction = plane->Position().Direction();
auto yDirection = plane->Position().YDirection();
setPosition(loc.X(), loc.Y(), loc.Z());
setNormal(direction.X(), direction.Y(), direction.Z());
setUp(yDirection.X(), yDirection.Y(), yDirection.Z());
return true;
}
}
}
return false;
}
bool FITKOCCReferenceThreePointsPlane::update()
{
gp_Pnt p1(m_Points.at(0).at(0), m_Points.at(0).at(1), m_Points.at(0).at(2));
gp_Pnt p2(m_Points.at(1).at(0), m_Points.at(1).at(1), m_Points.at(1).at(2));
gp_Pnt p3(m_Points.at(2).at(0), m_Points.at(2).at(1), m_Points.at(2).at(2));
gce_MakePln pln(p1, p2, p3);
if (!pln.IsDone()) return false;
auto plane = pln.Value();
auto loc = plane.Position().Location();
auto direction = plane.Position().Direction();
auto yDirection = plane.Position().YDirection();
setPosition(loc.X(), loc.Y(), loc.Z());
setNormal(direction.X(), direction.Y(), direction.Z());
setUp(yDirection.X(), yDirection.Y(), yDirection.Z());
return true;
}
bool FITKOCCReferenceEquationPlane::update()
{
gce_MakePln pln(m_A, m_B, m_C, m_D);
if (!pln.IsDone()) return false;
auto plane = pln.Value();
auto loc = plane.Position().Location();
auto direction = plane.Position().Direction();
auto yDirection = plane.Position().YDirection();
setPosition(loc.X(), loc.Y(), loc.Z());
setNormal(direction.X(), direction.Y(), direction.Z());
setUp(yDirection.X(), yDirection.Y(), yDirection.Z());
return true;
}
}