Skip to content

Commit

Permalink
Sketcher: add support for sketch exports
Browse files Browse the repository at this point in the history
SketchObject now use the new TopoShape element name mapping to expose
mapped geometry topological names during editing. SketchExport exports
the editing geometry using those mapped names.

The SketchExport acts just like SketchObject to the end-user, except
that you can't directly edit its content. Instead, when you double
click a SketchExport, it forwards the editing request to its parent
SketchObject, and then pre-selects the exported geometries. You can
then changed the export by selecting/removing geometries.

The SketchExport is a Part2DObject, meaning that it can be mapped onto
other faces, independent of its parent SketchObject. If no mapping,
then it follows the parent SketchObject placement. If mapped, when you
double click to edit the SketchExport, it will start editing the parent
SketchObject in the placement of the SketchExport.
  • Loading branch information
realthunder committed Mar 3, 2018
1 parent 6d005b7 commit 5fc101b
Show file tree
Hide file tree
Showing 19 changed files with 1,301 additions and 138 deletions.
1 change: 1 addition & 0 deletions src/Mod/Sketcher/App/AppSketcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ PyMOD_INIT_FUNC(Sketcher)

Sketcher::SketchObjectSF ::init();
Sketcher::SketchObject ::init();
Sketcher::SketchExport ::init();
Sketcher::SketchObjectPython ::init();
Sketcher::Sketch ::init();
Sketcher::Constraint ::init();
Expand Down
448 changes: 416 additions & 32 deletions src/Mod/Sketcher/App/SketchObject.cpp

Large diffs are not rendered by default.

46 changes: 43 additions & 3 deletions src/Mod/Sketcher/App/SketchObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <Mod/Part/App/PropertyGeometryList.h>
#include <Mod/Sketcher/App/PropertyConstraintList.h>

#include <App/Document.h>
#include "Sketch.h"

namespace Sketcher
Expand All @@ -58,6 +59,8 @@ class SketcherExport SketchObject : public Part::Part2DObject
Part ::PropertyGeometryList Geometry;
Sketcher::PropertyConstraintList Constraints;
App ::PropertyLinkSubList ExternalGeometry;
App ::PropertyLinkList Exports;
App ::PropertyInteger LastGeoID;
/** @name methods override Feature */
//@{
/// recalculate the Feature (if no recompute is needed see also solve() and solverNeedsUpdate boolean)
Expand Down Expand Up @@ -353,7 +356,16 @@ class SketcherExport SketchObject : public Part::Part2DObject
virtual DocumentObject *getSubObject(const char *subname, PyObject **pyObj=0,
Base::Matrix4D *mat=0, bool transform=true, int depth=0) const override;

std::vector<std::string> checkSubNames(const std::vector<std::string> &) const;
std::string checkSubName(const char *) const;
bool geoIdFromShapeType(const char *shapetype, int &geoId, PointPos &posId) const;
std::string convertSubName(const char *) const;
std::string convertSubName(const std::string &subname) const
{ return convertSubName(subname.c_str()); }
std::vector<std::pair<Base::Vector3d,std::string> > getPointRefs(const char *subname);

protected:

/// get called by the container when a property has changed
virtual void onChanged(const App::Property* /*prop*/);
virtual void onDocumentRestored();
Expand Down Expand Up @@ -403,13 +415,41 @@ class SketcherExport SketchObject : public Part::Part2DObject
boost::signals::scoped_connection constraintsRemovedConn;

bool AutoLockTangencyAndPerpty(Constraint* cstr, bool bForce = false, bool bLock = true);

mutable std::vector<App::Document::StringID> externalGeoKeys;
mutable std::map<long,std::pair<long,long> > externalGeoMap;
mutable std::map<long,long> geoMap;
mutable bool geoCached;
};

typedef App::FeaturePythonT<SketchObject> SketchObjectPython;

const std::string &editPrefix();
std::vector<std::string> checkSubNames(const std::vector<std::string> &);
const char *checkSubName(const char *);
// ---------------------------------------------------------

class SketcherExport SketchExport: public Part::Part2DObject {
PROPERTY_HEADER(Sketcher::SketchObject);

public:
SketchExport();
~SketchExport();

App::PropertyStringList Refs;
App::PropertyString Base;

App::DocumentObjectExecReturn *execute(void);
virtual void onChanged(const App::Property* /*prop*/);
const char* getViewProviderName(void) const {
return "SketcherGui::ViewProviderSketchExport";
}

bool update();

App::DocumentObject *getBase() const;
std::set<std::string> getRefs() const;
const char *getElementName(const char *element) const;

virtual short mustExecute(void) const override;
};

} //namespace Sketcher

