Keep faces colors on boolean operations

This commit is contained in:
wmayer 2012-05-31 15:28:15 +02:00
parent 9e872e4987
commit 20fcef29c7
6 changed files with 79 additions and 41 deletions

View File

@ -25,6 +25,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepAlgoAPI_Common.hxx>
# include <Standard_Failure.hxx>
#endif
@ -81,22 +82,38 @@ 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:
BRepAlgoAPI_Common mkCommon(res, *it);
// Let's check if the fusion has been successful
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()));
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:
BRepAlgoAPI_Common mkCommon(res, *it);
// Let's check if the fusion has been successful
if (!mkCommon.IsDone())
throw Base::Exception("Intersection failed");
res = mkCommon.Shape();
ShapeHistory hist1 = buildHistory(mkCommon, TopAbs_FACE, res, mkCommon.Shape1());
ShapeHistory hist2 = buildHistory(mkCommon, TopAbs_FACE, res, mkCommon.Shape2());
if (history.empty()) {
history.push_back(hist1);
history.push_back(hist2);
}
else {
for (std::vector<ShapeHistory>::iterator jt = history.begin(); jt != history.end(); ++jt)
*jt = joinHistory(*jt, hist1);
history.push_back(hist2);
}
}
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();
return new App::DocumentObjectExecReturn(e->GetMessageString());
}
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");

View File

@ -91,8 +91,18 @@ 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()));
ShapeHistory hist1 = buildHistory(mkFuse, TopAbs_FACE, res, mkFuse.Shape1());
ShapeHistory hist2 = buildHistory(mkFuse, TopAbs_FACE, res, mkFuse.Shape2());
if (history.empty()) {
history.push_back(hist1);
history.push_back(hist2);
}
else {
for (std::vector<ShapeHistory>::iterator jt = history.begin(); jt != history.end(); ++jt)
*jt = joinHistory(*jt, hist1);
history.push_back(hist2);
}
}
if (res.IsNull())
throw Base::Exception("Resulting shape is invalid");

View File

@ -143,36 +143,36 @@ ShapeHistory Feature::buildHistory(BRepBuilderAPI_MakeShape& mkShape, TopAbs_Sha
TopExp::MapShapes(oldS, type, oldM);
for (int i=1; i<=oldM.Extent(); i++) {
bool modified=false, generated=false;
bool found = false;
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(mkShape.Modified(oldM(i))); it.More(); it.Next()) {
modified = true;
found = true;
for (int j=1; j<=newM.Extent(); j++) {
if (newM(j).IsPartner(it.Value())) {
history.modified[i-1].push_back(j-1);
history.shapeMap[i-1].push_back(j-1);
break;
}
}
}
for (it.Initialize(mkShape.Generated(oldM(i))); it.More(); it.Next()) {
generated = true;
found = true;
for (int j=1; j<=newM.Extent(); j++) {
if (newM(j).IsPartner(it.Value())) {
history.generated[i-1].push_back(j-1);
history.shapeMap[i-1].push_back(j-1);
break;
}
}
}
if (!modified && !generated) {
if (!found) {
if (mkShape.IsDeleted(oldM(i))) {
history.deleted.insert(i-1);
history.shapeMap[i-1] = std::vector<int>();
}
else {
for (int j=1; j<=newM.Extent(); j++) {
if (newM(j).IsPartner(oldM(i))) {
history.accepted[i-1] = j-1;
history.shapeMap[i-1].push_back(j-1);
break;
}
}
@ -183,6 +183,27 @@ ShapeHistory Feature::buildHistory(BRepBuilderAPI_MakeShape& mkShape, TopAbs_Sha
return history;
}
ShapeHistory Feature::joinHistory(const ShapeHistory& oldH, const ShapeHistory& newH)
{
ShapeHistory join;
join.type = oldH.type;
for (ShapeHistory::MapList::const_iterator it = oldH.shapeMap.begin(); it != oldH.shapeMap.end(); ++it) {
int old_shape_index = it->first;
if (it->second.empty())
join.shapeMap[old_shape_index] = ShapeHistory::List();
for (ShapeHistory::List::const_iterator jt = it->second.begin(); jt != it->second.end(); ++jt) {
ShapeHistory::MapList::const_iterator kt = newH.shapeMap.find(*jt);
if (kt != newH.shapeMap.end()) {
ShapeHistory::List& ary = join.shapeMap[old_shape_index];
ary.insert(ary.end(), kt->second.begin(), kt->second.end());
}
}
}
return join;
}
/// returns the type name of the ViewProvider
const char* Feature::getViewProviderName(void) const {
return "PartGui::ViewProviderPart";

View File

@ -68,6 +68,7 @@ protected:
TopLoc_Location getLocation() const;
ShapeHistory buildHistory(BRepBuilderAPI_MakeShape&, TopAbs_ShapeEnum type,
const TopoDS_Shape& newS, const TopoDS_Shape& oldS);
ShapeHistory joinHistory(const ShapeHistory&, const ShapeHistory&);
};
class FilletBase : public Part::Feature

View File

@ -99,11 +99,11 @@ private:
};
struct PartExport ShapeHistory {
typedef std::map<int, std::vector<int> > MapList;
typedef std::vector<int> List;
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;
MapList shapeMap;
};
class PartExport PropertyShapeHistory : public App::PropertyLists

View File

@ -83,23 +83,12 @@ void applyColor(const Part::ShapeHistory& hist,
{
std::map<int, std::vector<int> >::const_iterator jt;
// apply color from modified faces
for (jt = hist.modified.begin(); jt != hist.modified.end(); ++jt) {
for (jt = hist.shapeMap.begin(); jt != hist.shapeMap.end(); ++jt) {
std::vector<int>::const_iterator kt;
for (kt = jt->second.begin(); kt != jt->second.end(); ++kt) {
colBool[*kt] = colBase[jt->first];
}
}
// 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)