diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp index c63dd05d3c..6724e6cc85 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,7 @@ DrawProjGroup::DrawProjGroup(void) : ADD_PROPERTY_TYPE(Source ,(0), group, App::Prop_None,"Shape to view"); Source.setScope(App::LinkScope::Global); Source.setAllowExternal(true); + ADD_PROPERTY_TYPE(XSource ,(0),group,App::Prop_None,"External 3D Shape to view"); ADD_PROPERTY_TYPE(Anchor, (0), group, App::Prop_None, "The root view to align projections with"); Anchor.setScope(App::LinkScope::Global); @@ -93,15 +95,28 @@ DrawProjGroup::~DrawProjGroup() { } + +//TODO: this duplicates code in DVP +std::vector DrawProjGroup::getAllSources(void) const +{ +// Base::Console().Message("DPG::getAllSources()\n"); + const std::vector links = Source.getValues(); + std::vector xLinks; + XSource.getLinks(xLinks); + std::vector result = links; + if (!xLinks.empty()) { + result.insert(result.end(), xLinks.begin(), xLinks.end()); + } + return result; +} + + void DrawProjGroup::onChanged(const App::Property* prop) { //TODO: For some reason, when the projection type is changed, the isometric views show change appropriately, but the orthographic ones don't... Or vice-versa. WF: why would you change from 1st to 3rd in mid drawing? //if group hasn't been added to page yet, can't scale or distribute projItems TechDraw::DrawPage *page = getPage(); if (!isRestoring() && page) { - if (prop == &Source) { - //nothing in particular - } if (prop == &Scale) { if (!m_lockScale) { updateChildrenScale(); @@ -112,7 +127,8 @@ void DrawProjGroup::onChanged(const App::Property* prop) updateChildrenEnforce(); } - if (prop == &Source) { + if ( (prop == &Source) || + (prop == &XSource) ) { updateChildrenSource(); } @@ -156,7 +172,7 @@ App::DocumentObjectExecReturn *DrawProjGroup::execute(void) return DrawViewCollection::execute(); } - std::vector docObjs = Source.getValues(); + std::vector docObjs = getAllSources(); if (docObjs.empty()) { return DrawViewCollection::execute(); } @@ -188,6 +204,7 @@ short DrawProjGroup::mustExecute() const if (!isRestoring()) { result = Views.isTouched() || Source.isTouched() || + XSource.isTouched() || Scale.isTouched() || ScaleType.isTouched() || ProjectionType.isTouched() || @@ -428,6 +445,11 @@ App::DocumentObject * DrawProjGroup::addProjection(const char *viewProjType) view->Label.setValue(viewProjType); addView(view); //from DrawViewCollection view->Source.setValues(Source.getValues()); +// std::vector xLinks; +// XSource.getLinks(xLinks); +// view->XSource.setValues(xLinks); + view->XSource.setValues(XSource.getValues()); + // the Scale is already set by DrawView view->Type.setValue(viewProjType); if (strcmp(viewProjType, "Front") != 0 ) { //not Front! @@ -957,8 +979,13 @@ void DrawProjGroup::updateChildrenSource(void) Base::Console().Log("PROBLEM - DPG::updateChildrenSource - non DPGI entry in Views! %s\n", getNameInDocument()); throw Base::TypeError("Error: projection in DPG list is not a DPGI!"); - } else if (view->Source.getValues() != Source.getValues()) { - view->Source.setValues(Source.getValues()); + } else { + if (view->Source.getValues() != Source.getValues()) { + view->Source.setValues(Source.getValues()); + } + if (view->XSource.getValues() != XSource.getValues()) { + view->XSource.setValues(XSource.getValues()); + } } } } diff --git a/src/Mod/TechDraw/App/DrawProjGroup.h b/src/Mod/TechDraw/App/DrawProjGroup.h index 23d5367104..e9985dcf56 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.h +++ b/src/Mod/TechDraw/App/DrawProjGroup.h @@ -27,6 +27,8 @@ # include #include #include +#include + #include #include @@ -55,7 +57,9 @@ public: DrawProjGroup(); ~DrawProjGroup(); - App::PropertyLinkList Source; + App::PropertyLinkList Source; + App::PropertyXLinkList XSource; + App::PropertyEnumeration ProjectionType; App::PropertyBool AutoDistribute; @@ -134,6 +138,9 @@ public: void autoPositionChildren(void); void updateChildrenEnforce(void); + std::vector getAllSources(void) const; + + protected: void onChanged(const App::Property* prop) override; diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index 36ac741e83..320b719e4d 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -86,6 +86,7 @@ short DrawProjGroupItem::mustExecute() const result = (Direction.isTouched() || XDirection.isTouched() || Source.isTouched() || + XSource.isTouched() || Scale.isTouched()); } @@ -174,6 +175,7 @@ void DrawProjGroupItem::autoPosition() void DrawProjGroupItem::onDocumentRestored() { +// Base::Console().Message("DPGI::onDocumentRestored() - %s\n", getNameInDocument()); App::DocumentObjectExecReturn* rc = DrawProjGroupItem::execute(); if (rc) { delete rc; diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index e1f95e7d4b..09e791ad7c 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -143,6 +143,8 @@ DrawViewPart::DrawViewPart(void) : ADD_PROPERTY_TYPE(Source ,(0),group,App::Prop_None,"3D Shape to view"); Source.setScope(App::LinkScope::Global); Source.setAllowExternal(true); + ADD_PROPERTY_TYPE(XSource ,(0),group,App::Prop_None,"External 3D Shape to view"); + ADD_PROPERTY_TYPE(Direction ,(0.0,-1.0,0.0), group,App::Prop_None,"Projection Plane normal. The direction you are looking from."); @@ -181,7 +183,7 @@ std::vector DrawViewPart::getSourceShape2d(void) const { // Base::Console().Message("DVP::getSourceShape2d()\n"); std::vector result; - const std::vector& links = Source.getValues(); + const std::vector& links = getAllSources(); result = ShapeExtractor::getShapes2d(links); return result; } @@ -189,8 +191,9 @@ std::vector DrawViewPart::getSourceShape2d(void) const TopoDS_Shape DrawViewPart::getSourceShape(void) const { +// Base::Console().Message("DVP::getSourceShape()\n"); TopoDS_Shape result; - const std::vector& links = Source.getValues(); + const std::vector& links = getAllSources(); if (links.empty()) { bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring); if (isRestoring) { @@ -208,8 +211,10 @@ TopoDS_Shape DrawViewPart::getSourceShape(void) const TopoDS_Shape DrawViewPart::getSourceShapeFused(void) const { +// Base::Console().Message("DVP::getSourceShapeFused()\n"); TopoDS_Shape result; - const std::vector& links = Source.getValues(); +// const std::vector& links = Source.getValues(); + const std::vector& links = getAllSources(); if (links.empty()) { bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring); if (isRestoring) { @@ -225,6 +230,20 @@ TopoDS_Shape DrawViewPart::getSourceShapeFused(void) const return result; } +std::vector DrawViewPart::getAllSources(void) const +{ +// Base::Console().Message("DVP::getAllSources()\n"); + const std::vector links = Source.getValues(); + std::vector xLinks = XSource.getValues(); +// std::vector xLinks; +// XSource.getLinks(xLinks); + + std::vector result = links; + if (!xLinks.empty()) { + result.insert(result.end(), xLinks.begin(), xLinks.end()); + } + return result; +} App::DocumentObjectExecReturn *DrawViewPart::execute(void) { @@ -232,10 +251,13 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) if (!keepUpdated()) { return App::DocumentObject::StdReturn; } + +// Base::Console().Message("DVP::execute - Source: %d XSource: %d\n", +// Source.getValues().size(), XSource.getValues().size()); App::Document* doc = getDocument(); bool isRestoring = doc->testStatus(App::Document::Status::Restoring); - const std::vector& links = Source.getValues(); + const std::vector& links = getAllSources(); if (links.empty()) { if (isRestoring) { Base::Console().Warning("DVP::execute - No Sources (but document is restoring) - %s\n", @@ -246,7 +268,6 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) } return App::DocumentObject::StdReturn; } - std::vector sources = Source.getValues(); TopoDS_Shape shape = getSourceShape(); if (shape.IsNull()) { @@ -307,6 +328,7 @@ short DrawViewPart::mustExecute() const if (!isRestoring()) { result = (Direction.isTouched() || Source.isTouched() || + XSource.isTouched() || Perspective.isTouched() || Focus.isTouched() || Rotation.isTouched() || diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 1c679be64e..c366e44823 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -93,6 +93,7 @@ public: virtual ~DrawViewPart(); App::PropertyLinkList Source; + App::PropertyXLinkList XSource; App::PropertyVector Direction; //TODO: Rename to YAxisDirection or whatever this actually is (ProjectionDirection) App::PropertyVector XDirection; App::PropertyBool Perspective; @@ -202,6 +203,9 @@ public: void removeAllReferencesFromGeom(); void resetReferenceVerts(); + std::vector getAllSources(void) const; + + protected: bool checkXDirection(void) const; diff --git a/src/Mod/TechDraw/Gui/Command.cpp b/src/Mod/TechDraw/Gui/Command.cpp index 89b680d198..7a82f0210f 100644 --- a/src/Mod/TechDraw/Gui/Command.cpp +++ b/src/Mod/TechDraw/Gui/Command.cpp @@ -30,28 +30,30 @@ #include -#include -#include -#include #include #include -#include #include +#include #include -#include #include +#include +#include +#include #include #include +#include #include +#include +#include #include #include #include #include #include #include -#include -#include #include +#include +#include #include #include @@ -304,6 +306,7 @@ void CmdTechDrawView::activated(int iMsg) //set projection direction from selected Face //use first object with a face selected std::vector shapes; + std::vector xShapes; App::DocumentObject* partObj = nullptr; std::string faceName; int resolve = 1; //mystery @@ -317,22 +320,33 @@ void CmdTechDrawView::activated(int iMsg) if (obj->isDerivedFrom(TechDraw::DrawPage::getClassTypeId()) ) { continue; } + if ( obj->isDerivedFrom(App::LinkElement::getClassTypeId()) || + obj->isDerivedFrom(App::LinkGroup::getClassTypeId()) || + obj->isDerivedFrom(App::Link::getClassTypeId()) ) { + xShapes.push_back(obj); + continue; + } + //not a Link and not null. assume to be drawable. Undrawables will be + // skipped later. if (obj != nullptr) { shapes.push_back(obj); } if(partObj != nullptr) { continue; } + //don't know if this works for an XLink for(auto& sub : sel.getSubNames()) { if (TechDraw::DrawUtil::getGeomTypeFromName(sub) == "Face") { faceName = sub; + // partObj = obj; break; } } } - if ((shapes.empty())) { + if ( shapes.empty() && + xShapes.empty() ) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QObject::tr("No Shapes, Groups or Links in this selection")); return; @@ -350,6 +364,7 @@ void CmdTechDrawView::activated(int iMsg) throw Base::TypeError("CmdTechDrawView DVP not found\n"); } dvp->Source.setValues(shapes); + dvp->XSource.setValues(xShapes); doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); if (faceName.size()) { std::pair dirs = DrawGuiUtil::getProjDirFromFace(partObj,faceName); @@ -450,26 +465,6 @@ void CmdTechDrawSectionView::activated(int iMsg) return; } TechDraw::DrawViewPart* dvp = static_cast(*baseObj.begin()); -// std::string BaseName = dvp->getNameInDocument(); -// std::string PageName = page->getNameInDocument(); -// double baseScale = dvp->getScale(); - -// Gui::WaitCursor wc; -// openCommand("Create view"); -// std::string FeatName = getUniqueObjectName("Section"); - -// doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawViewSection','%s')",FeatName.c_str()); - -// App::DocumentObject *docObj = getDocument()->getObject(FeatName.c_str()); -// TechDraw::DrawViewSection* dsv = dynamic_cast(docObj); -// if (!dsv) { -// throw Base::TypeError("CmdTechDrawSectionView DVS not found\n"); -// } -// dsv->Source.setValues(dvp->Source.getValues()); -// doCommand(Doc,"App.activeDocument().%s.BaseView = App.activeDocument().%s",FeatName.c_str(),BaseName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.ScaleType = App.activeDocument().%s.ScaleType",FeatName.c_str(),BaseName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str()); -// doCommand(Doc,"App.activeDocument().%s.Scale = %0.6f",FeatName.c_str(),baseScale); Gui::Control().showDialog(new TaskDlgSectionView(dvp)); updateActive(); //ok here since dialog doesn't call doc.recompute() @@ -568,6 +563,7 @@ void CmdTechDrawProjectionGroup::activated(int iMsg) //set projection direction from selected Face //use first object with a face selected std::vector shapes; + std::vector xShapes; App::DocumentObject* partObj = nullptr; std::string faceName; int resolve = 1; //mystery @@ -577,14 +573,19 @@ void CmdTechDrawProjectionGroup::activated(int iMsg) resolve, single); for (auto& sel: selection) { -// for(auto &sel : getSelection().getSelectionEx(0,App::DocumentObject::getClassTypeId(),false)) { auto obj = sel.getObject(); if (obj->isDerivedFrom(TechDraw::DrawPage::getClassTypeId()) ) { continue; } -// if(!obj || inlist.count(obj)) //?????? -// continue; - if (obj != nullptr) { //can this happen? + if ( obj->isDerivedFrom(App::LinkElement::getClassTypeId()) || + obj->isDerivedFrom(App::LinkGroup::getClassTypeId()) || + obj->isDerivedFrom(App::Link::getClassTypeId()) ) { + xShapes.push_back(obj); + continue; + } + //not a Link and not null. assume to be drawable. Undrawables will be + // skipped later. + if (obj != nullptr) { shapes.push_back(obj); } if(partObj != nullptr) { @@ -598,9 +599,10 @@ void CmdTechDrawProjectionGroup::activated(int iMsg) } } } - if (shapes.empty()) { + if ( shapes.empty() && + xShapes.empty() ) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("No Shapes or Groups in this selection")); + QObject::tr("No Shapes, Groups or Links in this selection")); return; } @@ -618,6 +620,7 @@ void CmdTechDrawProjectionGroup::activated(int iMsg) App::DocumentObject *docObj = getDocument()->getObject(multiViewName.c_str()); auto multiView( static_cast(docObj) ); multiView->Source.setValues(shapes); + multiView->XSource.setValues(xShapes); doCommand(Doc,"App.activeDocument().%s.addProjection('Front')",multiViewName.c_str()); if (faceName.size()) {