generalize preview mode
This commit is contained in:
parent
68d172687b
commit
342ba89afd
|
@ -196,7 +196,42 @@ App::DocumentObjectExecReturn *Pipe::execute(void)
|
||||||
if(!mkSolid.IsDone())
|
if(!mkSolid.IsDone())
|
||||||
return new App::DocumentObjectExecReturn("Result is not a solid");
|
return new App::DocumentObjectExecReturn("Result is not a solid");
|
||||||
|
|
||||||
this->Shape.setValue(mkSolid.Shape());
|
AddSubShape.setValue(mkSolid.Shape());
|
||||||
|
|
||||||
|
if(base.IsNull()) {
|
||||||
|
Shape.setValue(mkSolid.Shape());
|
||||||
|
return App::DocumentObject::StdReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getAddSubType() == FeatureAddSub::Additive) {
|
||||||
|
|
||||||
|
BRepAlgoAPI_Fuse mkFuse(base, mkSolid.Shape());
|
||||||
|
if (!mkFuse.IsDone())
|
||||||
|
return new App::DocumentObjectExecReturn("Adding the pipe failed");
|
||||||
|
// we have to get the solids (fuse sometimes creates compounds)
|
||||||
|
TopoDS_Shape boolOp = this->getSolid(mkFuse.Shape());
|
||||||
|
// lets check if the result is a solid
|
||||||
|
if (boolOp.IsNull())
|
||||||
|
return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
|
||||||
|
|
||||||
|
boolOp = refineShapeIfActive(boolOp);
|
||||||
|
Shape.setValue(boolOp);
|
||||||
|
}
|
||||||
|
else if(getAddSubType() == FeatureAddSub::Subtractive) {
|
||||||
|
|
||||||
|
BRepAlgoAPI_Cut mkCut(base, mkSolid.Shape());
|
||||||
|
if (!mkCut.IsDone())
|
||||||
|
return new App::DocumentObjectExecReturn("Subtracting the pipe failed");
|
||||||
|
// we have to get the solids (fuse sometimes creates compounds)
|
||||||
|
TopoDS_Shape boolOp = this->getSolid(mkCut.Shape());
|
||||||
|
// lets check if the result is a solid
|
||||||
|
if (boolOp.IsNull())
|
||||||
|
return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
|
||||||
|
|
||||||
|
boolOp = refineShapeIfActive(boolOp);
|
||||||
|
Shape.setValue(boolOp);
|
||||||
|
}
|
||||||
|
|
||||||
return App::DocumentObject::StdReturn;
|
return App::DocumentObject::StdReturn;
|
||||||
|
|
||||||
return SketchBased::execute();
|
return SketchBased::execute();
|
||||||
|
|
|
@ -140,6 +140,7 @@ PyMODINIT_FUNC initPartDesignGui()
|
||||||
PartDesignGui::ViewProviderDatumPlane ::init();
|
PartDesignGui::ViewProviderDatumPlane ::init();
|
||||||
PartDesignGui::ViewProviderDatumCoordinateSystem::init();
|
PartDesignGui::ViewProviderDatumCoordinateSystem::init();
|
||||||
PartDesignGui::ViewProviderBoolean ::init();
|
PartDesignGui::ViewProviderBoolean ::init();
|
||||||
|
PartDesignGui::ViewProviderAddSub ::init();
|
||||||
PartDesignGui::ViewProviderPrimitive ::init();
|
PartDesignGui::ViewProviderPrimitive ::init();
|
||||||
PartDesignGui::ViewProviderPipe ::init();
|
PartDesignGui::ViewProviderPipe ::init();
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,8 @@ SET(PartDesignGuiViewProvider_SRCS CommandPrimitive.cpp
|
||||||
ViewProviderDatumCS.h
|
ViewProviderDatumCS.h
|
||||||
ViewProviderBoolean.cpp
|
ViewProviderBoolean.cpp
|
||||||
ViewProviderBoolean.h
|
ViewProviderBoolean.h
|
||||||
|
ViewProviderAddSub.cpp
|
||||||
|
ViewProviderAddSub.h
|
||||||
ViewProviderPrimitive.h
|
ViewProviderPrimitive.h
|
||||||
ViewProviderPrimitive.cpp
|
ViewProviderPrimitive.cpp
|
||||||
ViewProviderPipe.h
|
ViewProviderPipe.h
|
||||||
|
|
|
@ -483,7 +483,9 @@ TaskPipeScaling::TaskPipeScaling(ViewProviderPipe* PipeView, bool newObj, QWidge
|
||||||
|
|
||||||
this->groupLayout()->addWidget(proxy);
|
this->groupLayout()->addWidget(proxy);
|
||||||
|
|
||||||
|
PartDesign::Pipe* pipe = static_cast<PartDesign::Pipe*>(PipeView->getObject());
|
||||||
|
ui->comboBoxScaling->setCurrentIndex(pipe->Transformation.getValue());
|
||||||
|
|
||||||
updateUI(0);
|
updateUI(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,26 +564,10 @@ TaskDlgPipeParameters::~TaskDlgPipeParameters()
|
||||||
|
|
||||||
|
|
||||||
bool TaskDlgPipeParameters::accept()
|
bool TaskDlgPipeParameters::accept()
|
||||||
{/*
|
{
|
||||||
std::string name = vp->getObject()->getNameInDocument();
|
std::string name = vp->getObject()->getNameInDocument();
|
||||||
|
|
||||||
// save the history
|
|
||||||
parameter->saveHistory();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//Gui::Command::openCommand("Pipe changed");
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Length = %f",name.c_str(),parameter->getLength());
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %i",name.c_str(),parameter->getReversed()?1:0);
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(),parameter->getMidplane()?1:0);
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Length2 = %f",name.c_str(),parameter->getLength2());
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Offset = %f",name.c_str(),parameter->getOffset());
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Type = %u",name.c_str(),parameter->getMode());
|
|
||||||
std::string facename = (const char*)parameter->getFaceName();
|
|
||||||
|
|
||||||
if (!facename.empty()) {
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = %s", name.c_str(), facename.c_str());
|
|
||||||
} else
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = None", name.c_str());
|
|
||||||
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
|
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
|
||||||
if (!vp->getObject()->isValid())
|
if (!vp->getObject()->isValid())
|
||||||
throw Base::Exception(vp->getObject()->getStatusString());
|
throw Base::Exception(vp->getObject()->getStatusString());
|
||||||
|
@ -593,7 +579,7 @@ bool TaskDlgPipeParameters::accept()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;*/
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool TaskDlgPipeParameters::reject()
|
//bool TaskDlgPipeParameters::reject()
|
||||||
|
|
285
src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
Normal file
285
src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp
Normal file
|
@ -0,0 +1,285 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
|
||||||
|
* *
|
||||||
|
* This file is part of the FreeCAD CAx development system. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this library; see the file COPYING.LIB. If not, *
|
||||||
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||||
|
* Suite 330, Boston, MA 02111-1307, USA *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PreCompiled.h"
|
||||||
|
|
||||||
|
#ifndef _PreComp_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ViewProviderAddSub.h"
|
||||||
|
#include "Mod/Part/Gui/SoBrepFaceSet.h"
|
||||||
|
#include <Mod/PartDesign/App/FeatureAddSub.h>
|
||||||
|
#include <Gui/TaskView/TaskDialog.h>
|
||||||
|
#include <Gui/Control.h>
|
||||||
|
#include <Gui/Command.h>
|
||||||
|
#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;
|
||||||
|
|
||||||
|
PROPERTY_SOURCE(PartDesignGui::ViewProviderAddSub,PartDesignGui::ViewProvider)
|
||||||
|
|
||||||
|
ViewProviderAddSub::ViewProviderAddSub()
|
||||||
|
{
|
||||||
|
|
||||||
|
previewShape = new SoSeparator();
|
||||||
|
previewShape->ref();
|
||||||
|
previewFaceSet = new PartGui::SoBrepFaceSet();
|
||||||
|
previewFaceSet->ref();
|
||||||
|
previewCoords = new SoCoordinate3();
|
||||||
|
previewCoords->ref();
|
||||||
|
previewNorm = new SoNormal();
|
||||||
|
previewNorm->ref();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewProviderAddSub::~ViewProviderAddSub()
|
||||||
|
{
|
||||||
|
previewFaceSet->unref();
|
||||||
|
previewCoords->unref();
|
||||||
|
previewNorm->unref();
|
||||||
|
previewShape->unref();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewProviderAddSub::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);
|
||||||
|
|
||||||
|
addDisplayMaskMode(previewShape, "Shape preview");
|
||||||
|
updateAddSubShapeIndicator();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewProviderAddSub::updateAddSubShapeIndicator() {
|
||||||
|
|
||||||
|
|
||||||
|
TopoDS_Shape cShape(static_cast<PartDesign::FeatureAddSub*>(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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewProviderAddSub::updateData(const App::Property* p) {
|
||||||
|
|
||||||
|
if(strcmp(p->getName(), "AddSubShape")==0)
|
||||||
|
updateAddSubShapeIndicator();
|
||||||
|
|
||||||
|
PartDesignGui::ViewProvider::updateData(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewProviderAddSub::setPreviewDisplayMode(bool onoff) {
|
||||||
|
|
||||||
|
if(onoff && displayMode!="Shape preview") {
|
||||||
|
|
||||||
|
displayMode = getActiveDisplayMode();
|
||||||
|
setDisplayMaskMode("Shape preview");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!onoff) {
|
||||||
|
setDisplayMaskMode(displayMode.c_str());
|
||||||
|
}
|
||||||
|
}
|
59
src/Mod/PartDesign/Gui/ViewProviderAddSub.h
Normal file
59
src/Mod/PartDesign/Gui/ViewProviderAddSub.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net> *
|
||||||
|
* *
|
||||||
|
* This file is part of the FreeCAD CAx development system. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this library; see the file COPYING.LIB. If not, *
|
||||||
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||||
|
* Suite 330, Boston, MA 02111-1307, USA *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PARTGUI_ViewProviderAddSub_H
|
||||||
|
#define PARTGUI_ViewProviderAddSub_H
|
||||||
|
|
||||||
|
#include "ViewProvider.h"
|
||||||
|
#include <Mod/Part/Gui/SoBrepFaceSet.h>
|
||||||
|
|
||||||
|
namespace PartDesignGui {
|
||||||
|
|
||||||
|
class PartDesignGuiExport ViewProviderAddSub : public ViewProvider
|
||||||
|
{
|
||||||
|
PROPERTY_HEADER(PartDesignGui::ViewProviderAddSub);
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// constructor
|
||||||
|
ViewProviderAddSub();
|
||||||
|
/// destructor
|
||||||
|
virtual ~ViewProviderAddSub();
|
||||||
|
|
||||||
|
virtual void attach(App::DocumentObject*);
|
||||||
|
virtual void updateData(const App::Property*);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateAddSubShapeIndicator();
|
||||||
|
void setPreviewDisplayMode(bool);
|
||||||
|
|
||||||
|
std::string displayMode;
|
||||||
|
SoSeparator* previewShape;
|
||||||
|
PartGui::SoBrepFaceSet* previewFaceSet;
|
||||||
|
SoCoordinate3* previewCoords;
|
||||||
|
SoNormal* previewNorm;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace PartDesignGui
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PARTGUI_ViewProviderBoolean_H
|
|
@ -78,6 +78,9 @@ bool ViewProviderPipe::doubleClicked(void)
|
||||||
bool ViewProviderPipe::setEdit(int ModNum)
|
bool ViewProviderPipe::setEdit(int ModNum)
|
||||||
{
|
{
|
||||||
if (ModNum == ViewProvider::Default || ModNum == 1 ) {
|
if (ModNum == ViewProvider::Default || ModNum == 1 ) {
|
||||||
|
|
||||||
|
setPreviewDisplayMode(true);
|
||||||
|
|
||||||
// When double-clicking on the item for this pad the
|
// When double-clicking on the item for this pad the
|
||||||
// object unsets and sets its edit mode without closing
|
// object unsets and sets its edit mode without closing
|
||||||
// the task panel
|
// the task panel
|
||||||
|
@ -117,6 +120,12 @@ bool ViewProviderPipe::setEdit(int ModNum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewProviderPipe::unsetEdit(int ModNum) {
|
||||||
|
setPreviewDisplayMode(false);
|
||||||
|
PartDesignGui::ViewProvider::unsetEdit(ModNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ViewProviderPipe::onDelete(const std::vector<std::string> &s)
|
bool ViewProviderPipe::onDelete(const std::vector<std::string> &s)
|
||||||
{/*
|
{/*
|
||||||
PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());
|
PartDesign::Pipe* pcPipe = static_cast<PartDesign::Pipe*>(getObject());
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
#ifndef PARTGUI_ViewProviderPipe_H
|
#ifndef PARTGUI_ViewProviderPipe_H
|
||||||
#define PARTGUI_ViewProviderPipe_H
|
#define PARTGUI_ViewProviderPipe_H
|
||||||
|
|
||||||
#include "ViewProvider.h"
|
#include "ViewProviderAddSub.h"
|
||||||
|
|
||||||
namespace PartDesignGui {
|
namespace PartDesignGui {
|
||||||
|
|
||||||
class PartDesignGuiExport ViewProviderPipe : public ViewProvider
|
class PartDesignGuiExport ViewProviderPipe : public ViewProviderAddSub
|
||||||
{
|
{
|
||||||
PROPERTY_HEADER(PartDesignGui::ViewProviderPipe);
|
PROPERTY_HEADER(PartDesignGui::ViewProviderPipe);
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool setEdit(int ModNum);
|
virtual bool setEdit(int ModNum);
|
||||||
|
virtual void unsetEdit(int ModNum);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -57,220 +57,24 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderPrimitive,PartDesignGui::ViewProvider
|
||||||
ViewProviderPrimitive::ViewProviderPrimitive()
|
ViewProviderPrimitive::ViewProviderPrimitive()
|
||||||
{
|
{
|
||||||
|
|
||||||
previewShape = new SoSeparator();
|
|
||||||
previewShape->ref();
|
|
||||||
previewFaceSet = new PartGui::SoBrepFaceSet();
|
|
||||||
previewFaceSet->ref();
|
|
||||||
previewCoords = new SoCoordinate3();
|
|
||||||
previewCoords->ref();
|
|
||||||
previewNorm = new SoNormal();
|
|
||||||
previewNorm->ref();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewProviderPrimitive::~ViewProviderPrimitive()
|
ViewProviderPrimitive::~ViewProviderPrimitive()
|
||||||
{
|
{
|
||||||
previewFaceSet->unref();
|
|
||||||
previewCoords->unref();
|
|
||||||
previewNorm->unref();
|
|
||||||
previewShape->unref();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewProviderPrimitive::attach(App::DocumentObject* obj) {
|
void ViewProviderPrimitive::attach(App::DocumentObject* obj) {
|
||||||
|
|
||||||
ViewProvider::attach(obj);
|
ViewProviderAddSub::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);
|
|
||||||
|
|
||||||
addDisplayMaskMode(previewShape, "Shape preview");
|
|
||||||
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)
|
bool ViewProviderPrimitive::setEdit(int ModNum)
|
||||||
{
|
{
|
||||||
displayMode = getActiveDisplayMode();
|
|
||||||
setDisplayMaskMode("Shape preview");
|
|
||||||
if (ModNum == ViewProvider::Default ) {
|
if (ModNum == ViewProvider::Default ) {
|
||||||
|
setPreviewDisplayMode(true);
|
||||||
|
|
||||||
// When double-clicking on the item for this fillet the
|
// When double-clicking on the item for this fillet the
|
||||||
// object unsets and sets its edit mode without closing
|
// object unsets and sets its edit mode without closing
|
||||||
// the task panel
|
// the task panel
|
||||||
|
@ -306,20 +110,17 @@ bool ViewProviderPrimitive::setEdit(int ModNum)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return PartGui::ViewProviderPart::setEdit(ModNum);
|
return ViewProviderAddSub::setEdit(ModNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewProviderPrimitive::unsetEdit(int ModNum) {
|
void ViewProviderPrimitive::unsetEdit(int ModNum) {
|
||||||
setDisplayMaskMode(displayMode.c_str());
|
setPreviewDisplayMode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewProviderPrimitive::updateData(const App::Property* p) {
|
void ViewProviderPrimitive::updateData(const App::Property* p) {
|
||||||
|
|
||||||
if(strcmp(p->getName(), "AddSubShape")==0)
|
PartDesignGui::ViewProviderAddSub::updateData(p);
|
||||||
updateAddSubShapeIndicator();
|
|
||||||
|
|
||||||
PartDesignGui::ViewProvider::updateData(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,12 @@
|
||||||
#define PARTGUI_ViewProviderPrimitive_H
|
#define PARTGUI_ViewProviderPrimitive_H
|
||||||
|
|
||||||
#include "ViewProvider.h"
|
#include "ViewProvider.h"
|
||||||
|
#include "ViewProviderAddSub.h"
|
||||||
#include <Mod/Part/Gui/SoBrepFaceSet.h>
|
#include <Mod/Part/Gui/SoBrepFaceSet.h>
|
||||||
|
|
||||||
namespace PartDesignGui {
|
namespace PartDesignGui {
|
||||||
|
|
||||||
class PartDesignGuiExport ViewProviderPrimitive : public ViewProvider
|
class PartDesignGuiExport ViewProviderPrimitive : public ViewProviderAddSub
|
||||||
{
|
{
|
||||||
PROPERTY_HEADER(PartDesignGui::ViewProviderPrimitive);
|
PROPERTY_HEADER(PartDesignGui::ViewProviderPrimitive);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user