PartDesign: body is responsible for visuals

-Hide all visual properties of features when they are part of a body
-Propagate all body visual changes to features
-Separate display mode from body mode to enable setting display mode for both "tip" and "through" modes
-Use default visuals for body shape and only make "through" a new display mask mode for the children
This commit is contained in:
Stefan Tröger 2016-03-14 21:56:14 +01:00
parent 03b08a311c
commit 048c374080
4 changed files with 103 additions and 55 deletions

View File

@ -222,3 +222,18 @@ bool ViewProvider::onDelete(const std::vector<std::string> &)
}
return true;
}
void ViewProvider::setBodyMode(bool bodymode) {
std::vector<App::Property*> props;
getPropertyList(props);
for(App::Property* prop : props) {
if(prop == &Visibility ||
prop == &Selectable)
continue;
prop->setStatus(App::Property::Hidden, bodymode);
}
}

View File

@ -48,6 +48,11 @@ public:
void updateData(const App::Property*);
void onChanged(const App::Property* prop);
//body mode means that the object is part of a body and that the body is used to set the
//visual properties, not the features. Hence setting body mode to true will hide most
//viewprovider properties.
void setBodyMode(bool bodymode);
protected:
virtual bool setEdit(int ModNum);
virtual void unsetEdit(int ModNum);

View File

