From d13afa7c3c46e131e744587e3e7540223b3fbcc3 Mon Sep 17 00:00:00 2001 From: logari81 Date: Wed, 13 Feb 2013 14:06:36 +0100 Subject: [PATCH] PartDesign: Highlight in red the rejected transformations when editing pattern features --- .../Gui/ViewProviderLinearPattern.cpp | 2 + .../PartDesign/Gui/ViewProviderMirrored.cpp | 2 + .../Gui/ViewProviderMultiTransform.cpp | 2 + .../Gui/ViewProviderPolarPattern.cpp | 2 + src/Mod/PartDesign/Gui/ViewProviderScaled.cpp | 2 + .../Gui/ViewProviderTransformed.cpp | 263 +++++++++++++++++- .../PartDesign/Gui/ViewProviderTransformed.h | 16 +- 7 files changed, 285 insertions(+), 4 deletions(-) diff --git a/src/Mod/PartDesign/Gui/ViewProviderLinearPattern.cpp b/src/Mod/PartDesign/Gui/ViewProviderLinearPattern.cpp index 393b9f2bf..cb0e256a9 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderLinearPattern.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderLinearPattern.cpp @@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderLinearPattern,PartDesignGui::ViewProv bool ViewProviderLinearPattern::setEdit(int ModNum) { + ViewProviderTransformed::setEdit(ModNum); + if (ModNum == ViewProvider::Default ) { TaskDlgLinearPatternParameters *linearpatternDlg = NULL; diff --git a/src/Mod/PartDesign/Gui/ViewProviderMirrored.cpp b/src/Mod/PartDesign/Gui/ViewProviderMirrored.cpp index 4bb9c794d..dece48ea2 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderMirrored.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderMirrored.cpp @@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderMirrored,PartDesignGui::ViewProvider) bool ViewProviderMirrored::setEdit(int ModNum) { + ViewProviderTransformed::setEdit(ModNum); + if (ModNum == ViewProvider::Default ) { TaskDlgMirroredParameters *mirroredDlg = NULL; diff --git a/src/Mod/PartDesign/Gui/ViewProviderMultiTransform.cpp b/src/Mod/PartDesign/Gui/ViewProviderMultiTransform.cpp index 3c17680ad..839e28ff0 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderMultiTransform.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderMultiTransform.cpp @@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderMultiTransform,PartDesignGui::ViewPro bool ViewProviderMultiTransform::setEdit(int ModNum) { + ViewProviderTransformed::setEdit(ModNum); + if (ModNum == ViewProvider::Default ) { TaskDlgMultiTransformParameters *multitransformDlg = NULL; diff --git a/src/Mod/PartDesign/Gui/ViewProviderPolarPattern.cpp b/src/Mod/PartDesign/Gui/ViewProviderPolarPattern.cpp index 48bc5d719..cafefd54d 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderPolarPattern.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderPolarPattern.cpp @@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderPolarPattern,PartDesignGui::ViewProvi bool ViewProviderPolarPattern::setEdit(int ModNum) { + ViewProviderTransformed::setEdit(ModNum); + if (ModNum == ViewProvider::Default ) { TaskDlgPolarPatternParameters *polarpatternDlg = NULL; diff --git a/src/Mod/PartDesign/Gui/ViewProviderScaled.cpp b/src/Mod/PartDesign/Gui/ViewProviderScaled.cpp index b704f4716..61df00ca4 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderScaled.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderScaled.cpp @@ -40,6 +40,8 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderScaled,PartDesignGui::ViewProvider) bool ViewProviderScaled::setEdit(int ModNum) { + ViewProviderTransformed::setEdit(ModNum); + if (ModNum == ViewProvider::Default ) { TaskDlgScaledParameters *scaledDlg = NULL; diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp index 5af43cd05..43e991b22 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp @@ -24,15 +24,34 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif #include "ViewProviderTransformed.h" #include "TaskTransformedParameters.h" -#include -#include +#include #include -#include #include +#include +#include +#include +#include using namespace PartDesignGui; @@ -46,6 +65,64 @@ void ViewProviderTransformed::setupContextMenu(QMenu* menu, QObject* receiver, c PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member); } +bool ViewProviderTransformed::setEdit(int ModNum) +{ + pcRejectedRoot = new SoSeparator(); + pcRejectedRoot->ref(); + + rejectedTrfms = new SoMultipleCopy(); + rejectedTrfms->ref(); + + rejectedCoords = new SoCoordinate3(); + rejectedCoords->ref(); + + rejectedNorms = new SoNormal(); + rejectedNorms->ref(); + + rejectedFaceSet = new SoIndexedFaceSet(); + rejectedFaceSet->ref(); + + SoPickStyle* rejectedPickStyle = new SoPickStyle(); + rejectedPickStyle->style = SoPickStyle::UNPICKABLE; + + SoShapeHints* rejectedHints = new SoShapeHints(); + rejectedHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; + rejectedHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; + + SoMaterialBinding* rejectedBind = new SoMaterialBinding(); + + SoTransparencyType* rejectedTransparencyType = new SoTransparencyType(); + rejectedTransparencyType->value.setValue(SoGLRenderAction::BLEND); + + SoMaterial* rejectedMaterial = new SoMaterial(); + rejectedMaterial->diffuseColor.set1Value(0,SbColor(1.f,0.f,0.f)); + rejectedMaterial->transparency.setValue(0.6f); + + SoDrawStyle* rejectedFaceStyle = new SoDrawStyle(); + rejectedFaceStyle->style = SoDrawStyle::FILLED; + + SoNormalBinding* rejectedNormb = new SoNormalBinding(); + rejectedNormb->value = SoNormalBinding::PER_VERTEX_INDEXED; + + // just faces with no edges or points + pcRejectedRoot->addChild(rejectedPickStyle); + pcRejectedRoot->addChild(rejectedTransparencyType); + pcRejectedRoot->addChild(rejectedBind); + pcRejectedRoot->addChild(rejectedMaterial); + pcRejectedRoot->addChild(rejectedHints); + pcRejectedRoot->addChild(rejectedFaceStyle); + pcRejectedRoot->addChild(rejectedCoords); + pcRejectedRoot->addChild(rejectedNorms); + pcRejectedRoot->addChild(rejectedNormb); + pcRejectedRoot->addChild(rejectedTrfms); + rejectedTrfms->addChild(rejectedFaceSet); + + pcRoot->addChild(pcRejectedRoot); + + recomputeFeature(); + return true; +} + void ViewProviderTransformed::unsetEdit(int ModNum) { if (ModNum == ViewProvider::Default) { @@ -55,6 +132,17 @@ void ViewProviderTransformed::unsetEdit(int ModNum) else { PartGui::ViewProviderPart::unsetEdit(ModNum); } + + rejectedTrfms->removeAllChildren(); + pcRejectedRoot->removeAllChildren(); + + pcRoot->removeChild(pcRejectedRoot); + + pcRejectedRoot->unref(); + rejectedTrfms->unref(); + rejectedCoords->unref(); + rejectedNorms->unref(); + rejectedFaceSet->unref(); } bool ViewProviderTransformed::onDelete(const std::vector &) @@ -126,5 +214,174 @@ void ViewProviderTransformed::recomputeFeature(void) msg = msg.arg(QObject::tr("Transformation succeeded")); } signalDiagnosis(msg); + + TopoDS_Shape shape; + if (rejected != 0) { + // FIXME: create a compound if there are more than one originals + App::DocumentObject* original = pcTransformed->Originals.getValues().front(); + if (original->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) { + PartDesign::Additive* addFeature = static_cast(original); + shape = addFeature->AddShape.getShape()._Shape; + } else if (original->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) { + PartDesign::Subtractive* subFeature = static_cast(original); + shape = subFeature->SubShape.getShape()._Shape; + } + } + + if (rejected == 0 || shape.IsNull()) { + rejectedCoords ->point .setNum(0); + rejectedNorms ->vector .setNum(0); + rejectedFaceSet ->coordIndex .setNum(0); + rejectedTrfms ->matrix .setNum(0); + } else { + // Display the rejected transformations in red + TopoDS_Shape cShape(shape); + + 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 + BRepMesh_IncrementalMesh myMesh(cShape,deflection); + // 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 + rejectedCoords ->point .setNum(nbrNodes); + rejectedNorms ->vector .setNum(nbrNodes); + 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 + rejectedTrfms->matrix.setNum(rejected); + SbMatrix* mats = rejectedTrfms->matrix.startEditing(); + + std::list rejected_trsf = pcTransformed->getRejectedTransformations(); + std::list::const_iterator trsf = rejected_trsf.begin(); + for (int i=0; i < rejected; i++,trsf++) { + Base::Matrix4D mat; + Part::TopoShape::convertToMatrix(*trsf,mat); + mats[i] = convert(mat); + } + rejectedTrfms->matrix.finishEditing(); + } + catch (...) { + Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n", + pcTransformed->getNameInDocument()); + } + } + } diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h index 1265f67e8..601df79b6 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h @@ -26,6 +26,12 @@ #include "ViewProvider.h" +class SoCoordinate3; +class SoIndexedFaceSet; +class SoMultipleCopy; +class SoNormal; +class SoSeparator; + namespace PartDesignGui { class TaskDlgTransformedParameters; @@ -53,10 +59,18 @@ public: std::string featureName; protected: - virtual bool setEdit(int ModNum) { return false; } + virtual bool setEdit(int ModNum); virtual void unsetEdit(int ModNum); const bool checkDlgOpen(TaskDlgTransformedParameters* transformedDlg); + + // nodes for the representation of rejected repetitions + SoGroup * pcRejectedRoot; + SoMultipleCopy * rejectedTrfms; + SoCoordinate3 * rejectedCoords; + SoNormal * rejectedNorms; + SoIndexedFaceSet * rejectedFaceSet; + public: void recomputeFeature(); };