Inspection: support display of lines, avoid explicit type checks

This commit is contained in:
wmayer
2022-09-15 11:46:20 +02:00
parent 1309b86ea5
commit 7dc67b7a01
4 changed files with 157 additions and 92 deletions

View File

@@ -116,14 +116,18 @@ void InspectActualShape::fetchPoints(double deflection)
TopTools_IndexedMapOfShape mapOfShapes;
TopExp::MapShapes(_rShape.getShape(), TopAbs_FACE, mapOfShapes);
if (!mapOfShapes.IsEmpty()) {
std::vector<Data::ComplexGeoData::Facet> f;
_rShape.getFaces(points, f, deflection);
std::vector<Data::ComplexGeoData::Facet> faces;
_rShape.getFaces(points, faces, deflection);
}
else {
TopExp::MapShapes(_rShape.getShape(), TopAbs_EDGE, mapOfShapes);
if (!mapOfShapes.IsEmpty()) {
std::vector<Base::Vector3d> n;
_rShape.getPoints(points, n, deflection);
std::vector<Data::ComplexGeoData::Line> lines;
_rShape.getLines(points, lines, deflection);
}
else {
std::vector<Base::Vector3d> normals;
_rShape.getPoints(points, normals, deflection);
}
}
}

View File

@@ -38,6 +38,7 @@
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoIndexedFaceSet.h>
#include <Inventor/nodes/SoIndexedLineSet.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoMaterialBinding.h>
#include <Inventor/nodes/SoNormal.h>
@@ -182,101 +183,149 @@ void ViewProviderInspection::attach(App::DocumentObject *pcFeat)
pcColorRoot->addChild(pcColorBar);
}
bool ViewProviderInspection::setupFaces(const Data::ComplexGeoData* data)
{
std::vector<Base::Vector3d> points;
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
double accuracy = data->getAccuracy();
data->getFaces(points, faces, accuracy);
if (faces.empty()) {
return false;
}
setupCoords(points);
setupFaceIndexes(faces);
return true;
}
bool ViewProviderInspection::setupLines(const Data::ComplexGeoData* data)
{
std::vector<Base::Vector3d> points;
std::vector<Data::ComplexGeoData::Line> lines;
double accuracy = data->getAccuracy();
data->getLines(points, lines, accuracy);
if (lines.empty()) {
return false;
}
setupCoords(points);
setupLineIndexes(lines);
return true;
}
bool ViewProviderInspection::setupPoints(const Data::ComplexGeoData* data, App::PropertyContainer* container)
{
std::vector<Base::Vector3d> points;
std::vector<Base::Vector3f> normals;
std::vector<Base::Vector3d> normals_d;
double accuracy = data->getAccuracy();
data->getPoints(points, normals_d, accuracy);
if (points.empty()) {
return false;
}
normals.reserve(normals_d.size());
std::transform(normals_d.cbegin(), normals_d.cend(), std::back_inserter(normals), [](const Base::Vector3d& p){
return Base::toVector<float>(p);
});
// If getPoints() doesn't deliver normals check a second property
if (normals.empty() && container) {
App::Property* propN = container->getPropertyByName("Normal");
if (propN && propN->getTypeId().isDerivedFrom(Points::PropertyNormalList::getClassTypeId())) {
normals = static_cast<Points::PropertyNormalList*>(propN)->getValues();
}
}
setupCoords(points);
if (!normals.empty() && normals.size() == points.size()) {
setupNormals(normals);
}
this->pcLinkRoot->addChild(this->pcPointStyle);
this->pcLinkRoot->addChild(new SoPointSet());
return true;
}
void ViewProviderInspection::setupCoords(const std::vector<Base::Vector3d>& points)
{
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();
}
void ViewProviderInspection::setupNormals(const std::vector<Base::Vector3f>& normals)
{
SoNormal* normalNode = new SoNormal();
normalNode->vector.setNum(normals.size());
SbVec3f* norm = normalNode->vector.startEditing();
std::size_t i=0;
for (std::vector<Base::Vector3f>::const_iterator it = normals.begin(); it != normals.end(); ++it) {
norm[i++].setValue(it->x, it->y, it->z);
}
normalNode->vector.finishEditing();
this->pcLinkRoot->addChild(normalNode);
}
void ViewProviderInspection::setupLineIndexes(const std::vector<Data::ComplexGeoData::Line>& lines)
{
SoIndexedLineSet* line = new SoIndexedLineSet();
this->pcLinkRoot->addChild(line);
line->coordIndex.setNum(3 * lines.size());
int32_t* indices = line->coordIndex.startEditing();
unsigned long j=0;
for (const auto& it : lines) {
indices[3*j+0] = it.I1;
indices[3*j+1] = it.I2;
indices[3*j+2] = SO_END_LINE_INDEX;
j++;
}
line->coordIndex.finishEditing();
}
void ViewProviderInspection::setupFaceIndexes(const std::vector<Data::ComplexGeoData::Facet>& faces)
{
SoIndexedFaceSet* face = new SoIndexedFaceSet();
this->pcLinkRoot->addChild(face);
face->coordIndex.setNum(4*faces.size());
int32_t* indices = face->coordIndex.startEditing();
unsigned long j=0;
for (const auto& it : faces) {
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;
j++;
}
face->coordIndex.finishEditing();
}
void ViewProviderInspection::updateData(const App::Property* prop)
{
// set to the expected size
if (prop->getTypeId().isDerivedFrom(App::PropertyLink::getClassTypeId())) {
App::GeoFeature* object = static_cast<const App::PropertyLink*>(prop)->getValue<App::GeoFeature*>();
if (object) {
double accuracy = 0.0;
Base::Type meshId = Base::Type::fromName("Mesh::Feature");
Base::Type shapeId = Base::Type::fromName("Part::Feature");
Base::Type pointId = Base::Type::fromName("Points::Feature");
Base::Type propId = App::PropertyComplexGeoData::getClassTypeId();
std::vector<Base::Vector3d> points;
std::vector<Base::Vector3f> 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
if (object->getTypeId().isDerivedFrom(meshId)) {
App::Property* propM = object->getPropertyByName("Mesh");
if (propM && propM->getTypeId().isDerivedFrom(propId)) {
const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(propM)->getComplexData();
data->getFaces(points, faces, accuracy);
}
}
else if (object->getTypeId().isDerivedFrom(shapeId)) {
App::Property* propS = object->getPropertyByName("Shape");
if (propS && propS->getTypeId().isDerivedFrom(propId)) {
const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(propS)->getComplexData();
accuracy = data->getAccuracy();
data->getFaces(points, faces, accuracy);
if (points.empty()) {
std::vector<Base::Vector3d> normals_d;
data->getPoints(points, normals_d, accuracy);
normals.reserve(normals_d.size());
std::transform(normals_d.cbegin(), normals_d.cend(), std::back_inserter(normals), [](const Base::Vector3d& p){
return Base::toVector<float>(p);
});
}
}
}
else if (object->getTypeId().isDerivedFrom(pointId)) {
App::Property* propP = object->getPropertyByName("Points");
if (propP && propP->getTypeId().isDerivedFrom(propId)) {
const Data::ComplexGeoData* data = static_cast<App::PropertyComplexGeoData*>(propP)->getComplexData();
std::vector<Base::Vector3d> normals;
data->getPoints(points, normals, accuracy);
}
App::Property* propN = object->getPropertyByName("Normal");
if (propN && propN->getTypeId().isDerivedFrom(Points::PropertyNormalList::getClassTypeId())) {
normals = static_cast<Points::PropertyNormalList*>(propN)->getValues();
}
}
const App::PropertyComplexGeoData* propData = object ? object->getPropertyOfGeometry() : nullptr;
if (propData) {
Gui::coinRemoveAllChildren(this->pcLinkRoot);
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();
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;
const Data::ComplexGeoData* data = propData->getComplexData();
if (!setupFaces(data)) {
if (!setupLines(data)) {
setupPoints(data, object);
}
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();
std::size_t i=0;
for (std::vector<Base::Vector3f>::const_iterator it = normals.begin(); it != normals.end(); ++it) {
norm[i++].setValue(it->x, it->y, it->z);
}
normalNode->vector.finishEditing();
this->pcLinkRoot->addChild(normalNode);
}
this->pcLinkRoot->addChild(this->pcPointStyle);
this->pcLinkRoot->addChild(new SoPointSet());
}
}
}

View File

@@ -25,6 +25,7 @@
#define INSPECTIOGUI_VIEWPROVIDERINSPECTION_H
#include <Base/Observer.h>
#include <App/ComplexGeoData.h>
#include <Gui/ViewProviderDocumentObject.h>
#include <Gui/ViewProviderDocumentObjectGroup.h>
@@ -82,6 +83,15 @@ protected:
void setDistances();
QString inspectDistance(const SoPickedPoint* pp) const;
private:
bool setupFaces(const Data::ComplexGeoData*);
bool setupLines(const Data::ComplexGeoData*);
bool setupPoints(const Data::ComplexGeoData*, App::PropertyContainer* container);
void setupCoords(const std::vector<Base::Vector3d>&);
void setupNormals(const std::vector<Base::Vector3f>&);
void setupLineIndexes(const std::vector<Data::ComplexGeoData::Line>&);
void setupFaceIndexes(const std::vector<Data::ComplexGeoData::Facet>&);
protected:
SoMaterial * pcColorMat;
SoMaterialBinding* pcMatBinding;

View File

@@ -3491,7 +3491,9 @@ double TopoShape::getAccuracy() const
{
double deviation = 0.2;
Base::BoundBox3d bbox = getBoundBox();
return ((bbox.LengthX() + bbox.LengthY() + bbox.LengthZ())/300.0 * deviation);
if (bbox.IsValid())
return ((bbox.LengthX() + bbox.LengthY() + bbox.LengthZ())/300.0 * deviation);
return ComplexGeoData::getAccuracy();
}
void TopoShape::getFaces(std::vector<Base::Vector3d> &aPoints,