diff --git a/src/Mod/Part/App/FeaturePartCommon.cpp b/src/Mod/Part/App/FeaturePartCommon.cpp index ea4be0edd..44c93a01c 100644 --- a/src/Mod/Part/App/FeaturePartCommon.cpp +++ b/src/Mod/Part/App/FeaturePartCommon.cpp @@ -25,6 +25,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ # include +# include #endif @@ -81,22 +82,38 @@ App::DocumentObjectExecReturn *MultiCommon::execute(void) } if (s.size() >= 2) { - std::vector history; - TopoDS_Shape res = s.front(); - for (std::vector::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 history; + TopoDS_Shape res = s.front(); + for (std::vector::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::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"); diff --git a/src/Mod/Part/App/FeaturePartFuse.cpp b/src/Mod/Part/App/FeaturePartFuse.cpp index 8493b7b88..47efb7a44 100644 --- a/src/Mod/Part/App/FeaturePartFuse.cpp +++ b/src/Mod/Part/App/FeaturePartFuse.cpp @@ -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::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"); diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index e71edcc7d..ef43452df 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -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(); } 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"; diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h index 159f0473e..689736a42 100644 --- a/src/Mod/Part/App/PartFeature.h +++ b/src/Mod/Part/App/PartFeature.h @@ -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 diff --git a/src/Mod/Part/App/PropertyTopoShape.h b/src/Mod/Part/App/PropertyTopoShape.h index 190a82d2a..a75c85ccd 100644 --- a/src/Mod/Part/App/PropertyTopoShape.h +++ b/src/Mod/Part/App/PropertyTopoShape.h @@ -99,11 +99,11 @@ private: }; struct PartExport ShapeHistory { + typedef std::map > MapList; + typedef std::vector List; + TopAbs_ShapeEnum type; - std::map > modified; - std::map > generated; - std::map accepted; - std::set deleted; + MapList shapeMap; }; class PartExport PropertyShapeHistory : public App::PropertyLists diff --git a/src/Mod/Part/Gui/ViewProviderBoolean.cpp b/src/Mod/Part/Gui/ViewProviderBoolean.cpp index 46c85bb65..22a9c8a4e 100644 --- a/src/Mod/Part/Gui/ViewProviderBoolean.cpp +++ b/src/Mod/Part/Gui/ViewProviderBoolean.cpp @@ -83,23 +83,12 @@ void applyColor(const Part::ShapeHistory& hist, { std::map >::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::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::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::const_iterator kt = hist.accepted.begin(); kt != hist.accepted.end(); ++kt) { - colBool[kt->second] = colBase[kt->first]; - } } void ViewProviderBoolean::updateData(const App::Property* prop)