diff --git a/src/Mod/Part/App/modelRefine.h b/src/Mod/Part/App/modelRefine.h index 29e97ccbb..8efa1271b 100644 --- a/src/Mod/Part/App/modelRefine.h +++ b/src/Mod/Part/App/modelRefine.h @@ -37,6 +37,7 @@ #include #include #include +#include namespace ModelRefine diff --git a/src/Mod/PartDesign/App/AppPartDesign.cpp b/src/Mod/PartDesign/App/AppPartDesign.cpp index cad48c424..651889fe0 100644 --- a/src/Mod/PartDesign/App/AppPartDesign.cpp +++ b/src/Mod/PartDesign/App/AppPartDesign.cpp @@ -52,6 +52,7 @@ #include "DatumPoint.h" #include "FeatureBoolean.h" #include "FeaturePrimitive.h" +#include "DatumCS.h" namespace PartDesign { extern PyObject* initModule(); @@ -101,13 +102,15 @@ PyMODINIT_FUNC init_PartDesign() PartDesign::Plane ::init(); PartDesign::Line ::init(); PartDesign::Point ::init(); + PartDesign::CoordinateSystem ::init(); PartDesign::Boolean ::init(); PartDesign::FeaturePrimitive ::init(); PartDesign::Box ::init(); PartDesign::AdditiveBox ::init(); PartDesign::SubtractiveBox ::init(); - PartDesign::Point::initHints(); - PartDesign::Line ::initHints(); - PartDesign::Plane::initHints(); + PartDesign::Point ::initHints(); + PartDesign::Line ::initHints(); + PartDesign::Plane ::initHints(); + PartDesign::CoordinateSystem ::initHints(); } diff --git a/src/Mod/PartDesign/App/CMakeLists.txt b/src/Mod/PartDesign/App/CMakeLists.txt index 07b995e5c..6cf9b899e 100644 --- a/src/Mod/PartDesign/App/CMakeLists.txt +++ b/src/Mod/PartDesign/App/CMakeLists.txt @@ -46,6 +46,8 @@ SET(DatumFeatures_SRCS DatumLine.h DatumPoint.cpp DatumPoint.h + DatumCS.h + DatumCS.cpp ) SOURCE_GROUP("DatumFeatures" FILES ${DatumFeatures_SRCS}) diff --git a/src/Mod/PartDesign/App/FeaturePrimitive.cpp b/src/Mod/PartDesign/App/FeaturePrimitive.cpp index c752d2951..310821bd0 100644 --- a/src/Mod/PartDesign/App/FeaturePrimitive.cpp +++ b/src/Mod/PartDesign/App/FeaturePrimitive.cpp @@ -27,32 +27,48 @@ #include "FeaturePrimitive.h" +#include "DatumPoint.h" +#include #include #include +#include #include #include #include #include +#include using namespace PartDesign; namespace PartDesign { - PROPERTY_SOURCE(PartDesign::FeaturePrimitive, PartDesign::FeatureAddSub) FeaturePrimitive::FeaturePrimitive() : primitiveType(Box) { - ADD_PROPERTY(References, (0,0));//, "Primitive", (App::PropertyType)(App::Prop_None), "References to build the location of the primitive"); + ADD_PROPERTY_TYPE(CoordinateSystem, (0), "Primitive", App::Prop_None, "References to build the location of the primitive"); +} + +TopoDS_Shape FeaturePrimitive::refineShapeIfActive(const TopoDS_Shape& oldShape) const +{ + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/PartDesign"); + if (hGrp->GetBool("RefineModel", false)) { + Part::BRepBuilderAPI_RefineModel mkRefine(oldShape); + TopoDS_Shape resShape = mkRefine.Shape(); + return resShape; + } + + return oldShape; } App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& primitiveShape) { try { //transform the primitive in the correct coordinance - BRepBuilderAPI_GTransform mkTrf(primitiveShape, getLocation().Transformation()); - const TopoDS_Shape primitiveShape = mkTrf.Shape(); + //BRepBuilderAPI_GTransform mkTrf(primitiveShape, getLocation().Transformation()); + //const TopoDS_Shape primitiveShape = mkTrf.Shape(); //if we have no base we just add the standart primitive shape TopoDS_Shape base; @@ -81,6 +97,7 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri if (boolOp.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); + boolOp = refineShapeIfActive(boolOp); Shape.setValue(boolOp); AddSubShape.setValue(primitiveShape); } @@ -95,6 +112,7 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri if (boolOp.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is not a solid"); + boolOp = refineShapeIfActive(boolOp); Shape.setValue(boolOp); AddSubShape.setValue(primitiveShape); } @@ -109,9 +127,49 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri return App::DocumentObject::StdReturn; } -TopLoc_Location FeaturePrimitive::calculateLocation() -{ - return TopLoc_Location(); +void FeaturePrimitive::onChanged(const App::Property* prop) +{/* + if ((prop == &CoordinateSystem)) { + std::multiset refTypes; + std::vector refs = References.getValues(); + std::vector refnames = References.getSubValues(); + if (refs.size() != refnames.size()) + return; + + for (int r = 0; r < refs.size(); r++) + refTypes.insert(getRefType(refs[r], refnames[r])); + + std::set hint; + if (hints.find(refTypes) != hints.end()) + hint = hints[refTypes]; + + if (!((hint.size() == 1) && (hint.find(QObject::tr("Done")) != hint.end()))) + return; // incomplete references + + std::pair origin = {Base::Vector3d(), false}; + std::pair dirX = {Base::Vector3d(), false}; + std::pair dirY = {Base::Vector3d(), false}; + + for (int i = 0; i < refs.size(); i++) { + + if (refs[i]->getTypeId().isDerivedFrom(PartDesign::Point::getClassTypeId())) { + Base::Vector3d point = static_cast(refs[i])->getPoint(); + if (!origin.second) + origin = {point, true}; + else if(!dirX.second) { + if((point-dirX.first).Sqr() < Precision::Confusion()) + return; + dirX = {point, true}; + } + else if(!dirY.second) { + if((origin.first-dirX.first).Sqr() < Precision::Confusion()) + return; + dirY = {point, true}; + } + } + } + } */ + FeatureAddSub::onChanged(prop); } PROPERTY_SOURCE(PartDesign::Box, PartDesign::FeaturePrimitive) diff --git a/src/Mod/PartDesign/App/FeaturePrimitive.h b/src/Mod/PartDesign/App/FeaturePrimitive.h index c809a74fb..34e522696 100644 --- a/src/Mod/PartDesign/App/FeaturePrimitive.h +++ b/src/Mod/PartDesign/App/FeaturePrimitive.h @@ -48,19 +48,17 @@ public: virtual const char* getViewProviderName(void) const { return "PartDesignGui::ViewProviderPrimitive"; } - Type getPrimitiveType() {return primitiveType;}; + Type getPrimitiveType() {return primitiveType;}; + TopoDS_Shape refineShapeIfActive(const TopoDS_Shape& oldShape) const; + virtual void onChanged(const App::Property* prop); - /// The references defining the primtive base - App::PropertyLinkSubList References; + /// The references datum defining the primtive location + App::PropertyLink CoordinateSystem; protected: //make the boolean ops with the primitives provided by the derived features App::DocumentObjectExecReturn* execute(const TopoDS_Shape& primitiveShape); - - //calculate the position of the primitive from the support and the exis - TopLoc_Location calculateLocation(); - - Type primitiveType; + Type primitiveType = Box; }; class PartDesignExport Box : public PartDesign::FeaturePrimitive { diff --git a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp index 15ffd3d8d..cbc433bba 100644 --- a/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp +++ b/src/Mod/PartDesign/Gui/AppPartDesignGui.cpp @@ -55,6 +55,7 @@ #include "ViewProviderDatumPlane.h" #include "ViewProviderBoolean.h" #include "ViewProviderPrimitive.h" +#include "ViewProviderDatumCS.h" // use a different name to CreateCommand() void CreatePartDesignCommands(void); @@ -134,6 +135,7 @@ PyMODINIT_FUNC initPartDesignGui() PartDesignGui::ViewProviderDatumPoint ::init(); PartDesignGui::ViewProviderDatumLine ::init(); PartDesignGui::ViewProviderDatumPlane ::init(); + PartDesignGui::ViewProviderDatumCoordinateSystem::init(); PartDesignGui::ViewProviderBoolean ::init(); PartDesignGui::ViewProviderPrimitive ::init(); diff --git a/src/Mod/PartDesign/Gui/CMakeLists.txt b/src/Mod/PartDesign/Gui/CMakeLists.txt index 2b3c7b7c9..89899d3ad 100644 --- a/src/Mod/PartDesign/Gui/CMakeLists.txt +++ b/src/Mod/PartDesign/Gui/CMakeLists.txt @@ -48,6 +48,7 @@ set(PartDesignGui_MOC_HDRS TaskMultiTransformParameters.h TaskDatumParameters.h TaskBooleanParameters.h + TaskPrimitiveParameters.h ) fc_wrap_cpp(PartDesignGui_MOC_SRCS ${PartDesignGui_MOC_HDRS}) SOURCE_GROUP("Moc" FILES ${PartDesignGui_MOC_SRCS}) @@ -118,6 +119,8 @@ SET(PartDesignGuiViewProvider_SRCS CommandPrimitive.cpp ViewProviderDatumLine.h ViewProviderDatumPlane.cpp ViewProviderDatumPlane.h + ViewProviderDatumCS.cpp + ViewProviderDatumCS.h ViewProviderBoolean.cpp ViewProviderBoolean.h ViewProviderPrimitive.h @@ -185,6 +188,8 @@ SET(PartDesignGuiTaskDlgs_SRCS TaskBooleanParameters.ui TaskBooleanParameters.cpp TaskBooleanParameters.h + TaskPrimitiveParameters.h + TaskPrimitiveParameters.cpp ) SOURCE_GROUP("TaskDialogs" FILES ${PartDesignGuiTaskDlgs_SRCS}) diff --git a/src/Mod/PartDesign/Gui/CommandPrimitive.cpp b/src/Mod/PartDesign/Gui/CommandPrimitive.cpp index 36493c39b..56247f2fa 100644 --- a/src/Mod/PartDesign/Gui/CommandPrimitive.cpp +++ b/src/Mod/PartDesign/Gui/CommandPrimitive.cpp @@ -54,7 +54,6 @@ CmdPrimtiveCompAdditive::CmdPrimtiveCompAdditive() void CmdPrimtiveCompAdditive::activated(int iMsg) { - Base::Console().Message("activated msg %i\n", iMsg); PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if (!pcActiveBody) return; @@ -62,13 +61,23 @@ void CmdPrimtiveCompAdditive::activated(int iMsg) if(iMsg == 0) { std::string FeatName = getUniqueObjectName("Box"); + std::string CSName = getUniqueObjectName("CoordinateSystem"); Gui::Command::openCommand("Make additive box"); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\'PartDesign::AdditiveBox\',\'%s\')", + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.addObject(\'PartDesign::AdditiveBox\',\'%s\')", FeatName.c_str()); - Gui::Command::doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)" + Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addFeature(App.activeDocument().%s)" ,pcActiveBody->getNameInDocument(), FeatName.c_str()); - Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().setEdit(\'%s\')", FeatName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.addObject(\'PartDesign::CoordinateSystem\',\'%s\')", + CSName.c_str()); + Gui::Command::doCommand(Doc,"App.ActiveDocument.%s.addFeature(App.activeDocument().%s)" + ,pcActiveBody->getNameInDocument(), CSName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.CoordinateSystem=(App.ActiveDocument.%s)", + FeatName.c_str(), CSName.c_str()); + Gui::Command::updateActive(); + + Gui::Command::doCommand(Gui, "Gui.activeDocument().hide(\'%s\')", CSName.c_str()); + Gui::Command::doCommand(Gui, "Gui.activeDocument().setEdit(\'%s\')", FeatName.c_str()); } } @@ -135,17 +144,22 @@ CmdPrimtiveCompSubtractive::CmdPrimtiveCompSubtractive() } void CmdPrimtiveCompSubtractive::activated(int iMsg) -{ - Base::Console().Message("activated msg %i\n", iMsg); - return; - - // Since the default icon is reset when enabing/disabling the command we have - // to explicitly set the icon of the used command. - Gui::ActionGroup* pcAction = qobject_cast(_pcAction); - QList a = pcAction->actions(); - - assert(iMsg < a.size()); - pcAction->setIcon(a[iMsg]->icon()); +{ + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + if (!pcActiveBody) return; + + if(iMsg == 0) { + + std::string FeatName = getUniqueObjectName("Box"); + + Gui::Command::openCommand("Make subtractive box"); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\'PartDesign::SubtractiveBox\',\'%s\')", + FeatName.c_str()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)" + ,pcActiveBody->getNameInDocument(), FeatName.c_str()); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().setEdit(\'%s\')", FeatName.c_str()); + Gui::Command::updateActive(); + } } Gui::Action * CmdPrimtiveCompSubtractive::createAction(void) diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp index 46ec22793..09427876b 100644 --- a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp @@ -277,7 +277,9 @@ void TaskDatumParameters::updateUI() std::set hint = pcDatum->getHint(); if (hint == std::set()) { - QMessageBox::warning(this, tr("Illegal selection"), tr("This feature cannot be created with this combination of references")); + if(!refs.empty()) + QMessageBox::warning(this, tr("Illegal selection"), tr("This feature cannot be created with this combination of references")); + if (refs.size() == 1) { onButtonRef1(true); } else if (refs.size() == 2) { diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp index 6160fece6..de5ae55eb 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "Base/Console.h" @@ -184,7 +185,7 @@ void ViewProviderBody::updateData(const App::Property* prop) // (prop->getTypeId() == App::PropertyLinkList::getClassTypeId() && strcmp(prop->getName(),"Model") == 0)) // // updateTree(); - // Update the visual size of datum lines and planes + // Update the visual size of datums PartDesign::Body* body = static_cast(getObject()); std::vector features = body->Model.getValues(); for (std::vector::const_iterator f = features.begin(); f != features.end(); f++) { @@ -193,6 +194,8 @@ void ViewProviderBody::updateData(const App::Property* prop) plm = &(static_cast(*f)->Placement); else if ((*f)->getTypeId().isDerivedFrom(PartDesign::Plane::getClassTypeId())) plm = &(static_cast(*f)->Placement); + else if ((*f)->getTypeId().isDerivedFrom(PartDesign::CoordinateSystem::getClassTypeId())) + plm = &(static_cast(*f)->Placement); if (plm != NULL) { Gui::ViewProviderDocumentObject* vp = dynamic_cast(Gui::Application::Instance->getViewProvider(*f)); diff --git a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp index a3c25dd02..7648e031b 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDatum.cpp @@ -62,6 +62,7 @@ #include #include #include +#include using namespace PartDesignGui; @@ -92,6 +93,8 @@ void ViewProviderDatum::attach(App::DocumentObject *obj) datumType = QObject::tr("Line"); else if (o->getTypeId() == PartDesign::Point::getClassTypeId()) datumType = QObject::tr("Point"); + else if (o->getTypeId() == PartDesign::CoordinateSystem::getClassTypeId()) + datumType = QObject::tr("CoordinateSystem"); SoShapeHints* hints = new SoShapeHints(); hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE); diff --git a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp index b634877a8..1c4b39df0 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * + * Copyright (c) 2015 Stefan Tröger * * * * This file is part of the FreeCAD CAx development system. * * * @@ -28,11 +28,13 @@ #endif #include "ViewProviderPrimitive.h" +#include "TaskPrimitiveParameters.h" #include #include #include #include #include +#include using namespace PartDesignGui; @@ -49,16 +51,16 @@ ViewProviderPrimitive::~ViewProviderPrimitive() } bool ViewProviderPrimitive::setEdit(int ModNum) -{/* +{ if (ModNum == ViewProvider::Default ) { // When double-clicking on the item for this fillet the // object unsets and sets its edit mode without closing // the task panel Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgBooleanParameters *booleanDlg = qobject_cast(dlg); - if (booleanDlg && booleanDlg->getBooleanView() != this) - booleanDlg = 0; // another pad left open its task panel - if (dlg && !booleanDlg) { + TaskPrimitiveParameters *primitiveDlg = qobject_cast(dlg); + if (primitiveDlg) + primitiveDlg = 0; // another pad left open its task panel + if (dlg && !primitiveDlg) { QMessageBox msgBox; msgBox.setText(QObject::tr("A dialog is already open in the task panel")); msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); @@ -78,18 +80,24 @@ bool ViewProviderPrimitive::setEdit(int ModNum) oldWb = Gui::Command::assureWorkbench("PartDesignWorkbench"); // start the edit dialog - if (booleanDlg) - Gui::Control().showDialog(booleanDlg); + if (primitiveDlg) + Gui::Control().showDialog(primitiveDlg); else - Gui::Control().showDialog(new TaskDlgBooleanParameters(this)); + Gui::Control().showDialog(new TaskPrimitiveParameters(this)); return true; } else { return PartGui::ViewProviderPart::setEdit(ModNum); - }*/ - - return false; + } } +std::vector< App::DocumentObject* > ViewProviderPrimitive::claimChildren(void) const { + +// Base::Console().Message("claim children\n"); + std::vector< App::DocumentObject* > vec; + vec.push_back(static_cast(getObject())->CoordinateSystem.getValue()); + + return vec; +} diff --git a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h index dbe54c821..106688aef 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h +++ b/src/Mod/PartDesign/Gui/ViewProviderPrimitive.h @@ -39,6 +39,8 @@ public: /// destructor virtual ~ViewProviderPrimitive(); + virtual std::vector< App::DocumentObject* > claimChildren(void) const; + protected: virtual bool setEdit(int ModNum); };