Expand Down
1 change: 1 addition & 0 deletions src/Mod/Sketcher/Gui/AppSketcherGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ PyMOD_INIT_FUNC(SketcherGui)

// init objects
SketcherGui::ViewProviderSketch ::init();
SketcherGui::ViewProviderSketchExport ::init();
SketcherGui::ViewProviderPython ::init();
SketcherGui::ViewProviderCustom ::init();
SketcherGui::ViewProviderCustomPython ::init();
Expand Down
4 changes: 2 additions & 2 deletions src/Mod/Sketcher/Gui/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,8 +613,8 @@ void CmdSketcherViewSketch::activated(int iMsg)
Gui::Document *doc = getActiveGuiDocument();
SketcherGui::ViewProviderSketch* vp = dynamic_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
if (vp) {
doCommand(Gui,"Gui.ActiveDocument.ActiveView.setCameraOrientation(%s.Placement.Rotation.Q)"
,getObjectCmd(vp->getObject()).c_str());
runCommand(Gui,"Gui.ActiveDocument.ActiveView.setCameraOrientation("
"App.Placement(Gui.editDocument().EditingTransform).Rotation.Q)");
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Mod/Sketcher/Gui/CommandAlterGeometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ void CmdSketcherToggleConstruction::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select edge(s) from the sketch."));
Expand Down
50 changes: 25 additions & 25 deletions src/Mod/Sketcher/Gui/CommandConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ int SketchSelection::setUp(void)
}

SketchObj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
SketchSubNames = checkSubNames(selection[0].getSubNames());
SketchSubNames = selection[0].getSubNames();
} else if(selection.size() == 2) {
if(selection[0].getObject()->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())){
SketchObj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
Expand All @@ -762,8 +762,8 @@ int SketchSelection::setUp(void)
}
// assume always a Part::Feature derived object as support
assert(selection[1].getObject()->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()));
SketchSubNames = checkSubNames(selection[0].getSubNames());
SupportSubNames = checkSubNames(selection[1].getSubNames());
SketchSubNames = selection[0].getSubNames();
SupportSubNames = selection[1].getSubNames();

} else if (selection[1].getObject()->getTypeId().isDerivedFrom(Sketcher::SketchObject::getClassTypeId())) {
SketchObj = static_cast<Sketcher::SketchObject*>(selection[1].getObject());
Expand All @@ -774,8 +774,8 @@ int SketchSelection::setUp(void)
}
// assume always a Part::Feature derived object as support
assert(selection[0].getObject()->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()));
SketchSubNames = checkSubNames(selection[1].getSubNames());
SupportSubNames = checkSubNames(selection[0].getSubNames());
SketchSubNames = selection[1].getSubNames();
SupportSubNames = selection[0].getSubNames();

} else {
ErrorMsg = QObject::tr("One of the selected has to be on the sketch");
Expand Down Expand Up @@ -1197,7 +1197,7 @@ void CmdSketcherConstrainHorizontal::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();

Expand Down Expand Up @@ -1444,7 +1444,7 @@ void CmdSketcherConstrainVertical::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());
const std::vector< Sketcher::Constraint * > &vals = Obj->Constraints.getValues();

Expand Down Expand Up @@ -1690,7 +1690,7 @@ void CmdSketcherConstrainLock::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

std::vector<int> GeoId;
Expand Down Expand Up @@ -1952,7 +1952,7 @@ void CmdSketcherConstrainBlock::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

