diff --git a/src/Mod/PartDesign/App/FeaturePipe.cpp b/src/Mod/PartDesign/App/FeaturePipe.cpp index 9357abdad..e2d8fd31e 100644 --- a/src/Mod/PartDesign/App/FeaturePipe.cpp +++ b/src/Mod/PartDesign/App/FeaturePipe.cpp @@ -196,7 +196,42 @@ App::DocumentObjectExecReturn *Pipe::execute(void) if(!mkSolid.IsDone()) 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 SketchBased::execute(); diff --git a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp index ad11d88bf..c4584b796 100644 --- a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp +++ b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp @@ -140,6 +140,7 @@ PyMODINIT_FUNC initPartDesignGui() PartDesignGui::ViewProviderDatumPlane ::init(); PartDesignGui::ViewProviderDatumCoordinateSystem::init(); PartDesignGui::ViewProviderBoolean ::init(); + PartDesignGui::ViewProviderAddSub ::init(); PartDesignGui::ViewProviderPrimitive ::init(); PartDesignGui::ViewProviderPipe ::init(); diff --git a/src/Mod/PartDesign/Gui/CMakeLists.txt b/src/Mod/PartDesign/Gui/CMakeLists.txt index 9c2fcaad5..4fce1d6bd 100644 --- a/src/Mod/PartDesign/Gui/CMakeLists.txt +++ b/src/Mod/PartDesign/Gui/CMakeLists.txt @@ -132,6 +132,8 @@ SET(PartDesignGuiViewProvider_SRCS CommandPrimitive.cpp ViewProviderDatumCS.h ViewProviderBoolean.cpp ViewProviderBoolean.h + ViewProviderAddSub.cpp + ViewProviderAddSub.h ViewProviderPrimitive.h ViewProviderPrimitive.cpp ViewProviderPipe.h diff --git a/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp b/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp index 1f822f34f..068dc5347 100644 --- a/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp @@ -483,7 +483,9 @@ TaskPipeScaling::TaskPipeScaling(ViewProviderPipe* PipeView, bool newObj, QWidge this->groupLayout()->addWidget(proxy); - + PartDesign::Pipe* pipe = static_cast(PipeView->getObject()); + ui->comboBoxScaling->setCurrentIndex(pipe->Transformation.getValue()); + updateUI(0); } @@ -562,26 +564,10 @@ TaskDlgPipeParameters::~TaskDlgPipeParameters() bool TaskDlgPipeParameters::accept() -{/* +{ std::string name = vp->getObject()->getNameInDocument(); - // save the history - parameter->saveHistory(); - 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()"); if (!vp->getObject()->isValid()) throw Base::Exception(vp->getObject()->getStatusString()); @@ -593,7 +579,7 @@ bool TaskDlgPipeParameters::accept() return false; } - return true;*/ + return true; } //bool TaskDlgPipeParameters::reject() diff --git a/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp b/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp new file mode 100644 index 000000000..714573228 --- /dev/null +++ b/src/Mod/PartDesign/Gui/ViewProviderAddSub.cpp @@ -0,0 +1,285 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +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(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(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 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()); + } +} diff --git a/src/Mod/PartDesign/Gui/ViewProviderAddSub.h b/src/Mod/PartDesign/Gui/ViewProviderAddSub.h new file mode 100644 index 000000000..9a1ebbe16 --- /dev/null +++ b/src/Mod/PartDesign/Gui/ViewProviderAddSub.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 + +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 diff --git a/src/Mod/PartDesign/Gui/ViewProviderPipe.cpp b/src/Mod/PartDesign/Gui/ViewProviderPipe.cpp index 86726aef7..038737c2e 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderPipe.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderPipe.cpp @@ -78,6 +78,9 @@ bool ViewProviderPipe::doubleClicked(void) bool ViewProviderPipe::setEdit(int ModNum) { if (ModNum == ViewProvider::Default || ModNum == 1 ) { + + setPreviewDisplayMode(true); + // When double-clicking on the item for this pad the // object unsets and sets its edit mode without closing // 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 &s) {/* PartDesign::Pipe* pcPipe = static_cast(getObject()); diff --git a/src/Mod/PartDesign/Gui/ViewProviderPipe.h b/src/Mod/PartDesign/Gui/ViewProviderPipe.h index b57ff37d1..3cf57623f 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderPipe.h +++ b/src/Mod/PartDesign/Gui/ViewProviderPipe.h @@ -24,11 +24,11 @@ #ifndef PARTGUI_ViewProviderPipe_H #define PARTGUI_ViewProviderPipe_H -#include "ViewProvider.h" +#include "ViewProviderAddSub.h" namespace PartDesignGui { -class PartDesignGuiExport ViewProviderPipe : public ViewProvider +class PartDesignGuiExport ViewProviderPipe : public ViewProviderAddSub { PROPERTY_HEADER(PartDesignGui::ViewProviderPipe); @@ -47,6 +47,7 @@ public: protected: virtual bool setEdit(int ModNum); + virtual void unsetEdit(int ModNum); }; diff --git a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp index 6f1ca87ae..9c03446ff 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp @@ -57,220 +57,24 @@ PROPERTY_SOURCE(PartDesignGui::ViewProviderPrimitive,PartDesignGui::ViewProvider 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() { - previewFaceSet->unref(); - previewCoords->unref(); - previewNorm->unref(); - previewShape->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(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(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 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()); - } + ViewProviderAddSub::attach(obj); } bool ViewProviderPrimitive::setEdit(int ModNum) { - displayMode = getActiveDisplayMode(); - setDisplayMaskMode("Shape preview"); if (ModNum == ViewProvider::Default ) { + setPreviewDisplayMode(true); + // When double-clicking on the item for this fillet the // object unsets and sets its edit mode without closing // the task panel @@ -306,20 +110,17 @@ bool ViewProviderPrimitive::setEdit(int ModNum) return true; } else { - return PartGui::ViewProviderPart::setEdit(ModNum); + return ViewProviderAddSub::setEdit(ModNum); } } void ViewProviderPrimitive::unsetEdit(int ModNum) { - setDisplayMaskMode(displayMode.c_str()); + setPreviewDisplayMode(false); } void ViewProviderPrimitive::updateData(const App::Property* p) { - - if(strcmp(p->getName(), "AddSubShape")==0) - updateAddSubShapeIndicator(); - - PartDesignGui::ViewProvider::updateData(p); + + PartDesignGui::ViewProviderAddSub::updateData(p); } diff --git a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h index ccde684d6..807be0661 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h +++ b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h @@ -25,11 +25,12 @@ #define PARTGUI_ViewProviderPrimitive_H #include "ViewProvider.h" +#include "ViewProviderAddSub.h" #include namespace PartDesignGui { -class PartDesignGuiExport ViewProviderPrimitive : public ViewProvider +class PartDesignGuiExport ViewProviderPrimitive : public ViewProviderAddSub { PROPERTY_HEADER(PartDesignGui::ViewProviderPrimitive);