Keep faces colors on boolean operations
This commit is contained in:
parent
8c3f97c98e
commit
9e872e4987
|
@ -134,6 +134,7 @@ void PartExport initPart()
|
|||
Part::TopoShape ::init();
|
||||
Part::PropertyPartShape ::init();
|
||||
Part::PropertyGeometryList ::init();
|
||||
Part::PropertyShapeHistory ::init();
|
||||
Part::PropertyFilletEdges ::init();
|
||||
|
||||
Part::Feature ::init();
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <BRepAlgoAPI_BooleanOperation.hxx>
|
||||
#include <memory>
|
||||
# include <memory>
|
||||
#endif
|
||||
|
||||
#include "FeaturePartBoolean.h"
|
||||
|
@ -35,10 +35,13 @@ using namespace Part;
|
|||
PROPERTY_SOURCE_ABSTRACT(Part::Boolean, Part::Feature)
|
||||
|
||||
|
||||
Boolean::Boolean(void) : myBoolOp(0)
|
||||
Boolean::Boolean(void)
|
||||
{
|
||||
ADD_PROPERTY(Base,(0));
|
||||
ADD_PROPERTY(Tool,(0));
|
||||
ADD_PROPERTY_TYPE(History,(ShapeHistory()), "Boolean", (App::PropertyType)
|
||||
(App::Prop_Output|App::Prop_Transient|App::Prop_Hidden), "Shape history");
|
||||
History.setSize(0);
|
||||
}
|
||||
|
||||
short Boolean::mustExecute() const
|
||||
|
@ -77,14 +80,15 @@ App::DocumentObjectExecReturn *Boolean::execute(void)
|
|||
return new App::DocumentObjectExecReturn("Resulting shape is invalid");
|
||||
}
|
||||
|
||||
// tmp. set boolean operation pointer
|
||||
this->myBoolOp = mkBool.get();
|
||||
std::vector<ShapeHistory> history;
|
||||
history.push_back(buildHistory(*mkBool.get(), TopAbs_FACE, resShape, BaseShape));
|
||||
history.push_back(buildHistory(*mkBool.get(), TopAbs_FACE, resShape, ToolShape));
|
||||
|
||||
this->Shape.setValue(resShape);
|
||||
this->myBoolOp = 0;
|
||||
this->History.setValues(history);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
catch (...) {
|
||||
this->myBoolOp = 0;
|
||||
return new App::DocumentObjectExecReturn("A fatal error occurred when running boolean operation");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
|
||||
App::PropertyLink Base;
|
||||
App::PropertyLink Tool;
|
||||
PropertyShapeHistory History;
|
||||
|
||||
/** @name methods overide Feature */
|
||||
//@{
|
||||
|
@ -53,13 +54,9 @@ public:
|
|||
const char* getViewProviderName(void) const {
|
||||
return "PartGui::ViewProviderBoolean";
|
||||
}
|
||||
BRepAlgoAPI_BooleanOperation* getBooleanOperation() const { return myBoolOp; }
|
||||
|
||||
protected:
|
||||
virtual BRepAlgoAPI_BooleanOperation* makeOperation(const TopoDS_Shape&, const TopoDS_Shape&) const = 0;
|
||||
|
||||
private:
|
||||
BRepAlgoAPI_BooleanOperation* myBoolOp;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,9 @@ MultiCommon::MultiCommon(void)
|
|||
{
|
||||
ADD_PROPERTY(Shapes,(0));
|
||||
Shapes.setSize(0);
|
||||
ADD_PROPERTY_TYPE(History,(ShapeHistory()), "Boolean", (App::PropertyType)
|
||||
(App::Prop_Output|App::Prop_Transient|App::Prop_Hidden), "Shape history");
|
||||
History.setSize(0);
|
||||
}
|
||||
|
||||
short MultiCommon::mustExecute() const
|
||||
|
@ -78,6 +81,7 @@ App::DocumentObjectExecReturn *MultiCommon::execute(void)
|
|||
}
|
||||
|
||||
if (s.size() >= 2) {
|
||||
std::vector<ShapeHistory> history;
|
||||
TopoDS_Shape res = s.front();
|
||||
for (std::vector<TopoDS_Shape>::iterator it = s.begin()+1; it != s.end(); ++it) {
|
||||
// Let's call algorithm computing a fuse operation:
|
||||
|
@ -86,10 +90,13 @@ App::DocumentObjectExecReturn *MultiCommon::execute(void)
|
|||
if (!mkCommon.IsDone())
|
||||
throw Base::Exception("Intersection failed");
|
||||
res = mkCommon.Shape();
|
||||
history.push_back(buildHistory(mkCommon, TopAbs_FACE, res, mkCommon.Shape1()));
|
||||
history.push_back(buildHistory(mkCommon, TopAbs_FACE, res, mkCommon.Shape2()));
|
||||
}
|
||||
if (res.IsNull())
|
||||
throw Base::Exception("Resulting shape is invalid");
|
||||
this->Shape.setValue(res);
|
||||
this->History.setValues(history);
|
||||
}
|
||||
else {
|
||||
throw Base::Exception("Not enough shape objects linked");
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
MultiCommon();
|
||||
|
||||
App::PropertyLinkList Shapes;
|
||||
PropertyShapeHistory History;
|
||||
|
||||
/** @name methods override feature */
|
||||
//@{
|
||||
|
|
|
@ -56,6 +56,9 @@ MultiFuse::MultiFuse(void)
|
|||
{
|
||||
ADD_PROPERTY(Shapes,(0));
|
||||
Shapes.setSize(0);
|
||||
ADD_PROPERTY_TYPE(History,(ShapeHistory()), "Boolean", (App::PropertyType)
|
||||
(App::Prop_Output|App::Prop_Transient|App::Prop_Hidden), "Shape history");
|
||||
History.setSize(0);
|
||||
}
|
||||
|
||||
short MultiFuse::mustExecute() const
|
||||
|
@ -79,6 +82,7 @@ App::DocumentObjectExecReturn *MultiFuse::execute(void)
|
|||
|
||||
if (s.size() >= 2) {
|
||||
try {
|
||||
std::vector<ShapeHistory> history;
|
||||
TopoDS_Shape res = s.front();
|
||||
for (std::vector<TopoDS_Shape>::iterator it = s.begin()+1; it != s.end(); ++it) {
|
||||
// Let's call algorithm computing a fuse operation:
|
||||
|
@ -87,10 +91,13 @@ App::DocumentObjectExecReturn *MultiFuse::execute(void)
|
|||
if (!mkFuse.IsDone())
|
||||
throw Base::Exception("Fusion failed");
|
||||
res = mkFuse.Shape();
|
||||
history.push_back(buildHistory(mkFuse, TopAbs_FACE, res, mkFuse.Shape1()));
|
||||
history.push_back(buildHistory(mkFuse, TopAbs_FACE, res, mkFuse.Shape2()));
|
||||
}
|
||||
if (res.IsNull())
|
||||
throw Base::Exception("Resulting shape is invalid");
|
||||
this->Shape.setValue(res);
|
||||
this->History.setValues(history);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
MultiFuse();
|
||||
|
||||
App::PropertyLinkList Shapes;
|
||||
PropertyShapeHistory History;
|
||||
|
||||
/** @name methods override feature */
|
||||
//@{
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#ifndef _PreComp_
|
||||
# include <gp_Trsf.hxx>
|
||||
# include <gp_Ax1.hxx>
|
||||
# include <BRepBuilderAPI_MakeShape.hxx>
|
||||
# include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
# include <TopExp.hxx>
|
||||
# include <TopTools_IndexedMapOfShape.hxx>
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -128,6 +132,57 @@ TopLoc_Location Feature::getLocation() const
|
|||
return TopLoc_Location(trf);
|
||||
}
|
||||
|
||||
ShapeHistory Feature::buildHistory(BRepBuilderAPI_MakeShape& mkShape, TopAbs_ShapeEnum type,
|
||||
const TopoDS_Shape& newS, const TopoDS_Shape& oldS)
|
||||
{
|
||||
ShapeHistory history;
|
||||
history.type = type;
|
||||
|
||||
TopTools_IndexedMapOfShape newM, oldM;
|
||||
TopExp::MapShapes(newS, type, newM);
|
||||
TopExp::MapShapes(oldS, type, oldM);
|
||||
|
||||
for (int i=1; i<=oldM.Extent(); i++) {
|
||||
bool modified=false, generated=false;
|
||||
TopTools_ListIteratorOfListOfShape it;
|
||||
for (it.Initialize(mkShape.Modified(oldM(i))); it.More(); it.Next()) {
|
||||
modified = true;
|
||||
for (int j=1; j<=newM.Extent(); j++) {
|
||||
if (newM(j).IsPartner(it.Value())) {
|
||||
history.modified[i-1].push_back(j-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (it.Initialize(mkShape.Generated(oldM(i))); it.More(); it.Next()) {
|
||||
generated = true;
|
||||
for (int j=1; j<=newM.Extent(); j++) {
|
||||
if (newM(j).IsPartner(it.Value())) {
|
||||
history.generated[i-1].push_back(j-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!modified && !generated) {
|
||||
if (mkShape.IsDeleted(oldM(i))) {
|
||||
history.deleted.insert(i-1);
|
||||
}
|
||||
else {
|
||||
for (int j=1; j<=newM.Extent(); j++) {
|
||||
if (newM(j).IsPartner(oldM(i))) {
|
||||
history.accepted[i-1] = j-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return history;
|
||||
}
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* Feature::getViewProviderName(void) const {
|
||||
return "PartGui::ViewProviderPart";
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <App/FeaturePython.h>
|
||||
#include <App/PropertyGeo.h>
|
||||
|
||||
class BRepBuilderAPI_MakeShape;
|
||||
|
||||
namespace Part
|
||||
{
|
||||
|
||||
|
@ -63,9 +65,9 @@ public:
|
|||
|
||||
protected:
|
||||
void onChanged(const App::Property* prop);
|
||||
|
||||
protected:
|
||||
TopLoc_Location getLocation() const;
|
||||
ShapeHistory buildHistory(BRepBuilderAPI_MakeShape&, TopAbs_ShapeEnum type,
|
||||
const TopoDS_Shape& newS, const TopoDS_Shape& oldS);
|
||||
};
|
||||
|
||||
class FilletBase : public Part::Feature
|
||||
|
|
|
@ -343,6 +343,72 @@ void PropertyPartShape::RestoreDocFile(Base::Reader &reader)
|
|||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
TYPESYSTEM_SOURCE(Part::PropertyShapeHistory , App::PropertyLists);
|
||||
|
||||
PropertyShapeHistory::PropertyShapeHistory()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyShapeHistory::~PropertyShapeHistory()
|
||||
{
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::setValue(const ShapeHistory& sh)
|
||||
{
|
||||
aboutToSetValue();
|
||||
_lValueList.resize(1);
|
||||
_lValueList[0] = sh;
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::setValues(const std::vector<ShapeHistory>& values)
|
||||
{
|
||||
aboutToSetValue();
|
||||
_lValueList = values;
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
PyObject *PropertyShapeHistory::getPyObject(void)
|
||||
{
|
||||
return Py::new_reference_to(Py::None());
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::setPyObject(PyObject *value)
|
||||
{
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::Save (Base::Writer &writer) const
|
||||
{
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::Restore(Base::XMLReader &reader)
|
||||
{
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::SaveDocFile (Base::Writer &writer) const
|
||||
{
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::RestoreDocFile(Base::Reader &reader)
|
||||
{
|
||||
}
|
||||
|
||||
App::Property *PropertyShapeHistory::Copy(void) const
|
||||
{
|
||||
PropertyShapeHistory *p= new PropertyShapeHistory();
|
||||
p->_lValueList = _lValueList;
|
||||
return p;
|
||||
}
|
||||
|
||||
void PropertyShapeHistory::Paste(const Property &from)
|
||||
{
|
||||
aboutToSetValue();
|
||||
_lValueList = dynamic_cast<const PropertyShapeHistory&>(from)._lValueList;
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
TYPESYSTEM_SOURCE(Part::PropertyFilletEdges , App::PropertyLists);
|
||||
|
||||
PropertyFilletEdges::PropertyFilletEdges()
|
||||
|
|
|
@ -21,12 +21,15 @@
|
|||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef PROPERTYTOPOSHAPE_H
|
||||
#define PROPERTYTOPOSHAPE_H
|
||||
#ifndef PART_PROPERTYTOPOSHAPE_H
|
||||
#define PART_PROPERTYTOPOSHAPE_H
|
||||
|
||||
#include "TopoShape.h"
|
||||
#include <TopAbs_ShapeEnum.hxx>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyGeo.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace Part
|
||||
{
|
||||
|
@ -95,6 +98,59 @@ private:
|
|||
TopoShape _Shape;
|
||||
};
|
||||
|
||||
struct PartExport ShapeHistory {
|
||||
TopAbs_ShapeEnum type;
|
||||
std::map<int, std::vector<int> > modified;
|
||||
std::map<int, std::vector<int> > generated;
|
||||
std::map<int, int> accepted;
|
||||
std::set<int> deleted;
|
||||
};
|
||||
|
||||
class PartExport PropertyShapeHistory : public App::PropertyLists
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
PropertyShapeHistory();
|
||||
~PropertyShapeHistory();
|
||||
|
||||
virtual void setSize(int newSize) {
|
||||
_lValueList.resize(newSize);
|
||||
}
|
||||
virtual int getSize(void) const {
|
||||
return _lValueList.size();
|
||||
}
|
||||
|
||||
/** Sets the property
|
||||
*/
|
||||
void setValue(const ShapeHistory&);
|
||||
|
||||
void setValues (const std::vector<ShapeHistory>& values);
|
||||
|
||||
const std::vector<ShapeHistory> &getValues(void) const {
|
||||
return _lValueList;
|
||||
}
|
||||
|
||||
virtual PyObject *getPyObject(void);
|
||||
virtual void setPyObject(PyObject *);
|
||||
|
||||
virtual void Save (Base::Writer &writer) const;
|
||||
virtual void Restore(Base::XMLReader &reader);
|
||||
|
||||
virtual void SaveDocFile (Base::Writer &writer) const;
|
||||
virtual void RestoreDocFile(Base::Reader &reader);
|
||||
|
||||
virtual Property *Copy(void) const;
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
virtual unsigned int getMemSize (void) const {
|
||||
return _lValueList.size() * sizeof(ShapeHistory);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ShapeHistory> _lValueList;
|
||||
};
|
||||
|
||||
/** A property class to store hash codes and two radii for the fillet algorithm.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
|
@ -151,4 +207,4 @@ private:
|
|||
} //namespace Part
|
||||
|
||||
|
||||
#endif // PROPERTYTOPOSHAPE_H
|
||||
#endif // PART_PROPERTYTOPOSHAPE_H
|
||||
|
|
|
@ -77,80 +77,69 @@ QIcon ViewProviderBoolean::getIcon(void) const
|
|||
return ViewProviderPart::getIcon();
|
||||
}
|
||||
|
||||
void findFaces(BRepAlgoAPI_BooleanOperation* mkBool,
|
||||
const TopTools_IndexedMapOfShape& M1,
|
||||
const TopTools_IndexedMapOfShape& M3,
|
||||
const std::vector<App::Color>& colBase,
|
||||
std::vector<App::Color>& colBool)
|
||||
void applyColor(const Part::ShapeHistory& hist,
|
||||
const std::vector<App::Color>& colBase,
|
||||
std::vector<App::Color>& colBool)
|
||||
{
|
||||
for (int i=1; i<=M1.Extent(); i++) {
|
||||
bool modified=false, generated=false;
|
||||
TopTools_ListIteratorOfListOfShape it;
|
||||
for (it.Initialize(mkBool->Modified(M1(i))); it.More(); it.Next()) {
|
||||
modified = true;
|
||||
for (int j=1; j<=M3.Extent(); j++) {
|
||||
if (M3(j).IsPartner(it.Value())) {
|
||||
colBool[j-1] = colBase[i-1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::map<int, std::vector<int> >::const_iterator jt;
|
||||
// apply color from modified faces
|
||||
for (jt = hist.modified.begin(); jt != hist.modified.end(); ++jt) {
|
||||
std::vector<int>::const_iterator kt;
|
||||
for (kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
|
||||
colBool[*kt] = colBase[jt->first];
|
||||
}
|
||||
|
||||
for (it.Initialize(mkBool->Generated(M1(i))); it.More(); it.Next()) {
|
||||
generated = true;
|
||||
for (int j=1; j<=M3.Extent(); j++) {
|
||||
if (M3(j).IsPartner(it.Value())) {
|
||||
colBool[j-1] = colBase[i-1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!modified && !generated && !mkBool->IsDeleted(M1(i))) {
|
||||
for (int j=1; j<=M3.Extent(); j++) {
|
||||
if (M3(j).IsPartner(M1(i))) {
|
||||
colBool[j-1] = colBase[i-1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// apply color from generated faces
|
||||
for (jt = hist.generated.begin(); jt != hist.generated.end(); ++jt) {
|
||||
std::vector<int>::const_iterator kt;
|
||||
for (kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
|
||||
colBool[*kt] = colBase[jt->first];
|
||||
}
|
||||
}
|
||||
// apply data from accepted faces
|
||||
for (std::map<int, int>::const_iterator kt = hist.accepted.begin(); kt != hist.accepted.end(); ++kt) {
|
||||
colBool[kt->second] = colBase[kt->first];
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderBoolean::updateData(const App::Property* prop)
|
||||
{
|
||||
PartGui::ViewProviderPart::updateData(prop);
|
||||
if (prop->getTypeId() == Part::PropertyPartShape::getClassTypeId()) {
|
||||
if (prop->getTypeId() == Part::PropertyShapeHistory::getClassTypeId()) {
|
||||
const std::vector<Part::ShapeHistory>& hist = static_cast<const Part::PropertyShapeHistory*>
|
||||
(prop)->getValues();
|
||||
if (hist.size() != 2)
|
||||
return;
|
||||
Part::Boolean* objBool = dynamic_cast<Part::Boolean*>(getObject());
|
||||
Part::Feature* objBase = dynamic_cast<Part::Feature*>(objBool->Base.getValue());
|
||||
Part::Feature* objTool = dynamic_cast<Part::Feature*>(objBool->Tool.getValue());
|
||||
|
||||
BRepAlgoAPI_BooleanOperation* mkBool = objBool->getBooleanOperation();
|
||||
if (mkBool && objBase && objTool) {
|
||||
if (objBase && objTool) {
|
||||
const TopoDS_Shape& baseShape = objBase->Shape.getValue();
|
||||
const TopoDS_Shape& toolShape = objTool->Shape.getValue();
|
||||
const TopoDS_Shape& boolShape = objBool->Shape.getValue();
|
||||
|
||||
TopTools_IndexedMapOfShape M1, M2, M3;
|
||||
TopExp::MapShapes(baseShape, TopAbs_FACE, M1);
|
||||
TopExp::MapShapes(toolShape, TopAbs_FACE, M2);
|
||||
TopExp::MapShapes(boolShape, TopAbs_FACE, M3);
|
||||
TopTools_IndexedMapOfShape baseMap, toolMap, boolMap;
|
||||
TopExp::MapShapes(baseShape, TopAbs_FACE, baseMap);
|
||||
TopExp::MapShapes(toolShape, TopAbs_FACE, toolMap);
|
||||
TopExp::MapShapes(boolShape, TopAbs_FACE, boolMap);
|
||||
|
||||
Gui::ViewProvider* vpBase = Gui::Application::Instance->getViewProvider(objBase);
|
||||
Gui::ViewProvider* vpTool = Gui::Application::Instance->getViewProvider(objTool);
|
||||
std::vector<App::Color> colBase = static_cast<PartGui::ViewProviderPart*>(vpBase)->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colTool = static_cast<PartGui::ViewProviderPart*>(vpTool)->DiffuseColor.getValues();
|
||||
std::vector<App::Color> colBool;
|
||||
colBool.resize(M3.Extent(), this->ShapeColor.getValue());
|
||||
bool applyColor=false;
|
||||
if (colBase.size() == M1.Extent()) {
|
||||
findFaces(mkBool, M1, M3, colBase, colBool);
|
||||
applyColor = true;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeColor.getValue());
|
||||
|
||||
bool setColor=false;
|
||||
if (colBase.size() == baseMap.Extent()) {
|
||||
applyColor(hist[0], colBase, colBool);
|
||||
setColor = true;
|
||||
}
|
||||
if (colTool.size() == M2.Extent()) {
|
||||
findFaces(mkBool, M2, M3, colTool, colBool);
|
||||
applyColor = true;
|
||||
if (colTool.size() == toolMap.Extent()) {
|
||||
applyColor(hist[1], colTool, colBool);
|
||||
setColor = true;
|
||||
}
|
||||
if (applyColor)
|
||||
if (setColor)
|
||||
this->DiffuseColor.setValues(colBool);
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +165,46 @@ QIcon ViewProviderMultiFuse::getIcon(void) const
|
|||
return Gui::BitmapFactory().pixmap("Part_Fuse");
|
||||
}
|
||||
|
||||
void ViewProviderMultiFuse::updateData(const App::Property* prop)
|
||||
{
|
||||
PartGui::ViewProviderPart::updateData(prop);
|
||||
if (prop->getTypeId() == Part::PropertyShapeHistory::getClassTypeId()) {
|
||||
const std::vector<Part::ShapeHistory>& hist = static_cast<const Part::PropertyShapeHistory*>
|
||||
(prop)->getValues();
|
||||
Part::MultiFuse* objBool = dynamic_cast<Part::MultiFuse*>(getObject());
|
||||
std::vector<App::DocumentObject*> sources = objBool->Shapes.getValues();
|
||||
if (hist.size() != sources.size())
|
||||
return;
|
||||
|
||||
const TopoDS_Shape& boolShape = objBool->Shape.getValue();
|
||||
TopTools_IndexedMapOfShape boolMap;
|
||||
TopExp::MapShapes(boolShape, TopAbs_FACE, boolMap);
|
||||
|
||||
std::vector<App::Color> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeColor.getValue());
|
||||
|
||||
bool setColor=false;
|
||||
int index=0;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = sources.begin(); it != sources.end(); ++it, ++index) {
|
||||
Part::Feature* objBase = dynamic_cast<Part::Feature*>(*it);
|
||||
const TopoDS_Shape& baseShape = objBase->Shape.getValue();
|
||||
|
||||
TopTools_IndexedMapOfShape baseMap;
|
||||
TopExp::MapShapes(baseShape, TopAbs_FACE, baseMap);
|
||||
|
||||
Gui::ViewProvider* vpBase = Gui::Application::Instance->getViewProvider(objBase);
|
||||
std::vector<App::Color> colBase = static_cast<PartGui::ViewProviderPart*>(vpBase)->DiffuseColor.getValues();
|
||||
if (colBase.size() == baseMap.Extent()) {
|
||||
applyColor(hist[index], colBase, colBool);
|
||||
setColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (setColor)
|
||||
this->DiffuseColor.setValues(colBool);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PROPERTY_SOURCE(PartGui::ViewProviderMultiCommon,PartGui::ViewProviderPart)
|
||||
|
||||
|
@ -196,3 +225,43 @@ QIcon ViewProviderMultiCommon::getIcon(void) const
|
|||
{
|
||||
return Gui::BitmapFactory().pixmap("Part_Common");
|
||||
}
|
||||
|
||||
void ViewProviderMultiCommon::updateData(const App::Property* prop)
|
||||
{
|
||||
PartGui::ViewProviderPart::updateData(prop);
|
||||
if (prop->getTypeId() == Part::PropertyShapeHistory::getClassTypeId()) {
|
||||
const std::vector<Part::ShapeHistory>& hist = static_cast<const Part::PropertyShapeHistory*>
|
||||
(prop)->getValues();
|
||||
Part::MultiCommon* objBool = dynamic_cast<Part::MultiCommon*>(getObject());
|
||||
std::vector<App::DocumentObject*> sources = objBool->Shapes.getValues();
|
||||
if (hist.size() != sources.size())
|
||||
return;
|
||||
|
||||
const TopoDS_Shape& boolShape = objBool->Shape.getValue();
|
||||
TopTools_IndexedMapOfShape boolMap;
|
||||
TopExp::MapShapes(boolShape, TopAbs_FACE, boolMap);
|
||||
|
||||
std::vector<App::Color> colBool;
|
||||
colBool.resize(boolMap.Extent(), this->ShapeColor.getValue());
|
||||
|
||||
bool setColor=false;
|
||||
int index=0;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = sources.begin(); it != sources.end(); ++it, ++index) {
|
||||
Part::Feature* objBase = dynamic_cast<Part::Feature*>(*it);
|
||||
const TopoDS_Shape& baseShape = objBase->Shape.getValue();
|
||||
|
||||
TopTools_IndexedMapOfShape baseMap;
|
||||
TopExp::MapShapes(baseShape, TopAbs_FACE, baseMap);
|
||||
|
||||
Gui::ViewProvider* vpBase = Gui::Application::Instance->getViewProvider(objBase);
|
||||
std::vector<App::Color> colBase = static_cast<PartGui::ViewProviderPart*>(vpBase)->DiffuseColor.getValues();
|
||||
if (colBase.size() == baseMap.Extent()) {
|
||||
applyColor(hist[index], colBase, colBool);
|
||||
setColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (setColor)
|
||||
this->DiffuseColor.setValues(colBool);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
/// grouping handling
|
||||
std::vector<App::DocumentObject*> claimChildren(void) const;
|
||||
QIcon getIcon(void) const;
|
||||
void updateData(const App::Property*);
|
||||
};
|
||||
|
||||
/// ViewProvider for the MultiFuse feature
|
||||
|
@ -75,6 +76,7 @@ public:
|
|||
/// grouping handling
|
||||
std::vector<App::DocumentObject*> claimChildren(void) const;
|
||||
QIcon getIcon(void) const;
|
||||
void updateData(const App::Property*);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user