Part: improve per geometry element coloring through topo naming
This commit is contained in:
@@ -66,7 +66,6 @@ enum ObjectStatus {
|
||||
NoAutoExpand = 17, // disable tree item auto expand on selection for this object
|
||||
PendingTransactionUpdate = 18, // mark that the object expects a call to onUndoRedoFinished() after transaction is finished.
|
||||
RecomputeExtension = 19, // mark the object to recompute its extensions
|
||||
TouchOnColorChange = 20, // inform view provider touch object on color change
|
||||
};
|
||||
|
||||
/** Return object for feature execution
|
||||
|
||||
@@ -194,25 +194,6 @@ public:
|
||||
}
|
||||
|
||||
void accept() {
|
||||
if(touched) {
|
||||
touched = false;
|
||||
if(ui->recompute->isChecked()) {
|
||||
auto obj = vp->getObject();
|
||||
auto objs = obj->getInListRecursive();
|
||||
objs.push_back(obj);
|
||||
for (auto o : objs)
|
||||
o->enforceRecompute();
|
||||
obj->getDocument()->recompute(objs);
|
||||
} else {
|
||||
for (auto obj : App::Document::getDependencyList(
|
||||
{vp->getObject()}, App::Document::DepSort))
|
||||
{
|
||||
auto vp = Application::Instance->getViewProvider(obj);
|
||||
if (vp)
|
||||
vp->updateColors();
|
||||
}
|
||||
}
|
||||
}
|
||||
App::GetApplication().closeActiveTransaction();
|
||||
}
|
||||
|
||||
@@ -390,7 +371,6 @@ ElementColors::ElementColors(ViewProviderDocumentObject* vp, bool noHide)
|
||||
if(noHide)
|
||||
d->ui->hideSelection->setVisible(false);
|
||||
|
||||
d->ui->recompute->setChecked(ViewParams::instance()->getColorRecompute());
|
||||
d->ui->onTop->setChecked(ViewParams::instance()->getColorOnTop());
|
||||
|
||||
Selection().addSelectionGate(d, ResolveMode::NoResolve);
|
||||
@@ -410,10 +390,6 @@ ElementColors::~ElementColors()
|
||||
Selection().rmvSelectionGate();
|
||||
}
|
||||
|
||||
void ElementColors::on_recompute_clicked(bool checked) {
|
||||
ViewParams::instance()->setColorRecompute(checked);
|
||||
}
|
||||
|
||||
void ElementColors::on_onTop_clicked(bool checked) {
|
||||
ViewParams::instance()->setColorOnTop(checked);
|
||||
d->vpParent->OnTopWhenSelected.setValue(checked?3:d->onTopMode);
|
||||
|
||||
@@ -51,7 +51,6 @@ private Q_SLOTS:
|
||||
void on_elementList_itemDoubleClicked(QListWidgetItem *item);
|
||||
void on_elementList_itemSelectionChanged();
|
||||
void on_elementList_itemEntered(QListWidgetItem *item);
|
||||
void on_recompute_clicked(bool checked);
|
||||
void on_onTop_clicked(bool checked);
|
||||
void on_hideSelection_clicked();
|
||||
void on_boxSelect_clicked();
|
||||
|
||||
@@ -72,13 +72,6 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="recompute">
|
||||
<property name="text">
|
||||
<string>Recompute after commit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="onTop">
|
||||
<property name="text">
|
||||
<string>On-top when selected</string>
|
||||
|
||||
@@ -63,7 +63,6 @@ public:
|
||||
FC_VIEW_PARAM(ShowSelectionBoundingBox,bool,Bool,false) \
|
||||
FC_VIEW_PARAM(PropertyViewTimer, unsigned long, Unsigned, 100) \
|
||||
FC_VIEW_PARAM(ColorOnTop, bool, Bool, true) \
|
||||
FC_VIEW_PARAM(ColorRecompute, bool, Bool, true) \
|
||||
|
||||
#undef FC_VIEW_PARAM
|
||||
#define FC_VIEW_PARAM(_name,_ctype,_type,_def) \
|
||||
|
||||
@@ -54,6 +54,58 @@ FC_LOG_LEVEL_INIT("Gui", true, true)
|
||||
|
||||
using namespace Gui;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static int _ColorUpdateCounter;
|
||||
static std::set<App::DocumentObjectT> _ColorChangedObjects;
|
||||
|
||||
ColorUpdater::ColorUpdater()
|
||||
{
|
||||
if (_ColorUpdateCounter >= 0)
|
||||
++_ColorUpdateCounter;
|
||||
}
|
||||
|
||||
ColorUpdater::~ColorUpdater()
|
||||
{
|
||||
if (_ColorUpdateCounter <= 0
|
||||
|| --_ColorUpdateCounter > 0
|
||||
|| _ColorChangedObjects.empty())
|
||||
return;
|
||||
// To prevent infinite recursive update
|
||||
_ColorUpdateCounter = -1;
|
||||
try {
|
||||
std::set<App::DocumentObject*> inset;
|
||||
for (const auto &objT : _ColorChangedObjects) {
|
||||
if (auto obj = objT.getObject()) {
|
||||
if (!obj->isRecomputing() && !obj->isTouched())
|
||||
obj->getInListEx(inset, true);
|
||||
}
|
||||
}
|
||||
std::vector<App::DocumentObject*> objs(inset.begin(), inset.end());
|
||||
for (auto obj : App::Document::getDependencyList(objs, App::Document::DepSort)) {
|
||||
if (obj->isRecomputing() || obj->isTouched() || !inset.count(obj))
|
||||
continue;
|
||||
if (auto vp = Base::freecad_dynamic_cast<ViewProviderDocumentObject>(
|
||||
Gui::Application::Instance->getViewProvider(obj))) {
|
||||
vp->checkColorUpdate();
|
||||
}
|
||||
}
|
||||
} catch (Base::Exception &e) {
|
||||
e.ReportException();
|
||||
} catch (...)
|
||||
{}
|
||||
_ColorChangedObjects.clear();
|
||||
_ColorUpdateCounter = 0;
|
||||
}
|
||||
|
||||
void ColorUpdater::addObject(App::DocumentObject *obj)
|
||||
{
|
||||
if (_ColorUpdateCounter && obj && !obj->isRecomputing() && !obj->isTouched())
|
||||
_ColorChangedObjects.emplace(obj);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PROPERTY_SOURCE(Gui::ViewProviderDocumentObject, Gui::ViewProvider)
|
||||
|
||||
@@ -97,16 +149,12 @@ void ViewProviderDocumentObject::getTaskViewContent(std::vector<Gui::TaskView::T
|
||||
void ViewProviderDocumentObject::startRestoring()
|
||||
{
|
||||
hide();
|
||||
auto vector = getExtensionsDerivedFromType<Gui::ViewProviderExtension>();
|
||||
for(Gui::ViewProviderExtension* ext : vector)
|
||||
ext->extensionStartRestoring();
|
||||
callExtension(&ViewProviderExtension::extensionStartRestoring);
|
||||
}
|
||||
|
||||
void ViewProviderDocumentObject::finishRestoring()
|
||||
{
|
||||
auto vector = getExtensionsDerivedFromType<Gui::ViewProviderExtension>();
|
||||
for(Gui::ViewProviderExtension* ext : vector)
|
||||
ext->extensionFinishRestoring();
|
||||
callExtension(&ViewProviderExtension::extensionFinishRestoring);
|
||||
}
|
||||
|
||||
bool ViewProviderDocumentObject::isAttachedToDocument() const
|
||||
@@ -278,6 +326,8 @@ void ViewProviderDocumentObject::addDefaultAction(QMenu* menu, const QString& te
|
||||
void ViewProviderDocumentObject::setModeSwitch() {
|
||||
if(isShowable())
|
||||
ViewProvider::setModeSwitch();
|
||||
else
|
||||
callExtension(&ViewProviderExtension::extensionModeSwitchChange);
|
||||
}
|
||||
|
||||
void ViewProviderDocumentObject::show(void)
|
||||
@@ -357,15 +407,12 @@ void ViewProviderDocumentObject::attach(App::DocumentObject *pcObj)
|
||||
}
|
||||
|
||||
//attach the extensions
|
||||
auto vector = getExtensionsDerivedFromType<Gui::ViewProviderExtension>();
|
||||
for (Gui::ViewProviderExtension* ext : vector)
|
||||
ext->extensionAttach(pcObj);
|
||||
callExtension(&ViewProviderExtension::extensionAttach,pcObj);
|
||||
}
|
||||
|
||||
void ViewProviderDocumentObject::reattach(App::DocumentObject *pcObj) {
|
||||
auto vector = getExtensionsDerivedFromType<Gui::ViewProviderExtension>();
|
||||
for (Gui::ViewProviderExtension* ext : vector)
|
||||
ext->extensionReattach(pcObj);
|
||||
setStatus(Detach, false);
|
||||
callExtension(&ViewProviderExtension::extensionReattach,pcObj);
|
||||
}
|
||||
|
||||
void ViewProviderDocumentObject::update(const App::Property* prop)
|
||||
@@ -505,11 +552,8 @@ PyObject* ViewProviderDocumentObject::getPyObject()
|
||||
bool ViewProviderDocumentObject::canDropObjectEx(App::DocumentObject* obj, App::DocumentObject *owner,
|
||||
const char *subname, const std::vector<std::string> &elements) const
|
||||
{
|
||||
auto vector = getExtensionsDerivedFromType<Gui::ViewProviderExtension>();
|
||||
for(Gui::ViewProviderExtension* ext : vector){
|
||||
if(ext->extensionCanDropObjectEx(obj,owner,subname,elements))
|
||||
return true;
|
||||
}
|
||||
if(queryExtension(&ViewProviderExtension::extensionCanDropObjectEx,obj,owner,subname,elements))
|
||||
return true;
|
||||
if(obj && obj->getDocument()!=getObject()->getDocument())
|
||||
return false;
|
||||
return canDropObject(obj);
|
||||
@@ -583,10 +627,8 @@ bool ViewProviderDocumentObject::getElementPicked(const SoPickedPoint *pp, std::
|
||||
{
|
||||
if(!isSelectable())
|
||||
return false;
|
||||
auto vector = getExtensionsDerivedFromType<Gui::ViewProviderExtension>();
|
||||
for(Gui::ViewProviderExtension* ext : vector)
|
||||
if(ext->extensionGetElementPicked(pp,subname))
|
||||
return true;
|
||||
if(queryExtension(&ViewProviderExtension::extensionGetElementPicked,pp,subname))
|
||||
return true;
|
||||
|
||||
auto childRoot = getChildRoot();
|
||||
int idx;
|
||||
|
||||
@@ -227,6 +227,20 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/** Convenient class to auto update colors for all affect objects
|
||||
*/
|
||||
class GuiExport ColorUpdater
|
||||
{
|
||||
public:
|
||||
ColorUpdater();
|
||||
~ColorUpdater();
|
||||
static void addObject(App::DocumentObject *obj);
|
||||
private:
|
||||
/// Private new operator to prevent heap allocation
|
||||
void* operator new(size_t size);
|
||||
};
|
||||
|
||||
|
||||
} // namespace Gui
|
||||
|
||||
#endif // GUI_VIEWPROVIDER_DOCUMENTOBJECT_H
|
||||
|
||||
@@ -872,17 +872,30 @@ private:
|
||||
{
|
||||
PyObject *pcObj = nullptr;
|
||||
char *name = "Shape";
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O!|s", &(TopoShapePy::Type), &pcObj, &name))
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O|s", &pcObj, &name))
|
||||
throw Py::Exception();
|
||||
|
||||
App::Document *pcDoc = App::GetApplication().getActiveDocument();
|
||||
if (!pcDoc)
|
||||
pcDoc = App::GetApplication().newDocument();
|
||||
TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObj);
|
||||
App::Document *pcSrcDoc = nullptr;
|
||||
TopoShape shape;
|
||||
if (PyObject_TypeCheck(pcObj, &TopoShapePy::Type))
|
||||
shape = *static_cast<TopoShapePy*>(pcObj)->getTopoShapePtr();
|
||||
else if (PyObject_TypeCheck(pcObj, &GeometryPy::Type))
|
||||
shape = static_cast<GeometryPy*>(pcObj)->getGeometryPtr()->toShape();
|
||||
else if (PyObject_TypeCheck(pcObj, &App::DocumentObjectPy::Type)) {
|
||||
auto obj = static_cast<App::DocumentObjectPy*>(pcObj)->getDocumentObjectPtr();
|
||||
pcSrcDoc = obj->getDocument();
|
||||
shape = Feature::getTopoShape(obj);
|
||||
}
|
||||
else
|
||||
throw Py::TypeError("Expects argument of type DocumentObject, Shape, or Geometry");
|
||||
Part::Feature *pcFeature = static_cast<Part::Feature*>(pcDoc->addObject("Part::Feature", name));
|
||||
// copy the data
|
||||
pcFeature->Shape.setValue(*pShape->getTopoShapePtr());
|
||||
pcDoc->recompute();
|
||||
pcFeature->Shape.setValue(shape);
|
||||
pcFeature->signalMapShapeColors(pcSrcDoc);
|
||||
pcFeature->purgeTouched();
|
||||
return Py::asObject(pcFeature->getPyObject());
|
||||
}
|
||||
Py::Object getFacets(const Py::Tuple& args)
|
||||
|
||||
@@ -95,6 +95,8 @@ PROPERTY_SOURCE(Part::Feature, App::GeoFeature)
|
||||
Feature::Feature(void)
|
||||
{
|
||||
ADD_PROPERTY(Shape, (TopoDS_Shape()));
|
||||
ADD_PROPERTY_TYPE(ColoredElements, (0), "",
|
||||
(App::PropertyType)(App::Prop_Hidden|App::Prop_ReadOnly|App::Prop_Output),"");
|
||||
}
|
||||
|
||||
Feature::~Feature()
|
||||
@@ -1304,6 +1306,21 @@ const std::vector<const char *>& Feature::getElementTypes(bool all) const
|
||||
return res;
|
||||
}
|
||||
|
||||
Feature *Feature::create(const TopoShape &s, const char *name, App::Document *doc)
|
||||
{
|
||||
if (!name || !name[0])
|
||||
name = "Shape";
|
||||
if (!doc) {
|
||||
doc = App::GetApplication().getActiveDocument();
|
||||
if (!doc)
|
||||
doc = App::GetApplication().newDocument();
|
||||
}
|
||||
auto res = static_cast<Part::Feature*>(doc->addObject("Part::Feature", name));
|
||||
res->Shape.setValue(s);
|
||||
res->purgeTouched();
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline App::PropertyBool *propDisableMapping(App::PropertyContainer *container, bool forced)
|
||||
{
|
||||
const char *name = "Part_NoElementMap";
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
virtual ~Feature();
|
||||
|
||||
PropertyPartShape Shape;
|
||||
App::PropertyLinkSubHidden ColoredElements;
|
||||
|
||||
/** @name methods override feature */
|
||||
//@{
|
||||
@@ -154,6 +155,12 @@ public:
|
||||
|
||||
virtual const std::vector<const char*>& getElementTypes(bool all=false) const override;
|
||||
|
||||
boost::signals2::signal<void (App::Document *)> signalMapShapeColors;
|
||||
|
||||
static Feature *create(const TopoShape &s,
|
||||
const char *name = nullptr,
|
||||
App::Document *doc = nullptr);
|
||||
|
||||
protected:
|
||||
/// recompute only this object
|
||||
virtual App::DocumentObjectExecReturn *recompute() override;
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/CommandT.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/SelectionObject.h>
|
||||
@@ -215,18 +216,30 @@ static void _copyShape(const char *cmdName, bool resolve,bool needElement=false,
|
||||
for(auto &v : subMap) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"__shape = Part.getShape(%s,'%s',needSubElement=%s,refine=%s)%s\n"
|
||||
"App.ActiveDocument.addObject('Part::Feature','%s').Shape=__shape\n"
|
||||
"App.ActiveDocument.addObject('Part::Feature','ShapeCopy').Shape=__shape\n"
|
||||
"App.ActiveDocument.ActiveObject.Label=%s.Label\n",
|
||||
parentName.c_str(), v.first.c_str(),
|
||||
parentName.c_str(),
|
||||
v.first.c_str(),
|
||||
needElement ? "True" : "False",
|
||||
refine ? "True" : "False",
|
||||
needElement ? ".copy()" : "",
|
||||
v.second->getNameInDocument(),
|
||||
Gui::Command::getObjectCmd(v.second).c_str());
|
||||
auto newObj = App::GetApplication().getActiveDocument()->getActiveObject();
|
||||
Gui::Command::copyVisual(newObj, "ShapeColor", v.second);
|
||||
Gui::Command::copyVisual(newObj, "LineColor", v.second);
|
||||
Gui::Command::copyVisual(newObj, "PointColor", v.second);
|
||||
Gui::cmdGuiObject(newObj,std::ostringstream()
|
||||
<< "mapShapeColors(App.getDocument('" << obj->getDocument()->getName() << "'))");
|
||||
if(obj->getDocument() != App::GetApplication().getActiveDocument()) {
|
||||
// clear element map if copied from external object, or else
|
||||
// weird stuff will happen
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"__shape.ElementMap = {}\n"
|
||||
"__shape.Tag = 0\n"
|
||||
"%s.Shape = __shape\n",
|
||||
Gui::Command::getObjectCmd(newObj).c_str());
|
||||
}
|
||||
Gui::Command::doCommand(Gui::Command::Doc,"del(__shape)");
|
||||
}
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
@@ -329,14 +342,13 @@ void CmdPartRefineShape::activated(int iMsg)
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Refine shape"));
|
||||
std::for_each(objs.begin(), objs.end(), [](App::DocumentObject* obj) {
|
||||
try {
|
||||
doCommand(Doc,"App.ActiveDocument.addObject('Part::Refine','%s').Source="
|
||||
doCommand(Doc,"App.ActiveDocument.addObject('Part::Refine','Refined').Source="
|
||||
"App.ActiveDocument.%s\n"
|
||||
"App.ActiveDocument.ActiveObject.Label="
|
||||
"App.ActiveDocument.%s.Label\n"
|
||||
"Gui.ActiveDocument.%s.hide()\n",
|
||||
obj->getNameInDocument(),
|
||||
obj->getNameInDocument(),
|
||||
obj->getNameInDocument(),
|
||||
obj->getNameInDocument());
|
||||
|
||||
copyVisual("ActiveObject", "ShapeColor", obj->getNameInDocument());
|
||||
|
||||
+1005
-196
File diff suppressed because it is too large
Load Diff
@@ -62,10 +62,12 @@ namespace PartGui {
|
||||
class SoBrepFaceSet;
|
||||
class SoBrepEdgeSet;
|
||||
class SoBrepPointSet;
|
||||
class SoFCCoordinate3;
|
||||
|
||||
class PartGuiExport ViewProviderPartExt : public Gui::ViewProviderGeometryObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(PartGui::ViewProviderPartExt);
|
||||
typedef Gui::ViewProviderGeometryObject inherited;
|
||||
|
||||
public:
|
||||
/// constructor
|
||||
@@ -92,6 +94,13 @@ public:
|
||||
// Faces (Gui::ViewProviderGeometryObject::ShapeColor and Gui::ViewProviderGeometryObject::ShapeMaterial apply)
|
||||
App::PropertyColorList DiffuseColor;
|
||||
|
||||
App::PropertyColorList MappedColors;
|
||||
App::PropertyBool MapFaceColor;
|
||||
App::PropertyBool MapLineColor;
|
||||
App::PropertyBool MapPointColor;
|
||||
App::PropertyBool MapTransparency;
|
||||
App::PropertyBool ForceMapColors;
|
||||
|
||||
virtual void attach(App::DocumentObject *) override;
|
||||
virtual void setDisplayMode(const char* ModeName) override;
|
||||
/// returns a list of all possible modes
|
||||
@@ -103,6 +112,8 @@ public:
|
||||
|
||||
virtual void updateData(const App::Property*) override;
|
||||
|
||||
virtual PyObject *getPyObject() override;
|
||||
|
||||
/** @name Selection handling
|
||||
* This group of methods do the selection handling.
|
||||
* Here you can define how the selection for your ViewProfider
|
||||
@@ -111,9 +122,13 @@ public:
|
||||
//@{
|
||||
/// indicates if the ViewProvider use the new Selection model
|
||||
virtual bool useNewSelectionModel(void) const override {return true;}
|
||||
/// return a hit element to the selection path or 0
|
||||
virtual std::string getElement(const SoDetail*) const override;
|
||||
virtual bool getElementPicked(const SoPickedPoint *, std::string &subname) const override;
|
||||
virtual std::string getElement(const SoDetail *detail) const override;
|
||||
virtual SoDetail* getDetail(const char*) const override;
|
||||
virtual bool getDetailPath(const char *subname,
|
||||
SoFullPath *pPath,
|
||||
bool append,
|
||||
SoDetail *&det) const override;
|
||||
virtual std::vector<Base::Vector3d> getModelPoints(const SoPickedPoint *) const override;
|
||||
/// return the highlight lines for a given element or the whole shape
|
||||
virtual std::vector<Base::Vector3d> getSelectionShape(const char* Element) const override;
|
||||
@@ -130,11 +145,13 @@ public:
|
||||
void unsetHighlightedEdges();
|
||||
void setHighlightedPoints(const std::vector<App::Color>& colors);
|
||||
void unsetHighlightedPoints();
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Color management methods
|
||||
*/
|
||||
//@{
|
||||
virtual void setElementColors(const std::map<std::string,App::Color> &colors) override;
|
||||
virtual std::map<std::string,App::Color> getElementColors(const char *element=nullptr) const override;
|
||||
//@}
|
||||
|
||||
@@ -145,9 +162,27 @@ public:
|
||||
|
||||
virtual bool allowOverride(const App::DocumentObject &) const override;
|
||||
|
||||
virtual void updateColors(App::Document *sourceDoc=0, bool forceColorMap=false) override;
|
||||
|
||||
virtual void checkColorUpdate() override;
|
||||
|
||||
static std::vector<App::Color> getShapeColors(const Part::TopoShape &shape, App::Color &defColor,
|
||||
App::Document *sourceDoc=0, bool linkOnly=false);
|
||||
|
||||
/** @name Edit methods */
|
||||
//@{
|
||||
void setupContextMenu(QMenu*, QObject*, const char*) override;
|
||||
virtual void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override;
|
||||
|
||||
virtual void setShapePropertyName(const char *propName);
|
||||
const char *getShapePropertyName() const;
|
||||
|
||||
Part::TopoShape getShape() const;
|
||||
virtual void updateVisual();
|
||||
|
||||
virtual void reattach(App::DocumentObject *) override;
|
||||
virtual void beforeDelete() override;
|
||||
virtual void finishRestoring() override;
|
||||
|
||||
protected:
|
||||
bool setEdit(int ModNum) override;
|
||||
@@ -157,8 +192,8 @@ protected:
|
||||
protected:
|
||||
/// get called by the container whenever a property has been changed
|
||||
virtual void onChanged(const App::Property* prop) override;
|
||||
bool loadParameter();
|
||||
void updateVisual();
|
||||
|
||||
virtual bool hasBaseFeature() const;
|
||||
|
||||
// nodes for the data representation
|
||||
SoMaterialBinding * pcFaceBind;
|
||||
@@ -171,6 +206,7 @@ protected:
|
||||
SoShapeHints * pShapeHints;
|
||||
|
||||
SoCoordinate3 * coords;
|
||||
SoCoordinate3 * pcoords;
|
||||
SoBrepFaceSet * faceset;
|
||||
SoNormal * norm;
|
||||
SoNormalBinding * normb;
|
||||
@@ -179,6 +215,11 @@ protected:
|
||||
|
||||
bool VisualTouched;
|
||||
bool NormalsFromUV;
|
||||
bool UpdatingColor;
|
||||
|
||||
std::string shapePropName;
|
||||
|
||||
friend class SoFCCoordinate3;
|
||||
|
||||
private:
|
||||
// settings stuff
|
||||
@@ -188,6 +229,9 @@ private:
|
||||
static App::PropertyQuantityConstraint::Constraints angDeflectionRange;
|
||||
static const char* LightingEnums[];
|
||||
static const char* DrawStyleEnums[];
|
||||
|
||||
Part::TopoShape cachedShape;
|
||||
boost::signals2::scoped_connection conn;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -678,6 +678,11 @@ PROPERTY_SOURCE(PartGui::ViewProviderRefine, PartGui::ViewProviderPart)
|
||||
ViewProviderRefine::ViewProviderRefine()
|
||||
{
|
||||
sPixmap = "Part_Refine_Shape";
|
||||
ForceMapColors.setValue(true);
|
||||
MapFaceColor.setValue(true);
|
||||
MapLineColor.setValue(true);
|
||||
MapPointColor.setValue(true);
|
||||
MapTransparency.setValue(true);
|
||||
}
|
||||
|
||||
ViewProviderRefine::~ViewProviderRefine()
|
||||
@@ -692,6 +697,12 @@ ViewProviderReverse::ViewProviderReverse()
|
||||
{
|
||||
//TODO: Need a specific icon here!
|
||||
//sPixmap = "Part_Reverse_Shape";
|
||||
|
||||
ForceMapColors.setValue(true);
|
||||
MapFaceColor.setValue(true);
|
||||
MapLineColor.setValue(true);
|
||||
MapPointColor.setValue(true);
|
||||
MapTransparency.setValue(true);
|
||||
}
|
||||
|
||||
ViewProviderReverse::~ViewProviderReverse()
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="ViewProviderDocumentObjectPy"
|
||||
Name="ViewProviderPartExtPy"
|
||||
Twin="ViewProviderPartExt"
|
||||
TwinPointer="ViewProviderPartExt"
|
||||
Include="Mod/Part/Gui/ViewProviderExt.h"
|
||||
Namespace="PartGui"
|
||||
FatherInclude="Gui/ViewProviderDocumentObjectPy.h"
|
||||
FatherNamespace="Gui">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Zheng, Lei" EMail="[email protected]" />
|
||||
<UserDocu>This is the father of all Part ViewProvider classes</UserDocu>
|
||||
</Documentation>
|
||||
<Methode Name="mapShapeColors">
|
||||
<Documentation>
|
||||
<UserDocu>
|
||||
mapShapeColors(sourceDoc=None): Update shape colors based on the element map inside the shape
|
||||
|
||||
sourceDoc: the document of the source object in case the shape comes from another document.
|
||||
If None, then use the owner document
|
||||
</UserDocu>
|
||||
</Documentation>
|
||||
</Methode>
|
||||
<Attribute Name="ShapePropertyName">
|
||||
<Documentation>
|
||||
<UserDocu>Set/get shape property name</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="ShapePropertyName" Type="String" />
|
||||
</Attribute>
|
||||
<Attribute Name="ElementColors">
|
||||
<Documentation>
|
||||
<UserDocu>Set/get element colors as a dict(name:color)</UserDocu>
|
||||
</Documentation>
|
||||
<Parameter Name="ElementColors" Type="Dict" />
|
||||
</Attribute>
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2018 Zheng Lei (realthunder) <[email protected]> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <App/DocumentPy.h>
|
||||
#include "ViewProviderExt.h"
|
||||
|
||||
// inclusion of the generated files (generated out of ViewProviderPartExtPy.xml)
|
||||
#include "ViewProviderPartExtPy.h"
|
||||
#include "ViewProviderPartExtPy.cpp"
|
||||
|
||||
using namespace PartGui;
|
||||
|
||||
// returns a string which represent the object e.g. when printed in python
|
||||
std::string ViewProviderPartExtPy::representation(void) const
|
||||
{
|
||||
return std::string("<Part::ViewProvider>");
|
||||
}
|
||||
|
||||
PyObject *ViewProviderPartExtPy::getCustomAttributes(const char* ) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ViewProviderPartExtPy::setCustomAttributes(const char* , PyObject *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject *ViewProviderPartExtPy::mapShapeColors(PyObject *args) {
|
||||
PyObject *pyDoc = Py_None;
|
||||
if(!PyArg_ParseTuple(args, "|O!", &App::DocumentPy::Type,&pyDoc))
|
||||
return 0;
|
||||
auto vp = getViewProviderPartExtPtr();
|
||||
App::Document *doc = 0;
|
||||
if(pyDoc!=Py_None)
|
||||
doc = static_cast<App::DocumentPy*>(pyDoc)->getDocumentPtr();
|
||||
vp->updateColors(doc,true);
|
||||
Py_Return;
|
||||
}
|
||||
|
||||
Py::Dict ViewProviderPartExtPy::getElementColors() const {
|
||||
auto *vp = getViewProviderPartExtPtr();
|
||||
Py::Dict dict;
|
||||
for(auto &v : vp->getElementColors()) {
|
||||
Py::TupleN color(Py::Float(v.second.r),Py::Float(v.second.g),
|
||||
Py::Float(v.second.b),Py::Float(v.second.a));
|
||||
dict[Py::String(v.first)] = color;
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
void ViewProviderPartExtPy::setElementColors(Py::Dict dict) {
|
||||
auto *vp = getViewProviderPartExtPtr();
|
||||
std::map<std::string,App::Color> info;
|
||||
for(auto it=dict.begin();it!=dict.end();++it) {
|
||||
const auto &value = *it;
|
||||
if(!value.first.isString())
|
||||
throw Py::TypeError("expect the key to be string");
|
||||
App::PropertyColor prop;
|
||||
try {
|
||||
prop.setPyObject(value.second.ptr());
|
||||
}catch(Base::Exception &e) {
|
||||
e.setPyException();
|
||||
return;
|
||||
}
|
||||
info.emplace(Py::String(value.first).as_string(),prop.getValue());
|
||||
}
|
||||
vp->setElementColors(info);
|
||||
}
|
||||
|
||||
Py::String ViewProviderPartExtPy::getShapePropertyName() const {
|
||||
return Py::String(getViewProviderPartExtPtr()->getShapePropertyName());
|
||||
}
|
||||
|
||||
void ViewProviderPartExtPy::setShapePropertyName(Py::String name) {
|
||||
getViewProviderPartExtPtr()->setShapePropertyName(name.as_string().c_str());
|
||||
}
|
||||
Reference in New Issue
Block a user