diff --git a/src/Mod/Part/Gui/ViewProviderPreviewExtension.cpp b/src/Mod/Part/Gui/ViewProviderPreviewExtension.cpp index a453afce77..eac9195389 100644 --- a/src/Mod/Part/Gui/ViewProviderPreviewExtension.cpp +++ b/src/Mod/Part/Gui/ViewProviderPreviewExtension.cpp @@ -137,13 +137,46 @@ void ViewProviderPreviewExtension::extensionAttach(App::DocumentObject* document { ViewProviderExtension::extensionAttach(documentObject); + pcPreviewRoot = new SoSeparator; pcPreviewShape = new SoPreviewShape; - pcPreviewRoot = new SoSeparator; - pcPreviewRoot->addChild(pcPreviewShape); - - updatePreviewShape(); + attachPreview(); + updatePreview(); } + +void ViewProviderPreviewExtension::extensionBeforeDelete() +{ + ViewProviderExtension::extensionBeforeDelete(); + + showPreview(false); +} + +void ViewProviderPreviewExtension::showPreview(bool enable) +{ + auto feature = getExtendedViewProvider()->getObject(); + if (!feature) { + return; + } + + auto previewExtension = feature->getExtensionByType(true); + if (!previewExtension) { + return; + } + + _isPreviewEnabled = enable; + + auto annotationRoot = getExtendedViewProvider()->getAnnotation(); + if (enable) { + previewExtension->updatePreview(); + + if (annotationRoot->findChild(pcPreviewRoot) < 0) { + annotationRoot->addChild(pcPreviewRoot); + } + } else { + annotationRoot->removeChild(pcPreviewRoot); + } +} + void ViewProviderPreviewExtension::extensionOnChanged(const App::Property* prop) { if (prop == &PreviewColor) { @@ -153,39 +186,68 @@ void ViewProviderPreviewExtension::extensionOnChanged(const App::Property* prop) ViewProviderExtension::extensionOnChanged(prop); } -void ViewProviderPreviewExtension::updatePreviewShape() +void ViewProviderPreviewExtension::attachPreview() { + pcPreviewRoot->addChild(pcPreviewShape); +} + +void ViewProviderPreviewExtension::updatePreview() +{ + updatePreviewShape(getPreviewShape(), pcPreviewShape); +} + +void ViewProviderPreviewExtension::updatePreviewShape(Part::TopoShape shape, + SoPreviewShape* preview) +{ + if (shape.isNull() || preview == nullptr) { + return; + } + auto vp = freecad_cast(getExtendedViewProvider()); if (!vp) { return; } - ViewProviderPartExt::setupCoinGeometry(getPreviewShape().getShape(), - pcPreviewShape->coords, - pcPreviewShape->faceset, - pcPreviewShape->norm, - pcPreviewShape->lineset, - pcPreviewShape->nodeset, - vp->Deviation.getValue(), - vp->AngularDeflection.getValue(), - false); + const auto updatePreviewShape = [vp](SoPreviewShape* preview, Part::TopoShape shape) { + ViewProviderPartExt::setupCoinGeometry(shape.getShape(), + preview->coords, + preview->faceset, + preview->norm, + preview->lineset, + preview->nodeset, + vp->Deviation.getValue(), + vp->AngularDeflection.getValue(), + false); + }; + + try { + updatePreviewShape(preview, shape); + } catch (Standard_Failure& e) { + Base::Console().userTranslatedNotification( + tr("Failure while rendering preview: %1. That usually indicates an error with model.") + .arg(QString::fromUtf8(e.GetMessageString())) + .toUtf8()); + + updatePreviewShape(preview, {}); + } // For some reason line patterns are not rendered correctly if material binding is set to // anything other than PER_FACE. PER_FACE material binding seems to require materialIndex per - // each distinct edge. Until that is fixed, this code forces each edge to use the first material. - unsigned lineCoordsCount = pcPreviewShape->lineset->coordIndex.getNum(); + // each distinct edge. Until that is fixed, this code forces each edge to use the first + // material. + unsigned lineCoordsCount = preview->lineset->coordIndex.getNum(); unsigned lineCount = 1; for (unsigned i = 0; i < lineCoordsCount; ++i) { - if (pcPreviewShape->lineset->coordIndex[i] < 0) { + if (preview->lineset->coordIndex[i] < 0) { lineCount++; } } - pcPreviewShape->lineset->materialIndex.setNum(lineCount); + preview->lineset->materialIndex.setNum(lineCount); for (unsigned i = 0; i < lineCount; ++i) { - pcPreviewShape->lineset->materialIndex.set1Value(i, 0); + preview->lineset->materialIndex.set1Value(i, 0); } } diff --git a/src/Mod/Part/Gui/ViewProviderPreviewExtension.h b/src/Mod/Part/Gui/ViewProviderPreviewExtension.h index 4213e87e45..f829445c41 100644 --- a/src/Mod/Part/Gui/ViewProviderPreviewExtension.h +++ b/src/Mod/Part/Gui/ViewProviderPreviewExtension.h @@ -43,6 +43,7 @@ #include #include #include +#include namespace PartGui { @@ -92,8 +93,12 @@ public: protected: void extensionOnChanged(const App::Property* prop) override; + /// attaches preview to the scene graph + virtual void attachPreview(); + /// updates preview + virtual void updatePreview(); /// updates geometry of the preview shape - void updatePreviewShape(); + void updatePreviewShape(Part::TopoShape shape, SoPreviewShape* preview); Gui::CoinPtr pcPreviewRoot; Gui::CoinPtr pcPreviewShape; diff --git a/src/Mod/PartDesign/App/FeatureMultiTransform.h b/src/Mod/PartDesign/App/FeatureMultiTransform.h index bfe1e0a658..5408fab22d 100644 --- a/src/Mod/PartDesign/App/FeatureMultiTransform.h +++ b/src/Mod/PartDesign/App/FeatureMultiTransform.h @@ -50,11 +50,6 @@ public: } //@} - std::vector getOriginals() const - { - return Originals.getValues(); - } - /** Create transformations * Returns a list containing the product of all transformations of the subfeatures given * by the Transformations property. Subfeatures can be Mirrored, LinearPattern, PolarPattern and diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp index b6a728c9bc..ae90ded7f3 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.cpp +++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp @@ -115,9 +115,33 @@ Part::Feature* Transformed::getBaseObject(bool silent) const return rv; } +std::vector Transformed::getOriginals() const +{ + auto const mode = static_cast(TransformMode.getValue()); + + if (mode == Mode::TransformBody) { + return {}; + } + + std::vector originals = Originals.getValues(); + + const auto isSuppressed = [](const DocumentObject* obj) { + auto feature = freecad_cast(obj); + + return feature != nullptr && feature->Suppressed.getValue(); + }; + + // Remove suppressed features from the list so the transformations behave as if they are not + // there + auto [first, last] = std::ranges::remove_if(originals, isSuppressed); + originals.erase(first, last); + + return originals; +} + App::DocumentObject* Transformed::getSketchObject() const { - std::vector originals = Originals.getValues(); + std::vector originals = getOriginals(); DocumentObject const* firstOriginal = !originals.empty() ? originals.front() : nullptr; if (auto feature = freecad_cast(firstOriginal)) { @@ -198,6 +222,15 @@ short Transformed::mustExecute() const } return PartDesign::Feature::mustExecute(); } +void Transformed::onChanged(const App::Property* prop) +{ + if (prop == &TransformMode) { + auto const mode = static_cast(TransformMode.getValue()); + Originals.setStatus(App::Property::Status::Hidden, mode == Mode::TransformBody); + } + + FeatureRefine::onChanged(prop); +} App::DocumentObjectExecReturn* Transformed::execute() { @@ -205,30 +238,16 @@ App::DocumentObjectExecReturn* Transformed::execute() return App::DocumentObject::StdReturn; } - std::vector originals; auto const mode = static_cast(TransformMode.getValue()); - if (mode == Mode::TransformBody) { - Originals.setStatus(App::Property::Status::Hidden, true); - } else { - Originals.setStatus(App::Property::Status::Hidden, false); - originals = Originals.getValues(); - } - // Remove suppressed features from the list so the transformations behave as if they are not - // there - auto eraseIter = - std::remove_if(originals.begin(), originals.end(), [](App::DocumentObject const* obj) { - auto feature = freecad_cast(obj); - return feature != nullptr && feature->Suppressed.getValue(); - }); - originals.erase(eraseIter, originals.end()); + + std::vector originals = getOriginals(); if (mode == Mode::TransformToolShapes && originals.empty()) { return App::DocumentObject::StdReturn; } if (!this->BaseFeature.getValue()) { - auto body = getFeatureBody(); - if (body) { + if (auto body = getFeatureBody()) { body->setBaseProperty(this); } } diff --git a/src/Mod/PartDesign/App/FeatureTransformed.h b/src/Mod/PartDesign/App/FeatureTransformed.h index 3fe27e8851..015a7f5613 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.h +++ b/src/Mod/PartDesign/App/FeatureTransformed.h @@ -53,9 +53,7 @@ public: /** The features to be transformed */ App::PropertyLinkList Originals; - App::PropertyEnumeration TransformMode; - App::PropertyBool Refine; /** @@ -67,6 +65,8 @@ public: */ Part::Feature* getBaseObject(bool silent = false) const override; + virtual std::vector getOriginals() const; + /// Return the sketch of the first original App::DocumentObject* getSketchObject() const; @@ -94,6 +94,8 @@ public: short mustExecute() const override; //@} + void onChanged(const App::Property* prop) override; + /** returns the compound of the shapes that were rejected during the last execute * because they did not overlap with the support */ diff --git a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp b/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp index 0640e4b135..c45b7c7f8d 100644 --- a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp @@ -569,7 +569,6 @@ void TaskTransformedParameters::exitSelectionMode() clearButtons(); selectionMode = SelectionMode::None; Gui::Selection().rmvSelectionGate(); - showObject(); } catch (Base::Exception& exc) { exc.reportException(); diff --git a/src/Mod/PartDesign/Gui/ViewProvider.cpp b/src/Mod/PartDesign/Gui/ViewProvider.cpp index c97c167193..6ba8634a34 100644 --- a/src/Mod/PartDesign/Gui/ViewProvider.cpp +++ b/src/Mod/PartDesign/Gui/ViewProvider.cpp @@ -203,7 +203,11 @@ void ViewProvider::unsetEdit(int ModNum) void ViewProvider::updateData(const App::Property* prop) { if (strcmp(prop->getName(), "PreviewShape") == 0) { - updatePreviewShape(); + updatePreview(); + } else if (auto* previewExtension = getObject()->getExtensionByType(true)) { + if (!previewExtension->isPreviewFresh() && isEditing()) { + previewExtension->updatePreview(); + } } inherited::updateData(prop); @@ -284,11 +288,11 @@ void ViewProvider::setTipIcon(bool onoff) { signalChangeIcon(); } -QIcon ViewProvider::mergeColorfulOverlayIcons (const QIcon & orig) const +QIcon ViewProvider::mergeColorfulOverlayIcons(const QIcon& orig) const { QIcon mergedicon = orig; - if(isSetTipIcon) { + if (isSetTipIcon) { static QPixmap px(Gui::BitmapFactory().pixmapFromSvg("PartDesign_Overlay_Tip", QSize(10, 10))); mergedicon = Gui::BitmapFactoryInst::mergePixmap(mergedicon, px, Gui::BitmapFactoryInst::BottomRight); } diff --git a/src/Mod/PartDesign/Gui/ViewProviderMirrored.h b/src/Mod/PartDesign/Gui/ViewProviderMirrored.h index f0abf0e0a4..a384d21c00 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderMirrored.h +++ b/src/Mod/PartDesign/Gui/ViewProviderMirrored.h @@ -38,13 +38,12 @@ public: sPixmap = "PartDesign_Mirrored.svg"; } - const std::string & featureName() const override; + const std::string& featureName() const override; void setupContextMenu(QMenu*, QObject*, const char*) override; protected: - /// Returns a newly create dialog for the part to be placed in the task view + /// Returns a newly created dialog for the part to be placed in the task view TaskDlgFeatureParameters *getEditDialog() override; - }; diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp index 73c4aa1225..416819fc29 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp @@ -26,23 +26,9 @@ #ifndef _PreComp_ # include # include -# include # include -# include -# include # include # include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include # include #endif @@ -56,9 +42,11 @@ #include "ViewProviderTransformed.h" #include "TaskTransformedParameters.h" +#include + using namespace PartDesignGui; -PROPERTY_SOURCE(PartDesignGui::ViewProviderTransformed,PartDesignGui::ViewProvider) +PROPERTY_SOURCE(PartDesignGui::ViewProviderTransformed, PartDesignGui::ViewProvider) const std::string & ViewProviderTransformed::featureName() const { @@ -68,99 +56,105 @@ const std::string & ViewProviderTransformed::featureName() const std::string ViewProviderTransformed::featureIcon() const { - return std::string("PartDesign_") + featureName(); + return fmt::format("PartDesign_{}", featureName()); } void ViewProviderTransformed::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) { QString text = QString::fromStdString(getObject()->Label.getStrValue()); addDefaultAction(menu, QObject::tr("Edit %1").arg(text)); - PartDesignGui::ViewProvider::setupContextMenu(menu, receiver, member); + + ViewProvider::setupContextMenu(menu, receiver, member); } Gui::ViewProvider *ViewProviderTransformed::startEditing(int ModNum) { - PartDesign::Transformed* pcTransformed = getObject(); - if(!pcTransformed->Originals.getSize()) { - for(auto obj : pcTransformed->getInList()) { - if(obj->isDerivedFrom()) { - auto vp = Gui::Application::Instance->getViewProvider(obj); - if(vp) - return vp->startEditing(ModNum); - return nullptr; + auto* pcTransformed = getObject(); + + if (!pcTransformed->Originals.getSize()) { + for (auto obj : pcTransformed->getInList()) { + if (!obj->isDerivedFrom()) { + continue; } + + if (auto vp = Gui::Application::Instance->getViewProvider(obj)) { + return vp->startEditing(ModNum); + } + + return nullptr; } } + return ViewProvider::startEditing(ModNum); } bool ViewProviderTransformed::setEdit(int ModNum) { - pcRejectedRoot = new SoSeparator(); - pcRejectedRoot->ref(); - - SoPickStyle* rejectedPickStyle = new SoPickStyle(); - rejectedPickStyle->style = SoPickStyle::UNPICKABLE; - - SoShapeHints* rejectedHints = new SoShapeHints(); - rejectedHints->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING; - 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(rejectedNormb); // NOTE: The code relies on the last child added here being index 6 - pcRoot->addChild(pcRejectedRoot); - recomputeFeature(false); return ViewProvider::setEdit(ModNum); } -void ViewProviderTransformed::unsetEdit(int ModNum) +void ViewProviderTransformed::attachPreview() { - ViewProvider::unsetEdit(ModNum); +} - while (pcRejectedRoot->getNumChildren() > 7) { - SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); - SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); - Gui::coinRemoveAllChildren(rejectedTrfms); - sep->removeChild(1); - sep->removeChild(0); - pcRejectedRoot ->removeChild(7); +void ViewProviderTransformed::updatePreview() +{ + try { + if (auto feature = getObject()) { + auto originals = feature->getOriginals(); + auto transforms = feature->getTransformations(originals); + + if (transforms.empty()) { + return; + } + + transforms.pop_front(); + + Gui::coinRemoveAllChildren(pcPreviewRoot); + + for (const auto& transform : transforms) { + Base::Matrix4D transformMatrix; + Part::TopoShape::convertToMatrix(transform, transformMatrix); + + auto sep = new SoSeparator; + + auto transformNode = new SoTransform; + transformNode->setMatrix(convert(transformMatrix)); + + sep->addChild(transformNode); + sep->addChild(pcPreviewShape); + + pcPreviewRoot->addChild(sep); + } + } + } catch (const Base::Exception& e) { + e.reportException(); } - Gui::coinRemoveAllChildren(pcRejectedRoot); - pcRoot->removeChild(pcRejectedRoot); - - pcRejectedRoot->unref(); + ViewProvider::updatePreview(); } -bool ViewProviderTransformed::onDelete(const std::vector &s) +Part::TopoShape ViewProviderTransformed::getPreviewShape() const { - return ViewProvider::onDelete(s); + if (auto feature = getObject()) { + auto originals = feature->getOriginals(); + + if (originals.empty()) { + return {}; + } + + if (auto first = freecad_cast(originals.front())) { + return first->PreviewShape.getShape(); + } + } + + return {}; } -void ViewProviderTransformed::handleTranformedResult(PartDesign::Transformed* pcTransformed) { +void ViewProviderTransformed::handleTransformedResult(PartDesign::Transformed* pcTransformed) { unsigned rejected = 0; + TopoDS_Shape cShape = pcTransformed->rejected; TopExp_Explorer xp; xp.Init(cShape, TopAbs_SOLID); @@ -178,159 +172,28 @@ void ViewProviderTransformed::handleTranformedResult(PartDesign::Transformed* pc msg = msg.arg(rejected); } } - auto error = pcTransformed->getDocument()->getErrorDescription(pcTransformed); - if (error) { + + if (const char* error = pcTransformed->getDocument()->getErrorDescription(pcTransformed)) { msg = msg.arg(QStringLiteral("%1
")); msg = msg.arg(QString::fromUtf8(error)); } else { msg = msg.arg(QStringLiteral("%1
")); msg = msg.arg(QObject::tr("Transformation succeeded")); } + diagMessage = msg; signalDiagnosis(msg); - - // Clear all the rejected stuff - while (pcRejectedRoot->getNumChildren() > 7) { - SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); - SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); - Gui::coinRemoveAllChildren(rejectedTrfms); - sep->removeChild(1); - sep->removeChild(0); - pcRejectedRoot ->removeChild(7); - } - - // Display the rejected transformations in red - if (rejected > 0) { - showRejectedShape(cShape); - } } void ViewProviderTransformed::recomputeFeature(bool recompute) { - PartDesign::Transformed* pcTransformed = getObject(); - if(recompute || (pcTransformed->isError() || pcTransformed->mustExecute())) + auto* pcTransformed = getObject(); + + if (recompute || pcTransformed->isError() || pcTransformed->mustExecute()) { pcTransformed->recomputeFeature(true); - - handleTranformedResult(pcTransformed); -} - -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 - Standard_Real AngDeflectionRads = Base::toRadians(AngularDeflection.getValue()); - BRepMesh_IncrementalMesh(shape, deflection, Standard_False, AngDeflectionRads, Standard_True); - - // 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 points; - std::vector facets; - if (!Part::Tools::getTriangulation(actFace, points, facets)) - continue; - - // get normal per vertex - std::vector 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()); } + + updatePreview(); + + handleTransformedResult(pcTransformed); } diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h index cce875cff5..1c081b2d76 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h @@ -26,6 +26,8 @@ #include "ViewProvider.h" +#include + namespace PartDesign { class Transformed; } @@ -45,9 +47,11 @@ public: // The feature name of the subclass virtual const std::string & featureName() const; std::string featureIcon() const; + + void recomputeFeature(bool recompute=true); void setupContextMenu(QMenu*, QObject*, const char*) override; - bool onDelete(const std::vector &) override; + Part::TopoShape getPreviewShape() const override; /// signals if the transformation contains errors boost::signals2::signal signalDiagnosis; @@ -57,24 +61,19 @@ public: Gui::ViewProvider *startEditing(int ModNum=0) override; + QString getMessage() const { return diagMessage; } + protected: bool setEdit(int ModNum) override; - void unsetEdit(int ModNum) override; + + void attachPreview() override; + void updatePreview() override; bool checkDlgOpen(TaskDlgTransformedParameters* transformedDlg); - void handleTranformedResult(PartDesign::Transformed* transformed); - - // node for the representation of rejected repetitions - SoGroup * pcRejectedRoot{nullptr}; + void handleTransformedResult(PartDesign::Transformed* transformed); + Gui::CoinPtr pcMultipleCopy; QString diagMessage; - -public: - void recomputeFeature(bool recompute=true); - QString getMessage() const {return diagMessage;} - -private: - void showRejectedShape(TopoDS_Shape shape); };