// Check that the solver does not report redundant/conflicting constraints
Expand Down Expand Up @@ -2262,7 +2262,7 @@ void CmdSketcherConstrainCoincident::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.size() < 2) {
Expand Down Expand Up @@ -2455,7 +2455,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.size() < 1 || SubNames.size() > 2) {
Expand Down Expand Up @@ -2828,7 +2828,7 @@ void CmdSketcherConstrainPointOnObject::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

//count curves and points
Expand Down Expand Up @@ -3011,7 +3011,7 @@ void CmdSketcherConstrainDistanceX::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.size() < 1 || SubNames.size() > 2) {
Expand Down Expand Up @@ -3257,7 +3257,7 @@ void CmdSketcherConstrainDistanceY::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.size() < 1 || SubNames.size() > 2) {
Expand Down Expand Up @@ -3539,7 +3539,7 @@ void CmdSketcherConstrainParallel::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

// go through the selected subelements
Expand Down Expand Up @@ -3747,7 +3747,7 @@ void CmdSketcherConstrainPerpendicular::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = dynamic_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (!Obj || (SubNames.size() != 2 && SubNames.size() != 3)) {
Expand Down Expand Up @@ -4352,7 +4352,7 @@ void CmdSketcherConstrainTangent::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.size() != 2 && SubNames.size() != 3){
Expand Down Expand Up @@ -4932,7 +4932,7 @@ void CmdSketcherConstrainRadius::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.empty()) {
Expand Down Expand Up @@ -5414,7 +5414,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.size() < 1 || SubNames.size() > 3) {
Expand Down Expand Up @@ -5902,7 +5902,7 @@ void CmdSketcherConstrainEqual::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

// go through the selected subelements
Expand Down Expand Up @@ -6089,7 +6089,7 @@ void CmdSketcherConstrainSymmetric::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

if (SubNames.size() != 3 && SubNames.size() != 2) {
Expand Down Expand Up @@ -6345,7 +6345,7 @@ void CmdSketcherConstrainSnellsLaw::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();

if (SubNames.size() != 3) {
strError = QObject::tr("Number of selected objects is not 3 (is %1).", dmbg).arg(SubNames.size());
Expand Down Expand Up @@ -6485,7 +6485,7 @@ void CmdSketcherConstrainInternalAlignment::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

// go through the selected subelements
Expand Down Expand Up @@ -6918,7 +6918,7 @@ void CmdSketcherToggleDrivingConstraint::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
Expand Down Expand Up @@ -6948,7 +6948,7 @@ void CmdSketcherToggleDrivingConstraint::activated(int iMsg)
else // toggle the selected constraint(s)
{
// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
if (SubNames.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select constraint(s) from the sketch."));
Expand Down
11 changes: 8 additions & 3 deletions src/Mod/Sketcher/Gui/CommandCreateGeo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6488,10 +6488,15 @@ class DrawSketchHandlerExternal: public DrawSketchHandler
virtual bool onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
App::DocumentObject* obj = sketchgui->getObject()->getDocument()->getObject(msg.pObjectName);
auto sels = Gui::Selection().getSelection(0,2,true);
if(sels.empty())
return false;
auto &sel = sels[0];
App::DocumentObject* obj = sel.pObject;
if (obj == NULL)
throw Base::Exception("Sketcher: External geometry: Invalid object in selection");
std::string subName(msg.pSubName);
const char *dot = strrchr(sel.SubName,'.');
std::string subName(dot?dot+1:sel.SubName);
if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) ||
obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId()) ||
(subName.size() > 4 && subName.substr(0,4) == "Edge") ||
Expand All @@ -6501,7 +6506,7 @@ class DrawSketchHandlerExternal: public DrawSketchHandler
Gui::Command::openCommand("Add external geometry");
FCMD_OBJ_CMD2("addExternal(\"%s\",\"%s\")",
sketchgui->getObject(),
msg.pObjectName, msg.pSubName);
sel.FeatName, Data::ComplexGeoData::newElementName(sel.SubName).c_str());
Gui::Command::commitCommand();

// adding external geometry does not require a solve() per se (the DoF is the same),
Expand Down
8 changes: 4 additions & 4 deletions src/Mod/Sketcher/Gui/CommandSketcherBSpline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ void CmdSketcherConvertToNURB::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

bool nurbsized = false;
Expand Down Expand Up @@ -446,7 +446,7 @@ void CmdSketcherIncreaseDegree::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();
Sketcher::SketchObject* Obj = static_cast<Sketcher::SketchObject*>(selection[0].getObject());

openCommand("Increase degree");
Expand Down Expand Up @@ -514,7 +514,7 @@ void CmdSketcherIncreaseKnotMultiplicity::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();

if(SubNames.size()>1) {
// Check that only one object is selected, as we need only one object to get the new GeoId after multiplicity change
Expand Down Expand Up @@ -672,7 +672,7 @@ void CmdSketcherDecreaseKnotMultiplicity::activated(int iMsg)
}

// get the needed lists and objects
const std::vector<std::string> &SubNames = checkSubNames(selection[0].getSubNames());
const std::vector<std::string> &SubNames = selection[0].getSubNames();

if(SubNames.size()>1) {
// Check that only one object is selected, as we need only one object to get the new GeoId after multiplicity change
Expand Down
Loading

0 comments on commit 5fc101b

Please sign in to comment.