visualize the primitive add/sub shape in edit
This commit is contained in:
parent
1f180a11da
commit
fec86abc09
|
@ -127,7 +127,7 @@ using namespace PartGui;
|
|||
PROPERTY_SOURCE(PartGui::ViewProviderPartExt, Gui::ViewProviderGeometryObject)
|
||||
|
||||
|
||||
void GetNormals(const TopoDS_Face& theFace,
|
||||
void ViewProviderPartExt::GetNormals(const TopoDS_Face& theFace,
|
||||
const Handle(Poly_Triangulation)& aPolyTri,
|
||||
TColgp_Array1OfDir& theNormals)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include <Standard_math.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <TColgp_Array1OfDir.hxx>
|
||||
#include <App/PropertyUnits.h>
|
||||
#include <Gui/ViewProviderGeometryObject.h>
|
||||
#include <map>
|
||||
|
@ -125,6 +128,8 @@ protected:
|
|||
virtual void onChanged(const App::Property* prop);
|
||||
bool loadParameter();
|
||||
void updateVisual(const TopoDS_Shape &);
|
||||
void GetNormals(const TopoDS_Face& theFace, const Handle(Poly_Triangulation)& aPolyTri,
|
||||
TColgp_Array1OfDir& theNormals);
|
||||
|
||||
// nodes for the data representation
|
||||
SoMaterialBinding * pcShapeBind;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "PreCompiled.h"
|
||||
#include "Workbench.h"
|
||||
#include <Mod/PartDesign/App/Body.h>
|
||||
#include <Mod/PartDesign/App/FeaturePrimitive.h>
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoPickStyle.h>
|
||||
# include <QApplication>
|
||||
|
@ -95,11 +96,9 @@ void CmdPrimtiveCompAdditive::activated(int iMsg)
|
|||
FeatName.c_str(), CSName.c_str());
|
||||
Gui::Command::updateActive();
|
||||
|
||||
if (isActiveObjectValid() && (pcActiveBody != NULL)) {
|
||||
App::DocumentObject* prevSolidFeature = pcActiveBody->getPrevSolidFeature(NULL, false);
|
||||
if (prevSolidFeature != NULL && strcmp(prevSolidFeature->getNameInDocument(), FeatName.c_str())!=0)
|
||||
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", prevSolidFeature->getNameInDocument());
|
||||
}
|
||||
auto* prm = static_cast<PartDesign::FeaturePrimitive*>(getDocument()->getObject(FeatName.c_str()));
|
||||
if (prm->BaseFeature.getValue())
|
||||
doCommand(Gui,"Gui.activeDocument().hide(\"%s\")", prm->BaseFeature.getValue()->getNameInDocument());
|
||||
|
||||
Gui::Command::doCommand(Gui, "Gui.activeDocument().hide(\'%s\')", CSName.c_str());
|
||||
Gui::Command::doCommand(Gui, "Gui.activeDocument().setEdit(\'%s\')", FeatName.c_str());
|
||||
|
|
|
@ -528,7 +528,7 @@ void TaskBoxPrimitives::createPrimitive(const QString& placement)
|
|||
}
|
||||
}*/
|
||||
|
||||
TaskPrimitiveParameters::TaskPrimitiveParameters(ViewProviderPrimitive* PrimitiveView)
|
||||
TaskPrimitiveParameters::TaskPrimitiveParameters(ViewProviderPrimitive* PrimitiveView) : vp_prm(PrimitiveView)
|
||||
{
|
||||
|
||||
assert(PrimitiveView);
|
||||
|
@ -548,8 +548,15 @@ TaskPrimitiveParameters::TaskPrimitiveParameters(ViewProviderPrimitive* Primitiv
|
|||
Gui::Application::Instance->activeDocument()->getViewProvider(cs));
|
||||
|
||||
assert(vp);
|
||||
|
||||
//make sure the relevant things are visible
|
||||
cs_visibility = vp->isVisible();
|
||||
vp->Visibility.setValue(true);
|
||||
if(prm->BaseFeature.getValue()) {
|
||||
Gui::Application::Instance->activeDocument()->getViewProvider(prm->BaseFeature.getValue())->setVisible(true);
|
||||
vp_prm->setVisible(false);
|
||||
}
|
||||
|
||||
parameter = new TaskDatumParameters(vp);
|
||||
Content.push_back(parameter);
|
||||
|
||||
|
@ -562,6 +569,12 @@ TaskPrimitiveParameters::~TaskPrimitiveParameters()
|
|||
ViewProviderDatumCoordinateSystem* vp = static_cast<ViewProviderDatumCoordinateSystem*>(
|
||||
Gui::Application::Instance->activeDocument()->getViewProvider(cs));
|
||||
vp->setVisible(cs_visibility);
|
||||
|
||||
auto* prm = static_cast<PartDesign::FeaturePrimitive*>(vp_prm->getObject());
|
||||
if(prm->BaseFeature.getValue()) {
|
||||
Gui::Application::Instance->activeDocument()->getViewProvider(prm->BaseFeature.getValue())->setVisible(false);
|
||||
}
|
||||
vp_prm->setVisible(true);
|
||||
}
|
||||
|
||||
bool TaskPrimitiveParameters::accept()
|
||||
|
|
|
@ -92,6 +92,7 @@ private:
|
|||
TaskBoxPrimitives* primitive;
|
||||
TaskDatumParameters* parameter;
|
||||
PartDesign::CoordinateSystem* cs;
|
||||
ViewProviderPrimitive* vp_prm;
|
||||
bool cs_visibility;
|
||||
};
|
||||
|
||||
|
|
|
@ -81,6 +81,13 @@ void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop)
|
|||
getPointForDirection(Base::Vector3d(1,0,0), x);
|
||||
getPointForDirection(Base::Vector3d(0,1,0), y);
|
||||
getPointForDirection(Base::Vector3d(0,0,1), z);
|
||||
|
||||
//normalize all to equal lengths
|
||||
Base::Vector3d axis = (x.Sqr() > y.Sqr()) ? x : y;
|
||||
axis = (axis.Sqr() > z.Sqr()) ? axis : z;
|
||||
x = x.Normalize()*axis.Length();
|
||||
y = y.Normalize()*axis.Length();
|
||||
z = z.Normalize()*axis.Length();
|
||||
|
||||
|
||||
// Display the line
|
||||
|
@ -97,13 +104,12 @@ void ViewProviderDatumCoordinateSystem::updateData(const App::Property* prop)
|
|||
|
||||
pShapeSep->addChild(coord);
|
||||
lineSet = new PartGui::SoBrepEdgeSet();
|
||||
lineSet->coordIndex.setNum(6);
|
||||
lineSet->coordIndex.set1Value(0, 0);
|
||||
lineSet->coordIndex.set1Value(1, 1);
|
||||
lineSet->coordIndex.set1Value(2, 0);
|
||||
lineSet->coordIndex.set1Value(3, 2);
|
||||
lineSet->coordIndex.set1Value(4, 0);
|
||||
lineSet->coordIndex.set1Value(5, 3);
|
||||
lineSet->coordIndex.setNum(5);
|
||||
lineSet->coordIndex.set1Value(0, 1);
|
||||
lineSet->coordIndex.set1Value(1, 0);
|
||||
lineSet->coordIndex.set1Value(2, 2);
|
||||
lineSet->coordIndex.set1Value(3, 0);
|
||||
lineSet->coordIndex.set1Value(4, 3);
|
||||
pShapeSep->addChild(lineSet);
|
||||
} else {
|
||||
coord = static_cast<SoCoordinate3*>(pShapeSep->getChild(1));
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "ViewProviderPrimitive.h"
|
||||
#include "TaskPrimitiveParameters.h"
|
||||
#include "Mod/Part/Gui/SoBrepFaceSet.h"
|
||||
#include <Mod/PartDesign/App/FeaturePrimitive.h>
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <Gui/Control.h>
|
||||
|
@ -36,6 +37,17 @@
|
|||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/nodes/SoSwitch.h>
|
||||
#include <Inventor/nodes/SoCoordinate3.h>
|
||||
#include <Inventor/nodes/SoNormal.h>
|
||||
#include <Inventor/nodes/SoMaterial.h>
|
||||
#include <Inventor/nodes/SoPickStyle.h>
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
|
||||
|
||||
using namespace PartDesignGui;
|
||||
|
@ -44,15 +56,223 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderPrimitive,PartDesignGui::ViewProvider
|
|||
|
||||
ViewProviderPrimitive::ViewProviderPrimitive()
|
||||
{
|
||||
|
||||
|
||||
previewSwitch = new SoSwitch();
|
||||
previewSwitch->ref();
|
||||
previewShape = new SoSeparator();
|
||||
previewShape->ref();
|
||||
previewFaceSet = new PartGui::SoBrepFaceSet();
|
||||
previewFaceSet->ref();
|
||||
previewCoords = new SoCoordinate3();
|
||||
previewCoords->ref();
|
||||
previewNorm = new SoNormal();
|
||||
previewNorm->ref();
|
||||
|
||||
}
|
||||
|
||||
ViewProviderPrimitive::~ViewProviderPrimitive()
|
||||
{
|
||||
previewFaceSet->unref();
|
||||
previewCoords->unref();
|
||||
previewNorm->unref();
|
||||
previewShape->unref();
|
||||
previewSwitch->unref();
|
||||
}
|
||||
|
||||
void ViewProviderPrimitive::attach(App::DocumentObject* obj) {
|
||||
|
||||
ViewProvider::attach(obj);
|
||||
|
||||
auto* bind = new SoMaterialBinding();
|
||||
bind->value = SoMaterialBinding::OVERALL;
|
||||
auto* material = new SoMaterial();
|
||||
if(static_cast<PartDesign::FeatureAddSub*>(obj)->getAddSubType() == PartDesign::FeatureAddSub::Additive)
|
||||
material->diffuseColor = SbColor(1,1,0);
|
||||
else
|
||||
material->diffuseColor = SbColor(1,0,0);
|
||||
|
||||
material->transparency = 0.7;
|
||||
auto* pick = new SoPickStyle();
|
||||
pick->style = SoPickStyle::UNPICKABLE;
|
||||
|
||||
previewShape->addChild(pick);
|
||||
previewShape->addChild(bind);
|
||||
previewShape->addChild(material);
|
||||
previewShape->addChild(previewCoords);
|
||||
previewShape->addChild(previewNorm);
|
||||
previewShape->addChild(previewFaceSet);
|
||||
previewSwitch->addChild(previewShape);
|
||||
previewSwitch->whichChild = -1;
|
||||
getRoot()->addChild(previewSwitch);
|
||||
updateAddSubShapeIndicator();
|
||||
}
|
||||
|
||||
void ViewProviderPrimitive::updateAddSubShapeIndicator() {
|
||||
|
||||
|
||||
TopoDS_Shape cShape(static_cast<PartDesign::FeaturePrimitive*>(getObject())->AddSubShape.getValue());
|
||||
if (cShape.IsNull()) {
|
||||
previewCoords ->point .setNum(0);
|
||||
previewNorm ->vector .setNum(0);
|
||||
previewFaceSet ->coordIndex .setNum(0);
|
||||
previewFaceSet ->partIndex .setNum(0);
|
||||
return;
|
||||
}
|
||||
|
||||
int numTriangles=0,numNodes=0,numNorms=0,numFaces=0;
|
||||
std::set<int> faceEdges;
|
||||
|
||||
try {
|
||||
// calculating the deflection value
|
||||
Bnd_Box bounds;
|
||||
BRepBndLib::Add(cShape, bounds);
|
||||
bounds.SetGap(0.0);
|
||||
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
|
||||
bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
|
||||
Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 *
|
||||
Deviation.getValue();
|
||||
Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI;
|
||||
|
||||
// create or use the mesh on the data structure
|
||||
#if OCC_VERSION_HEX >= 0x060600
|
||||
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
|
||||
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()) {
|
||||
numTriangles += mesh->NbTriangles();
|
||||
numNodes += mesh->NbNodes();
|
||||
numNorms += mesh->NbNodes();
|
||||
}
|
||||
numFaces++;
|
||||
}
|
||||
|
||||
// create memory for the nodes and indexes
|
||||
previewCoords ->point .setNum(numNodes);
|
||||
previewNorm ->vector .setNum(numNorms);
|
||||
previewFaceSet ->coordIndex .setNum(numTriangles*4);
|
||||
previewFaceSet ->partIndex .setNum(numFaces);
|
||||
// get the raw memory for fast fill up
|
||||
SbVec3f* verts = previewCoords ->point .startEditing();
|
||||
SbVec3f* previewNorms = previewNorm ->vector .startEditing();
|
||||
int32_t* index = previewFaceSet ->coordIndex .startEditing();
|
||||
int32_t* parts = previewFaceSet ->partIndex .startEditing();
|
||||
|
||||
// preset the previewNormal vector with null vector
|
||||
for (int i=0;i < numNorms;i++)
|
||||
previewNorms[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();
|
||||
TColgp_Array1OfDir Normals (Nodes.Lower(), Nodes.Upper());
|
||||
GetNormals(actFace, mesh, Normals);
|
||||
|
||||
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));
|
||||
|
||||
// get the 3 previewNormals of this triangle
|
||||
gp_Dir NV1(Normals(N1)), NV2(Normals(N2)), NV3(Normals(N3));
|
||||
|
||||
// transform the vertices and previewNormals to the place of the face
|
||||
if(!identity) {
|
||||
V1.Transform(myTransf);
|
||||
V2.Transform(myTransf);
|
||||
V3.Transform(myTransf);
|
||||
NV1.Transform(myTransf);
|
||||
NV2.Transform(myTransf);
|
||||
NV3.Transform(myTransf);
|
||||
}
|
||||
|
||||
// add the previewNormals for all points of this triangle
|
||||
previewNorms[faceNodeOffset+N1-1] += SbVec3f(NV1.X(),NV1.Y(),NV1.Z());
|
||||
previewNorms[faceNodeOffset+N2-1] += SbVec3f(NV2.X(),NV2.Y(),NV2.Z());
|
||||
previewNorms[faceNodeOffset+N3-1] += SbVec3f(NV3.X(),NV3.Y(),NV3.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;
|
||||
}
|
||||
|
||||
parts[ii] = nbTriInFace; // new part
|
||||
|
||||
// counting up the per Face offsets
|
||||
faceNodeOffset += nbNodesInFace;
|
||||
faceTriaOffset += nbTriInFace;
|
||||
}
|
||||
|
||||
// previewNormalize all previewNormals
|
||||
for (int i = 0; i< numNorms ;i++)
|
||||
previewNorms[i].normalize();
|
||||
|
||||
// end the editing of the nodes
|
||||
previewCoords ->point .finishEditing();
|
||||
previewNorm ->vector .finishEditing();
|
||||
previewFaceSet ->coordIndex .finishEditing();
|
||||
previewFaceSet ->partIndex .finishEditing();
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Error("Cannot compute Inventor representation for the shape of %s.\n",pcObject->getNameInDocument());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ViewProviderPrimitive::setEdit(int ModNum)
|
||||
{
|
||||
previewSwitch->whichChild = 0;
|
||||
if (ModNum == ViewProvider::Default ) {
|
||||
// When double-clicking on the item for this fillet the
|
||||
// object unsets and sets its edit mode without closing
|
||||
|
@ -93,6 +313,20 @@ bool ViewProviderPrimitive::setEdit(int ModNum)
|
|||
}
|
||||
}
|
||||
|
||||
void ViewProviderPrimitive::unsetEdit(int ModNum) {
|
||||
previewSwitch->whichChild = -1;
|
||||
}
|
||||
|
||||
void ViewProviderPrimitive::updateData(const App::Property* p) {
|
||||
|
||||
if(strcmp(p->getName(), "AddSubShape")==0)
|
||||
updateAddSubShapeIndicator();
|
||||
|
||||
PartDesignGui::ViewProvider::updateData(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::vector< App::DocumentObject* > ViewProviderPrimitive::claimChildren(void) const {
|
||||
|
||||
std::vector< App::DocumentObject* > vec;
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
#define PARTGUI_ViewProviderPrimitive_H
|
||||
|
||||
#include "ViewProvider.h"
|
||||
#include <Mod/Part/Gui/SoBrepFaceSet.h>
|
||||
|
||||
class SoSwitch;
|
||||
|
||||
namespace PartDesignGui {
|
||||
|
||||
|
@ -40,10 +42,21 @@ public:
|
|||
virtual ~ViewProviderPrimitive();
|
||||
|
||||
virtual std::vector< App::DocumentObject* > claimChildren(void) const;
|
||||
virtual void attach(App::DocumentObject*);
|
||||
virtual void updateData(const App::Property*);
|
||||
|
||||
protected:
|
||||
virtual QIcon getIcon(void) const;
|
||||
virtual bool setEdit(int ModNum);
|
||||
virtual void unsetEdit(int ModNum);
|
||||
|
||||
void updateAddSubShapeIndicator();
|
||||
|
||||
SoSwitch* previewSwitch;
|
||||
SoSeparator* previewShape;
|
||||
PartGui::SoBrepFaceSet* previewFaceSet;
|
||||
SoCoordinate3* previewCoords;
|
||||
SoNormal* previewNorm;
|
||||
};
|
||||
|
||||
} // namespace PartDesignGui
|
||||
|
|
Loading…
Reference in New Issue
Block a user