compute signed distances of points to shape, show results of visual inspection for point clouds
This commit is contained in:
parent
7943ce4ce4
commit
0ad93186b5
|
@ -25,6 +25,9 @@
|
|||
#include <gp_Pnt.hxx>
|
||||
#include <BRepExtrema_DistShapeShape.hxx>
|
||||
#include <BRepBuilderAPI_MakeVertex.hxx>
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
#include <BRepGProp_Face.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
#include <QEventLoop>
|
||||
|
@ -419,10 +422,24 @@ float InspectNominalPoints::getDistance(const Base::Vector3f& point)
|
|||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
InspectNominalShape::InspectNominalShape(const TopoDS_Shape& shape, float /*radius*/) : _rShape(shape)
|
||||
InspectNominalShape::InspectNominalShape(const TopoDS_Shape& shape, float /*radius*/)
|
||||
: _rShape(shape)
|
||||
, isSolid(false)
|
||||
{
|
||||
distss = new BRepExtrema_DistShapeShape();
|
||||
distss->LoadS1(_rShape);
|
||||
|
||||
// When having a solid then use its shell because otherwise the distance
|
||||
// for inner points will always be zero
|
||||
if (!_rShape.IsNull() && _rShape.ShapeType() == TopAbs_SOLID) {
|
||||
TopExp_Explorer xp;
|
||||
xp.Init(_rShape, TopAbs_SHELL);
|
||||
if (xp.More()) {
|
||||
distss->LoadS1(xp.Current());
|
||||
isSolid = true;
|
||||
}
|
||||
|
||||
}
|
||||
//distss->SetDeflection(radius);
|
||||
}
|
||||
|
||||
|
@ -433,11 +450,45 @@ InspectNominalShape::~InspectNominalShape()
|
|||
|
||||
float InspectNominalShape::getDistance(const Base::Vector3f& point)
|
||||
{
|
||||
BRepBuilderAPI_MakeVertex mkVert(gp_Pnt(point.x,point.y,point.z));
|
||||
gp_Pnt pnt3d(point.x,point.y,point.z);
|
||||
BRepBuilderAPI_MakeVertex mkVert(pnt3d);
|
||||
distss->LoadS2(mkVert.Vertex());
|
||||
|
||||
float fMinDist=FLT_MAX;
|
||||
if (distss->Perform() && distss->NbSolution() > 0)
|
||||
if (distss->Perform() && distss->NbSolution() > 0) {
|
||||
fMinDist = (float)distss->Value();
|
||||
// the shape is a solid, check if the vertex is inside
|
||||
if (isSolid) {
|
||||
const Standard_Real tol = 0.001;
|
||||
BRepClass3d_SolidClassifier classifier(_rShape);
|
||||
classifier.Perform(pnt3d, tol);
|
||||
if (classifier.State() == TopAbs_IN) {
|
||||
fMinDist = -fMinDist;
|
||||
}
|
||||
|
||||
}
|
||||
else if (fMinDist > 0) {
|
||||
// check if the distance was compued from a face
|
||||
for (Standard_Integer index = 1; index <= distss->NbSolution(); index++) {
|
||||
if (distss->SupportTypeShape1(index) == BRepExtrema_IsInFace) {
|
||||
TopoDS_Shape face = distss->SupportOnShape1(index);
|
||||
Standard_Real u, v;
|
||||
distss->ParOnFaceS1(index, u, v);
|
||||
//gp_Pnt pnt = distss->PointOnShape1(index);
|
||||
BRepGProp_Face props(TopoDS::Face(face));
|
||||
gp_Vec normal;
|
||||
gp_Pnt center;
|
||||
props.Normal(u, v, center, normal);
|
||||
gp_Vec dir(center, pnt3d);
|
||||
Standard_Real scalar = normal.Dot(dir);
|
||||
if (scalar < 0) {
|
||||
fMinDist = -fMinDist;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fMinDist;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,7 @@ public:
|
|||
private:
|
||||
BRepExtrema_DistShapeShape* distss;
|
||||
const TopoDS_Shape& _rShape;
|
||||
bool isSolid;
|
||||
};
|
||||
|
||||
class InspectionExport PropertyDistanceList: public App::PropertyLists
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <Inventor/nodes/SoShapeHints.h>
|
||||
#include <Inventor/nodes/SoOrthographicCamera.h>
|
||||
#include <Inventor/nodes/SoMaterialBinding.h>
|
||||
#include <Inventor/nodes/SoNormal.h>
|
||||
#include <Inventor/errors/SoDebugError.h>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
|
@ -191,68 +192,83 @@ void ViewProviderInspection::updateData(const App::Property* prop)
|
|||
Base::Type pointId = Base::Type::fromName("Points::Feature");
|
||||
Base::Type propId = App::PropertyComplexGeoData::getClassTypeId();
|
||||
|
||||
std::vector<Base::Vector3d> points;
|
||||
std::vector<Base::Vector3d> normals;
|
||||
std::vector<Data::ComplexGeoData::Facet> faces;
|
||||
|
||||
// set the Distance property to the correct size to sync size of material node with number
|
||||
// of vertices/points of the referenced geometry
|
||||
const Data::ComplexGeoData* data = 0;
|
||||
if (object->getTypeId().isDerivedFrom(meshId)) {
|
||||
App::Property* prop = object->getPropertyByName("Mesh");
|
||||
if (prop && prop->getTypeId().isDerivedFrom(propId)) {
|
||||
data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
|
||||
const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
|
||||
data->getFaces(points, faces, accuracy);
|
||||
}
|
||||
}
|
||||
else if (object->getTypeId().isDerivedFrom(shapeId)) {
|
||||
App::Property* prop = object->getPropertyByName("Shape");
|
||||
if (prop && prop->getTypeId().isDerivedFrom(propId)) {
|
||||
data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
|
||||
const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Mod/Part");
|
||||
float deviation = hGrp->GetFloat("MeshDeviation",0.2);
|
||||
|
||||
Base::BoundBox3d bbox = data->getBoundBox();
|
||||
accuracy = (float)((bbox.LengthX() + bbox.LengthY() + bbox.LengthZ())/300.0 * deviation);
|
||||
data->getFaces(points, faces, accuracy);
|
||||
}
|
||||
}
|
||||
else if (object->getTypeId().isDerivedFrom(pointId)) {
|
||||
App::Property* prop = object->getPropertyByName("Points");
|
||||
if (prop && prop->getTypeId().isDerivedFrom(propId)) {
|
||||
data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
|
||||
const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(prop)->getComplexData();
|
||||
data->getPoints(points, normals, accuracy);
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
this->pcLinkRoot->removeAllChildren();
|
||||
std::vector<Base::Vector3d> points;
|
||||
std::vector<Data::ComplexGeoData::Facet> faces;
|
||||
data->getFaces(points, faces, accuracy);
|
||||
this->pcLinkRoot->removeAllChildren();
|
||||
this->pcLinkRoot->addChild(this->pcCoords);
|
||||
this->pcCoords->point.setNum(points.size());
|
||||
SbVec3f* pts = this->pcCoords->point.startEditing();
|
||||
for (size_t i=0; i < points.size(); i++) {
|
||||
const Base::Vector3d& p = points[i];
|
||||
pts[i].setValue((float)p.x,(float)p.y,(float)p.z);
|
||||
}
|
||||
this->pcCoords->point.finishEditing();
|
||||
|
||||
this->pcLinkRoot->addChild(this->pcCoords);
|
||||
this->pcCoords->point.setNum(points.size());
|
||||
SbVec3f* pts = this->pcCoords->point.startEditing();
|
||||
for (size_t i=0; i < points.size(); i++) {
|
||||
const Base::Vector3d& p = points[i];
|
||||
pts[i].setValue((float)p.x,(float)p.y,(float)p.z);
|
||||
if (!faces.empty()) {
|
||||
SoIndexedFaceSet* face = new SoIndexedFaceSet();
|
||||
this->pcLinkRoot->addChild(face);
|
||||
face->coordIndex.setNum(4*faces.size());
|
||||
int32_t* indices = face->coordIndex.startEditing();
|
||||
unsigned long j=0;
|
||||
std::vector<Data::ComplexGeoData::Facet>::iterator it;
|
||||
for (it = faces.begin(); it != faces.end(); ++it,j++) {
|
||||
indices[4*j+0] = it->I1;
|
||||
indices[4*j+1] = it->I2;
|
||||
indices[4*j+2] = it->I3;
|
||||
indices[4*j+3] = SO_END_FACE_INDEX;
|
||||
}
|
||||
this->pcCoords->point.finishEditing();
|
||||
face->coordIndex.finishEditing();
|
||||
}
|
||||
else {
|
||||
if (!normals.empty() && normals.size() == points.size()) {
|
||||
SoNormal* normalNode = new SoNormal();
|
||||
normalNode->vector.setNum(normals.size());
|
||||
SbVec3f* norm = normalNode->vector.startEditing();
|
||||
|
||||
if (!faces.empty()) {
|
||||
SoIndexedFaceSet* face = new SoIndexedFaceSet();
|
||||
this->pcLinkRoot->addChild(face);
|
||||
face->coordIndex.setNum(4*faces.size());
|
||||
int32_t* indices = face->coordIndex.startEditing();
|
||||
unsigned long j=0;
|
||||
std::vector<Data::ComplexGeoData::Facet>::iterator it;
|
||||
for (it = faces.begin(); it != faces.end(); ++it,j++) {
|
||||
indices[4*j+0] = it->I1;
|
||||
indices[4*j+1] = it->I2;
|
||||
indices[4*j+2] = it->I3;
|
||||
indices[4*j+3] = SO_END_FACE_INDEX;
|
||||
std::size_t i=0;
|
||||
for (std::vector<Base::Vector3d>::const_iterator it = normals.begin(); it != normals.end(); ++it) {
|
||||
norm[i++].setValue(static_cast<float>(it->x),
|
||||
static_cast<float>(it->y),
|
||||
static_cast<float>(it->z));
|
||||
}
|
||||
face->coordIndex.finishEditing();
|
||||
}
|
||||
else {
|
||||
this->pcLinkRoot->addChild(this->pcPointStyle);
|
||||
this->pcLinkRoot->addChild(new SoPointSet());
|
||||
|
||||
normalNode->vector.finishEditing();
|
||||
this->pcLinkRoot->addChild(normalNode);
|
||||
}
|
||||
this->pcLinkRoot->addChild(this->pcPointStyle);
|
||||
this->pcLinkRoot->addChild(new SoPointSet());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user