+ command to create points object from geometry
+ implement TopoShape::getPoints
This commit is contained in:
parent
0ec81d2760
commit
34b9ff8867
|
@ -59,6 +59,7 @@
|
||||||
# include <BRepCheck_Analyzer.hxx>
|
# include <BRepCheck_Analyzer.hxx>
|
||||||
# include <BRepCheck_ListIteratorOfListOfStatus.hxx>
|
# include <BRepCheck_ListIteratorOfListOfStatus.hxx>
|
||||||
# include <BRepCheck_Result.hxx>
|
# include <BRepCheck_Result.hxx>
|
||||||
|
# include <BRepClass_FaceClassifier.hxx>
|
||||||
# include <BRepFilletAPI_MakeFillet.hxx>
|
# include <BRepFilletAPI_MakeFillet.hxx>
|
||||||
# include <BRepMesh_IncrementalMesh.hxx>
|
# include <BRepMesh_IncrementalMesh.hxx>
|
||||||
# include <BRepMesh_Triangle.hxx>
|
# include <BRepMesh_Triangle.hxx>
|
||||||
|
@ -76,6 +77,8 @@
|
||||||
# include <BRepTools_ShapeSet.hxx>
|
# include <BRepTools_ShapeSet.hxx>
|
||||||
# include <BRepFill_CompatibleWires.hxx>
|
# include <BRepFill_CompatibleWires.hxx>
|
||||||
# include <GCE2d_MakeSegment.hxx>
|
# include <GCE2d_MakeSegment.hxx>
|
||||||
|
# include <GCPnts_AbscissaPoint.hxx>
|
||||||
|
# include <GCPnts_UniformAbscissa.hxx>
|
||||||
# include <Geom2d_Line.hxx>
|
# include <Geom2d_Line.hxx>
|
||||||
# include <Geom2d_TrimmedCurve.hxx>
|
# include <Geom2d_TrimmedCurve.hxx>
|
||||||
# include <GeomLProp_SLProps.hxx>
|
# include <GeomLProp_SLProps.hxx>
|
||||||
|
@ -86,6 +89,7 @@
|
||||||
# include <GeomFill_Pipe.hxx>
|
# include <GeomFill_Pipe.hxx>
|
||||||
# include <GeomFill_SectionLaw.hxx>
|
# include <GeomFill_SectionLaw.hxx>
|
||||||
# include <GeomFill_Sweep.hxx>
|
# include <GeomFill_Sweep.hxx>
|
||||||
|
# include <GeomLib.hxx>
|
||||||
# include <Handle_Law_BSpFunc.hxx>
|
# include <Handle_Law_BSpFunc.hxx>
|
||||||
# include <Handle_Law_BSpline.hxx>
|
# include <Handle_Law_BSpline.hxx>
|
||||||
# include <Handle_TopTools_HSequenceOfShape.hxx>
|
# include <Handle_TopTools_HSequenceOfShape.hxx>
|
||||||
|
@ -2532,3 +2536,111 @@ void TopoShape::setFaces(const std::vector<Base::Vector3d> &Points,
|
||||||
if (_Shape.IsNull())
|
if (_Shape.IsNull())
|
||||||
_Shape = aComp;
|
_Shape = aComp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TopoShape::getPoints(std::vector<Base::Vector3d> &Points,
|
||||||
|
std::vector<Base::Vector3d> &Normals,
|
||||||
|
float Accuracy, uint16_t flags) const
|
||||||
|
{
|
||||||
|
if (_Shape.IsNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int minPointsPerEdge = 30;
|
||||||
|
const double lateralDistance = Accuracy;
|
||||||
|
|
||||||
|
// get all 3d points from free vertices
|
||||||
|
for (TopExp_Explorer xp(_Shape, TopAbs_VERTEX, TopAbs_EDGE); xp.More(); xp.Next()) {
|
||||||
|
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(xp.Current()));
|
||||||
|
Points.push_back(Base::convertTo<Base::Vector3d>(p));
|
||||||
|
Normals.push_back(Base::Vector3d(0,0,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// sample inner points of all free edges
|
||||||
|
for (TopExp_Explorer xp(_Shape, TopAbs_EDGE, TopAbs_FACE); xp.More(); xp.Next()) {
|
||||||
|
BRepAdaptor_Curve curve(TopoDS::Edge(xp.Current()));
|
||||||
|
GCPnts_UniformAbscissa discretizer(curve, lateralDistance, curve.FirstParameter(), curve.LastParameter());
|
||||||
|
if (discretizer.IsDone () && discretizer.NbPoints () > 0) {
|
||||||
|
int nbPoints = discretizer.NbPoints();
|
||||||
|
for (int i=1; i<=nbPoints; i++) {
|
||||||
|
gp_Pnt p = curve.Value (discretizer.Parameter(i));
|
||||||
|
Points.push_back(Base::convertTo<Base::Vector3d>(p));
|
||||||
|
Normals.push_back(Base::Vector3d(0,0,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sample inner points of all faces
|
||||||
|
BRepClass_FaceClassifier classifier;
|
||||||
|
bool hasFaces = false;
|
||||||
|
for (TopExp_Explorer xp(_Shape, TopAbs_FACE); xp.More(); xp.Next()) {
|
||||||
|
hasFaces = true;
|
||||||
|
int pointsPerEdge = minPointsPerEdge;
|
||||||
|
TopoDS_Face face = TopoDS::Face(xp.Current());
|
||||||
|
BRepAdaptor_Surface surface(face);
|
||||||
|
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(face);
|
||||||
|
|
||||||
|
// parameter ranges
|
||||||
|
Standard_Real uFirst = surface.FirstUParameter();
|
||||||
|
Standard_Real uLast = surface.LastUParameter();
|
||||||
|
Standard_Real vFirst = surface.FirstVParameter();
|
||||||
|
Standard_Real vLast = surface.LastVParameter();
|
||||||
|
|
||||||
|
// get geometrical length and width of the surface
|
||||||
|
//
|
||||||
|
gp_Pnt p1, p2;
|
||||||
|
Standard_Real fLengthU = 0.0, fLengthV = 0.0;
|
||||||
|
for (int i = 1; i <= pointsPerEdge; i++) {
|
||||||
|
double u1 = static_cast<double>(i-1)/static_cast<double>(pointsPerEdge);
|
||||||
|
double s1 = (1.0-u1)*uFirst + u1*uLast;
|
||||||
|
p1 = surface.Value(s1,0.0);
|
||||||
|
|
||||||
|
double u2 = static_cast<double>(i)/static_cast<double>(pointsPerEdge);
|
||||||
|
double s2 = (1.0-u2)*uFirst + u2*uLast;
|
||||||
|
p2 = surface.Value(s2,0.0);
|
||||||
|
|
||||||
|
fLengthU += p1.Distance(p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i <= pointsPerEdge; i++) {
|
||||||
|
double v1 = static_cast<double>(i-1)/static_cast<double>(pointsPerEdge);
|
||||||
|
double t1 = (1.0-v1)*vFirst + v1*vLast;
|
||||||
|
p1 = surface.Value(0.0,t1);
|
||||||
|
|
||||||
|
double v2 = static_cast<double>(i)/static_cast<double>(pointsPerEdge);
|
||||||
|
double t2 = (1.0-v2)*vFirst + v2*vLast;
|
||||||
|
p2 = surface.Value(0.0,t2);
|
||||||
|
|
||||||
|
fLengthV += p1.Distance(p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uPointsPerEdge = static_cast<int>(fLengthU / lateralDistance);
|
||||||
|
int vPointsPerEdge = static_cast<int>(fLengthV / lateralDistance);
|
||||||
|
|
||||||
|
for (int i = 0; i <= uPointsPerEdge; i++) {
|
||||||
|
double u = static_cast<double>(i)/static_cast<double>(uPointsPerEdge);
|
||||||
|
double s = (1.0-u)*uFirst + u*uLast;
|
||||||
|
|
||||||
|
for (int j = 0; j <= vPointsPerEdge; j++) {
|
||||||
|
double v = static_cast<double>(j)/static_cast<double>(vPointsPerEdge);
|
||||||
|
double t = (1.0-v)*vFirst + v*vLast;
|
||||||
|
|
||||||
|
gp_Pnt2d p2d(s,t);
|
||||||
|
classifier.Perform(face,p2d,1.0e-4);
|
||||||
|
if (classifier.State() == TopAbs_IN || classifier.State() == TopAbs_ON) {
|
||||||
|
gp_Pnt p = surface.Value(s,t);
|
||||||
|
Points.push_back(Base::convertTo<Base::Vector3d>(p));
|
||||||
|
gp_Dir normal;
|
||||||
|
if (GeomLib::NormEstim(aSurf, p2d, Precision::Confusion(), normal) <= 1) {
|
||||||
|
Normals.push_back(Base::convertTo<Base::Vector3d>(normal));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Normals.push_back(Base::Vector3d(0,0,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no faces are found then the normals can be cleared
|
||||||
|
if (!hasFaces)
|
||||||
|
Normals.clear();
|
||||||
|
}
|
||||||
|
|
|
@ -200,7 +200,11 @@ public:
|
||||||
|
|
||||||
/** @name Getting basic geometric entities */
|
/** @name Getting basic geometric entities */
|
||||||
//@{
|
//@{
|
||||||
void getFaces(std::vector<Base::Vector3d> &Points,std::vector<Facet> &faces,
|
/** Get points from object with given accuracy */
|
||||||
|
virtual void getPoints(std::vector<Base::Vector3d> &Points,
|
||||||
|
std::vector<Base::Vector3d> &Normals,
|
||||||
|
float Accuracy, uint16_t flags=0) const;
|
||||||
|
virtual void getFaces(std::vector<Base::Vector3d> &Points,std::vector<Facet> &faces,
|
||||||
float Accuracy, uint16_t flags=0) const;
|
float Accuracy, uint16_t flags=0) const;
|
||||||
void setFaces(const std::vector<Base::Vector3d> &Points,
|
void setFaces(const std::vector<Base::Vector3d> &Points,
|
||||||
const std::vector<Facet> &faces, float Accuracy=1.0e-06);
|
const std::vector<Facet> &faces, float Accuracy=1.0e-06);
|
||||||
|
|
|
@ -24,9 +24,8 @@
|
||||||
#include "PreCompiled.h"
|
#include "PreCompiled.h"
|
||||||
#ifndef _PreComp_
|
#ifndef _PreComp_
|
||||||
# include <algorithm>
|
# include <algorithm>
|
||||||
# include <qaction.h>
|
# include <QFileInfo>
|
||||||
# include <qdir.h>
|
# include <QInputDialog>
|
||||||
# include <qfileinfo.h>
|
|
||||||
# include <Inventor/events/SoMouseButtonEvent.h>
|
# include <Inventor/events/SoMouseButtonEvent.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -42,6 +41,7 @@
|
||||||
#include <Gui/ViewProvider.h>
|
#include <Gui/ViewProvider.h>
|
||||||
#include <Gui/View3DInventor.h>
|
#include <Gui/View3DInventor.h>
|
||||||
#include <Gui/View3DInventorViewer.h>
|
#include <Gui/View3DInventorViewer.h>
|
||||||
|
#include <Gui/WaitCursor.h>
|
||||||
|
|
||||||
#include "../App/PointsFeature.h"
|
#include "../App/PointsFeature.h"
|
||||||
#include "../App/Properties.h"
|
#include "../App/Properties.h"
|
||||||
|
@ -182,7 +182,7 @@ CmdPointsConvert::CmdPointsConvert()
|
||||||
{
|
{
|
||||||
sAppModule = "Points";
|
sAppModule = "Points";
|
||||||
sGroup = QT_TR_NOOP("Points");
|
sGroup = QT_TR_NOOP("Points");
|
||||||
sMenuText = QT_TR_NOOP("Convert to points");
|
sMenuText = QT_TR_NOOP("Convert to points...");
|
||||||
sToolTipText = QT_TR_NOOP("Convert to points");
|
sToolTipText = QT_TR_NOOP("Convert to points");
|
||||||
sWhatsThis = QT_TR_NOOP("Convert to points");
|
sWhatsThis = QT_TR_NOOP("Convert to points");
|
||||||
sStatusTip = QT_TR_NOOP("Convert to points");
|
sStatusTip = QT_TR_NOOP("Convert to points");
|
||||||
|
@ -190,15 +190,32 @@ CmdPointsConvert::CmdPointsConvert()
|
||||||
|
|
||||||
void CmdPointsConvert::activated(int iMsg)
|
void CmdPointsConvert::activated(int iMsg)
|
||||||
{
|
{
|
||||||
|
bool ok;
|
||||||
|
double tol = QInputDialog::getDouble(Gui::getMainWindow(), QObject::tr("Distance"),
|
||||||
|
QObject::tr("Enter maximum distance:"), 0.1, 0.05, 10.0, 2, &ok);
|
||||||
|
if (!ok)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Gui::WaitCursor wc;
|
||||||
openCommand("Convert to points");
|
openCommand("Convert to points");
|
||||||
std::vector<App::DocumentObject*> meshes = getSelection().getObjectsOfType(Base::Type::fromName("Mesh::Feature"));
|
std::vector<App::DocumentObject*> geoObject = getSelection().getObjectsOfType(Base::Type::fromName("App::GeoFeature"));
|
||||||
for (std::vector<App::DocumentObject*>::iterator it = meshes.begin(); it != meshes.end(); ++it) {
|
|
||||||
App::PropertyComplexGeoData* prop = dynamic_cast<App::PropertyComplexGeoData*>((*it)->getPropertyByName("Mesh"));
|
bool addedPoints = false;
|
||||||
|
for (std::vector<App::DocumentObject*>::iterator it = geoObject.begin(); it != geoObject.end(); ++it) {
|
||||||
|
App::PropertyComplexGeoData* prop = 0;
|
||||||
|
|
||||||
|
// a cad shape?
|
||||||
|
if ((*it)->isDerivedFrom(Base::Type::fromName("Part::Feature")))
|
||||||
|
prop = dynamic_cast<App::PropertyComplexGeoData*>((*it)->getPropertyByName("Shape"));
|
||||||
|
// a mesh?
|
||||||
|
else if ((*it)->isDerivedFrom(Base::Type::fromName("Mesh::Feature")))
|
||||||
|
prop = dynamic_cast<App::PropertyComplexGeoData*>((*it)->getPropertyByName("Mesh"));
|
||||||
|
|
||||||
if (prop) {
|
if (prop) {
|
||||||
const Data::ComplexGeoData* data = prop->getComplexData();
|
const Data::ComplexGeoData* data = prop->getComplexData();
|
||||||
std::vector<Base::Vector3d> vertexes;
|
std::vector<Base::Vector3d> vertexes;
|
||||||
std::vector<Base::Vector3d> normals;
|
std::vector<Base::Vector3d> normals;
|
||||||
data->getPoints(vertexes, normals, 0.0f);
|
data->getPoints(vertexes, normals, static_cast<float>(tol));
|
||||||
if (!vertexes.empty()) {
|
if (!vertexes.empty()) {
|
||||||
Points::Feature* fea = 0;
|
Points::Feature* fea = 0;
|
||||||
if (vertexes.size() == normals.size()) {
|
if (vertexes.size() == normals.size()) {
|
||||||
|
@ -228,15 +245,20 @@ void CmdPointsConvert::activated(int iMsg)
|
||||||
|
|
||||||
App::Document* doc = (*it)->getDocument();
|
App::Document* doc = (*it)->getDocument();
|
||||||
doc->addObject(fea, "Points");
|
doc->addObject(fea, "Points");
|
||||||
|
addedPoints = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addedPoints)
|
||||||
commitCommand();
|
commitCommand();
|
||||||
|
else
|
||||||
|
abortCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CmdPointsConvert::isActive(void)
|
bool CmdPointsConvert::isActive(void)
|
||||||
{
|
{
|
||||||
return getSelection().countObjectsOfType(Base::Type::fromName("Mesh::Feature")) > 0;
|
return getSelection().countObjectsOfType(Base::Type::fromName("App::GeoFeature")) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_STD_CMD_A(CmdPointsPolyCut);
|
DEF_STD_CMD_A(CmdPointsPolyCut);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user