PD: simplify code to display rejected shape and move it to its own function
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include <Mod/Part/App/Tools.h>
|
||||
#include <Mod/PartDesign/App/FeatureTransformed.h>
|
||||
#include <Mod/PartDesign/App/FeatureAddSub.h>
|
||||
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
|
||||
@@ -198,162 +199,131 @@ void ViewProviderTransformed::recomputeFeature(bool recompute)
|
||||
}
|
||||
|
||||
// Display the rejected transformations in red
|
||||
|
||||
if (rejected > 0) {
|
||||
try {
|
||||
// calculating the deflection value
|
||||
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
|
||||
{
|
||||
Bnd_Box bounds;
|
||||
BRepBndLib::Add(cShape, bounds);
|
||||
bounds.SetGap(0.0);
|
||||
bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
}
|
||||
Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue();
|
||||
|
||||
// create or use the mesh on the data structure
|
||||
// Note: This DOES have an effect on cShape
|
||||
#if OCC_VERSION_HEX >= 0x060600
|
||||
Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI;
|
||||
BRepMesh_IncrementalMesh(cShape,deflection,Standard_False,
|
||||
AngDeflectionRads,Standard_True);
|
||||
#else
|
||||
BRepMesh_IncrementalMesh(cShape,deflection);
|
||||
#endif
|
||||
// We must reset the location here because the transformation data
|
||||
// are set in the placement property
|
||||
TopLoc_Location aLoc;
|
||||
cShape.Location(aLoc);
|
||||
|
||||
// count triangles and nodes in the mesh
|
||||
int nbrTriangles=0, nbrNodes=0;
|
||||
TopExp_Explorer Ex;
|
||||
for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) {
|
||||
Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc);
|
||||
// Note: we must also count empty faces
|
||||
if (!mesh.IsNull()) {
|
||||
nbrTriangles += mesh->NbTriangles();
|
||||
nbrNodes += mesh->NbNodes();
|
||||
}
|
||||
}
|
||||
|
||||
// create memory for the nodes and indexes
|
||||
SoCoordinate3* rejectedCoords = new SoCoordinate3();
|
||||
rejectedCoords ->point .setNum(nbrNodes);
|
||||
SoNormal* rejectedNorms = new SoNormal();
|
||||
rejectedNorms ->vector .setNum(nbrNodes);
|
||||
SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet();
|
||||
rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4);
|
||||
|
||||
// get the raw memory for fast fill up
|
||||
SbVec3f* verts = rejectedCoords ->point .startEditing();
|
||||
SbVec3f* norms = rejectedNorms ->vector .startEditing();
|
||||
int32_t* index = rejectedFaceSet ->coordIndex .startEditing();
|
||||
|
||||
// preset the normal vector with null vector
|
||||
for (int i=0; i < nbrNodes; i++)
|
||||
norms[i]= SbVec3f(0.0,0.0,0.0);
|
||||
|
||||
int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0;
|
||||
for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) {
|
||||
TopLoc_Location aLoc;
|
||||
const TopoDS_Face &actFace = TopoDS::Face(Ex.Current());
|
||||
// get the mesh of the shape
|
||||
Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc);
|
||||
if (mesh.IsNull()) continue;
|
||||
|
||||
// getting the transformation of the shape/face
|
||||
gp_Trsf myTransf;
|
||||
Standard_Boolean identity = true;
|
||||
if (!aLoc.IsIdentity()) {
|
||||
identity = false;
|
||||
myTransf = aLoc.Transformation();
|
||||
}
|
||||
|
||||
// getting size of node and triangle array of this face
|
||||
int nbNodesInFace = mesh->NbNodes();
|
||||
int nbTriInFace = mesh->NbTriangles();
|
||||
// check orientation
|
||||
TopAbs_Orientation orient = actFace.Orientation();
|
||||
|
||||
// cycling through the poly mesh
|
||||
const Poly_Array1OfTriangle& Triangles = mesh->Triangles();
|
||||
const TColgp_Array1OfPnt& Nodes = mesh->Nodes();
|
||||
for (int g=1; g <= nbTriInFace; g++) {
|
||||
// Get the triangle
|
||||
Standard_Integer N1,N2,N3;
|
||||
Triangles(g).Get(N1,N2,N3);
|
||||
|
||||
// change orientation of the triangle if the face is reversed
|
||||
if ( orient != TopAbs_FORWARD ) {
|
||||
Standard_Integer tmp = N1;
|
||||
N1 = N2;
|
||||
N2 = tmp;
|
||||
}
|
||||
|
||||
// get the 3 points of this triangle
|
||||
gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3));
|
||||
|
||||
// transform the vertices to the place of the face
|
||||
if (!identity) {
|
||||
V1.Transform(myTransf);
|
||||
V2.Transform(myTransf);
|
||||
V3.Transform(myTransf);
|
||||
}
|
||||
|
||||
// calculating per vertex normals
|
||||
// Calculate triangle normal
|
||||
gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
|
||||
gp_Vec Normal = (v2-v1)^(v3-v1);
|
||||
|
||||
// add the triangle normal to the vertex normal for all points of this triangle
|
||||
norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
|
||||
norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
|
||||
norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z());
|
||||
|
||||
// set the vertices
|
||||
verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z()));
|
||||
verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z()));
|
||||
verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z()));
|
||||
|
||||
// set the index vector with the 3 point indexes and the end delimiter
|
||||
index[FaceTriaOffset*4+4*(g-1)] = FaceNodeOffset+N1-1;
|
||||
index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1;
|
||||
index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1;
|
||||
index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX;
|
||||
}
|
||||
|
||||
// counting up the per Face offsets
|
||||
FaceNodeOffset += nbNodesInFace;
|
||||
FaceTriaOffset += nbTriInFace;
|
||||
|
||||
|
||||
// normalize all normals
|
||||
for (int i=0; i < nbrNodes; i++)
|
||||
norms[i].normalize();
|
||||
|
||||
// end the editing of the nodes
|
||||
rejectedCoords ->point .finishEditing();
|
||||
rejectedNorms ->vector .finishEditing();
|
||||
rejectedFaceSet ->coordIndex .finishEditing();
|
||||
|
||||
// fill in the transformation matrices
|
||||
SoMultipleCopy* rejectedTrfms = new SoMultipleCopy();
|
||||
|
||||
|
||||
rejectedTrfms->matrix.finishEditing();
|
||||
rejectedTrfms->addChild(rejectedFaceSet);
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
sep->addChild(rejectedCoords);
|
||||
sep->addChild(rejectedNorms);
|
||||
sep->addChild(rejectedTrfms);
|
||||
pcRejectedRoot->addChild(sep);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n",
|
||||
pcTransformed->getNameInDocument());
|
||||
}
|
||||
showRejectedShape(cShape);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderTransformed::showRejectedShape(TopoDS_Shape shape)
|
||||
{
|
||||
try {
|
||||
// calculating the deflection value
|
||||
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
|
||||
{
|
||||
Bnd_Box bounds;
|
||||
BRepBndLib::Add(shape, bounds);
|
||||
bounds.SetGap(0.0);
|
||||
bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
}
|
||||
Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue();
|
||||
|
||||
// create or use the mesh on the data structure
|
||||
// Note: This DOES have an effect on shape
|
||||
#if OCC_VERSION_HEX >= 0x060600
|
||||
Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI;
|
||||
BRepMesh_IncrementalMesh(shape, deflection, Standard_False, AngDeflectionRads, Standard_True);
|
||||
#else
|
||||
BRepMesh_IncrementalMesh(shape, deflection);
|
||||
#endif
|
||||
// We must reset the location here because the transformation data
|
||||
// are set in the placement property
|
||||
TopLoc_Location aLoc;
|
||||
shape.Location(aLoc);
|
||||
|
||||
// count triangles and nodes in the mesh
|
||||
int nbrTriangles=0, nbrNodes=0;
|
||||
TopExp_Explorer Ex;
|
||||
for (Ex.Init(shape, TopAbs_FACE); Ex.More(); Ex.Next()) {
|
||||
Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc);
|
||||
// Note: we must also count empty faces
|
||||
if (!mesh.IsNull()) {
|
||||
nbrTriangles += mesh->NbTriangles();
|
||||
nbrNodes += mesh->NbNodes();
|
||||
}
|
||||
}
|
||||
|
||||
// create memory for the nodes and indexes
|
||||
SoCoordinate3* rejectedCoords = new SoCoordinate3();
|
||||
rejectedCoords ->point .setNum(nbrNodes);
|
||||
SoNormal* rejectedNorms = new SoNormal();
|
||||
rejectedNorms ->vector .setNum(nbrNodes);
|
||||
SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet();
|
||||
rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4);
|
||||
|
||||
// get the raw memory for fast fill up
|
||||
SbVec3f* verts = rejectedCoords ->point .startEditing();
|
||||
SbVec3f* norms = rejectedNorms ->vector .startEditing();
|
||||
int32_t* index = rejectedFaceSet ->coordIndex .startEditing();
|
||||
|
||||
// preset the normal vector with null vector
|
||||
for (int i=0; i < nbrNodes; i++)
|
||||
norms[i]= SbVec3f(0.0,0.0,0.0);
|
||||
|
||||
int FaceNodeOffset=0,FaceTriaOffset=0;
|
||||
for (Ex.Init(shape, TopAbs_FACE); Ex.More(); Ex.Next()) {
|
||||
const TopoDS_Face &actFace = TopoDS::Face(Ex.Current());
|
||||
|
||||
// get triangulation
|
||||
std::vector<gp_Pnt> points;
|
||||
std::vector<Poly_Triangle> facets;
|
||||
if (!Part::Tools::getTriangulation(actFace, points, facets))
|
||||
continue;
|
||||
|
||||
// get normal per vertex
|
||||
std::vector<gp_Vec> vertexnormals;
|
||||
Part::Tools::getPointNormals(points, facets, vertexnormals);
|
||||
|
||||
// getting size of node and triangle array of this face
|
||||
std::size_t nbNodesInFace = points.size();
|
||||
std::size_t nbTriInFace = facets.size();
|
||||
|
||||
for (std::size_t i = 0; i < points.size(); i++) {
|
||||
verts[FaceNodeOffset+i] = SbVec3f(points[i].X(), points[i].Y(), points[i].Z());
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < vertexnormals.size(); i++) {
|
||||
norms[FaceNodeOffset+i] = SbVec3f(vertexnormals[i].X(), vertexnormals[i].Y(), vertexnormals[i].Z());
|
||||
}
|
||||
|
||||
// cycling through the poly mesh
|
||||
for (std::size_t g=0; g < nbTriInFace; g++) {
|
||||
// Get the triangle
|
||||
Standard_Integer N1,N2,N3;
|
||||
facets[g].Get(N1,N2,N3);
|
||||
|
||||
// set the index vector with the 3 point indexes and the end delimiter
|
||||
index[FaceTriaOffset*4+4*g] = FaceNodeOffset+N1;
|
||||
index[FaceTriaOffset*4+4*g+1] = FaceNodeOffset+N2;
|
||||
index[FaceTriaOffset*4+4*g+2] = FaceNodeOffset+N3;
|
||||
index[FaceTriaOffset*4+4*g+3] = SO_END_FACE_INDEX;
|
||||
}
|
||||
|
||||
// counting up the per Face offsets
|
||||
FaceNodeOffset += nbNodesInFace;
|
||||
FaceTriaOffset += nbTriInFace;
|
||||
|
||||
// normalize all normals
|
||||
for (int i=0; i < nbrNodes; i++)
|
||||
norms[i].normalize();
|
||||
|
||||
// end the editing of the nodes
|
||||
rejectedCoords ->point .finishEditing();
|
||||
rejectedNorms ->vector .finishEditing();
|
||||
rejectedFaceSet ->coordIndex .finishEditing();
|
||||
|
||||
// fill in the transformation matrices
|
||||
SoMultipleCopy* rejectedTrfms = new SoMultipleCopy();
|
||||
rejectedTrfms->matrix.finishEditing();
|
||||
rejectedTrfms->addChild(rejectedFaceSet);
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
sep->addChild(rejectedCoords);
|
||||
sep->addChild(rejectedNorms);
|
||||
sep->addChild(rejectedTrfms);
|
||||
pcRejectedRoot->addChild(sep);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n",
|
||||
getObject()->getNameInDocument());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user