@ -52,17 +52,21 @@
#include "Utils.h"
#include "ViewProviderBody.h"
#include "ViewProvider.h"
using namespace PartDesignGui;
const char* PartDesignGui::ViewProviderBody::BodyModeEnum[] = {"Through","Tip",NULL};
PROPERTY_SOURCE(PartDesignGui::ViewProviderBody,PartGui::ViewProviderPart)
ViewProviderBody::ViewProviderBody()
{
ADD_PROPERTY(DisplayModeBody,((long)0));
DisplayModeBody.setEnums(BodyModeEnum);
pcBodyChildren = new SoSeparator();
pcBodyChildren->ref();
pcBodyTip = new SoSeparator();
pcBodyTip->ref();
sPixmap = "PartDesign_Body_Tree.svg";
}
@ -70,26 +74,15 @@ ViewProviderBody::ViewProviderBody()
ViewProviderBody::~ViewProviderBody()
{
pcBodyChildren->unref ();
pcBodyTip->unref ();
}
void ViewProviderBody::attach(App::DocumentObject *pcFeat)
{
// call parent attach method
ViewProviderPart::attach(pcFeat);
PartDesign::Body *body = static_cast <PartDesign::Body *> (pcFeat);
App::DocumentObject *tip = body->Tip.getValue ();
if (tip) {
Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider (tip);
if (vp) {
pcBodyTip->addChild ( vp->getRoot () );
}
}
addDisplayMaskMode(pcBodyChildren, "Through");
addDisplayMaskMode(pcBodyTip, "Tip");
setDisplayMaskMode("Through");
App::Document *adoc = pcObject->getDocument ();
Gui::Document *gdoc = Gui::Application::Instance->getDocument ( adoc ) ;
@ -109,19 +102,14 @@ void ViewProviderBody::attach(App::DocumentObject *pcFeat)
// TODO drag&drop (2015-09-05, Fat-Zer)
// TODO Add activate () call (2015-09-08, Fat-Zer)
void ViewProviderBody::setDisplayMode(const char* ModeName)
{
if ( strcmp("Through",ModeName)==0 )
setDisplayMaskMode("Through");
// TODO Use other Part::features display modes instead of the "Tip" (2015-09-08, Fat-Zer)
if ( strcmp("Tip",ModeName)==0 )
setDisplayMaskMode("Tip");
// TODO When switching into Tip mode switch it's visability to true (2015-09-05, Fat-Zer)
ViewProviderGeometryObject::setDisplayMode( ModeName );
}
void ViewProviderBody::setDisplayMode(const char* ModeName) {
std::vector<std::string> ViewProviderBody::getDisplayModes(void) const {
return {"Through" , "Tip"};
//if we show "Through" we must avoid to set the display mask modes, as this would result
//in going into tip mode. When through is chosen the child features are displayed, and all
//we need to ensure is that the display mode change is propagated to them fro within the
//onChanged() method.
if(DisplayModeBody.getValue() == 1)
PartGui::ViewProviderPartExt::setDisplayMode(ModeName);
}
@ -241,25 +229,8 @@ void ViewProviderBody::updateData(const App::Property* prop)
if (prop == &body->Model || prop == &body->BaseFeature) {
// update sizes of origins and datums
updateOriginDatumSize ();
} else if (prop == &body->Tip) {
// Adjust the internals to display
App::DocumentObject *tip = body->Tip.getValue ();
if (tip) {
Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider (tip);
if (vp) {
SoNode *tipRoot = vp->getRoot ();
if ( pcBodyTip->findChild ( tipRoot ) == -1 ) {
pcBodyTip->removeAllChildren ();
pcBodyTip->addChild ( tipRoot );
}
// Else our tip is already shown
} else {
pcBodyTip->removeAllChildren ();
}
} else {
pcBodyTip->removeAllChildren ();
}
//ensure all model features are in visual body mode
setVisualBodyMode(true);
}
PartGui::ViewProviderPart::updateData(prop);
@ -377,3 +348,57 @@ void ViewProviderBody::updateOriginDatumSize () {
vpOrigin->Size.setValue ( size*1.2 );
}
void ViewProviderBody::onChanged(const App::Property* prop) {
if(prop == &DisplayModeBody) {
if ( DisplayModeBody.getValue() == 0 )
setDisplayMaskMode("Through");
else
setDisplayMaskMode(DisplayMode.getValueAsString());
}
else
unifyVisualProperty(prop);
PartGui::ViewProviderPartExt::onChanged(prop);
}
void ViewProviderBody::unifyVisualProperty(const App::Property* prop) {
if(prop == &Visibility ||
prop == &Selectable ||
prop == &DisplayModeBody)
return;
Gui::Document *gdoc = Gui::Application::Instance->getDocument ( pcObject->getDocument() ) ;
PartDesign::Body *body = static_cast<PartDesign::Body *> ( getObject() );
auto features = body->Model.getValues();
for(auto feature : features) {
if(!feature->isDerivedFrom(PartDesign::Feature::getClassTypeId()))
continue;
//copy over the properties data
auto p = gdoc->getViewProvider(feature)->getPropertyByName(prop->getName());
p->Paste(*prop);
}
}
void ViewProviderBody::setVisualBodyMode(bool bodymode) {
Gui::Document *gdoc = Gui::Application::Instance->getDocument ( pcObject->getDocument() ) ;
PartDesign::Body *body = static_cast<PartDesign::Body *> ( getObject() );
auto features = body->Model.getValues();
for(auto feature : features) {
if(!feature->isDerivedFrom(PartDesign::Feature::getClassTypeId()))
continue;
static_cast<PartDesignGui::ViewProvider*>(gdoc->getViewProvider(feature))->setBodyMode(bodymode);
}
}

View File

@ -48,10 +48,9 @@ public:
/// destructor
virtual ~ViewProviderBody();
App::PropertyEnumeration DisplayModeBody;
virtual void attach(App::DocumentObject *);
virtual void setDisplayMode(const char* ModeName);
/// returns a list of all possible modes
virtual std::vector<std::string> getDisplayModes(void) const;
virtual bool doubleClicked(void);
virtual std::vector<App::DocumentObject*> claimChildren(void)const;
@ -59,11 +58,14 @@ public:
// returns the root node where the children gets collected(3D)
virtual SoGroup* getChildRoot(void) const {return pcBodyChildren;}
virtual std::vector<App::DocumentObject*> claimChildren3D(void)const;
virtual void setDisplayMode(const char* ModeName);
virtual bool onDelete(const std::vector<std::string> &);
/// Update the children's highlighting when triggered
virtual void updateData(const App::Property* prop);
///unify children visuals
virtual void onChanged(const App::Property* prop);
/// Update the sizes of origin and datums
void updateOriginDatumSize ();
@ -78,14 +80,15 @@ protected:
void slotChangedObjectApp ( const App::DocumentObject& obj, const App::Property& prop );
void slotChangedObjectGui ( const Gui::ViewProviderDocumentObject& obj, const App::Property& prop );
/// Copy over all visual properties to the child features
void unifyVisualProperty(const App::Property* prop);
/// Set Feature viewprovider into visual body mode
void setVisualBodyMode(bool bodymode);
private:
/// group used to store children collected by claimChildren3D() in the through (edit) mode.
SoGroup *pcBodyChildren;
/// The tip node used to display the Body when it doesn't edited.
SoGroup *pcBodyTip;
/// Update the children's highlighting
//void updateTree();
static const char* BodyModeEnum[];
boost::signals::connection connectChangedObjectApp;
boost::signals::connection connectChangedObjectGui;