diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index d87f405ceb..e92b84fa01 100644 --- a/src/App/GeoFeature.cpp +++ b/src/App/GeoFeature.cpp @@ -48,6 +48,11 @@ PROPERTY_SOURCE(App::GeoFeature, App::DocumentObject) GeoFeature::GeoFeature() { ADD_PROPERTY_TYPE(Placement, (Base::Placement()), nullptr, Prop_NoRecompute, nullptr); + ADD_PROPERTY_TYPE(_ElementMapVersion, + (""), + "Base", + (App::PropertyType)(Prop_Output | Prop_Hidden | Prop_Transient), + ""); } GeoFeature::~GeoFeature() = default; @@ -244,6 +249,16 @@ void GeoFeature::updateElementReference() return; } bool reset = false; + + auto version = getElementMapVersion(prop); + if (_ElementMapVersion.getStrValue().empty()) { + _ElementMapVersion.setValue(version); + } + else if (_ElementMapVersion.getStrValue() != version) { + reset = true; + _ElementMapVersion.setValue(version); + } + PropertyLinkBase::updateElementReferences(this, reset); } @@ -258,6 +273,14 @@ void GeoFeature::onChanged(const Property* prop) DocumentObject::onChanged(prop); } +void GeoFeature::onDocumentRestored() +{ + if (!getDocument()->testStatus(Document::Status::Importing)) { + _ElementMapVersion.setValue(getElementMapVersion(getPropertyOfGeometry(), true)); + } + DocumentObject::onDocumentRestored(); +} + const std::vector& GeoFeature::searchElementCache(const std::string& element, Data::SearchOptions options, double tol, diff --git a/src/App/GeoFeature.h b/src/App/GeoFeature.h index cb4dcfbd66..eee0d53559 100644 --- a/src/App/GeoFeature.h +++ b/src/App/GeoFeature.h @@ -42,6 +42,7 @@ class AppExport GeoFeature: public App::DocumentObject public: PropertyPlacement Placement; + PropertyString _ElementMapVersion; /// Constructor GeoFeature(); @@ -198,7 +199,7 @@ public: protected: void onChanged(const Property* prop) override; - // void onDocumentRestored() override; + void onDocumentRestored() override; void updateElementReference(); protected: diff --git a/src/Mod/Part/App/PartFeature.cpp b/src/Mod/Part/App/PartFeature.cpp index b4550f49a3..47dc709f27 100644 --- a/src/Mod/Part/App/PartFeature.cpp +++ b/src/Mod/Part/App/PartFeature.cpp @@ -1640,6 +1640,12 @@ Feature* Feature::create(const TopoShape& shape, const char* name, App::Document return res; } +void Feature::onDocumentRestored() +{ + // expandShapeContents(); + App::GeoFeature::onDocumentRestored(); +} + ShapeHistory Feature::buildHistory(BRepBuilderAPI_MakeShape& mkShape, TopAbs_ShapeEnum type, const TopoDS_Shape& newS, const TopoDS_Shape& oldS) { diff --git a/src/Mod/Part/App/PartFeature.h b/src/Mod/Part/App/PartFeature.h index 4311fe2be2..15ab5822df 100644 --- a/src/Mod/Part/App/PartFeature.h +++ b/src/Mod/Part/App/PartFeature.h @@ -175,6 +175,7 @@ protected: App::DocumentObjectExecReturn *execute() override; void onBeforeChange(const App::Property* prop) override; void onChanged(const App::Property* prop) override; + void onDocumentRestored() override; void copyMaterial(Feature* feature); void copyMaterial(App::DocumentObject* link); diff --git a/src/Mod/Part/App/PropertyTopoShape.cpp b/src/Mod/Part/App/PropertyTopoShape.cpp index 17c4123325..552467d1c5 100644 --- a/src/Mod/Part/App/PropertyTopoShape.cpp +++ b/src/Mod/Part/App/PropertyTopoShape.cpp @@ -587,11 +587,25 @@ void PropertyPartShape::SaveDocFile (Base::Writer &writer) const void PropertyPartShape::RestoreDocFile(Base::Reader &reader) { + + // save the element map + auto elementMap = _Shape.resetElementMap(); + auto hasher = _Shape.Hasher; + Base::FileInfo brep(reader.getFileName()); + TopoShape shape; + + // In LS3 the following statement is executed right before shape.Hasher = hasher; + // https://github.com/realthunder/FreeCAD/blob/a9810d509a6f112b5ac03d4d4831b67e6bffd5b7/src/Mod/Part/App/PropertyTopoShape.cpp#L639 + // Now it's not possible anymore because both PropertyPartShape::loadFromFile() and + // PropertyPartShape::loadFromStream() calls PropertyPartShape::setValue() which clears the + // value of _Ver. + // Therefor we're storing the value of _Ver here so that we don't lose it. + + std::string ver = _Ver; + if (brep.hasExtension("bin")) { - TopoShape shape; shape.importBinary(reader); - setValue(shape); } else { bool direct = App::GetApplication().GetParameterGroupByPath @@ -604,7 +618,14 @@ void PropertyPartShape::RestoreDocFile(Base::Reader &reader) loadFromStream(reader); reader.exceptions(iostate); } + shape = getValue(); } + + // restore the element map + shape.Hasher = hasher; + shape.resetElementMap(elementMap); + setValue(shape); + _Ver = ver; } // ------------------------------------------------------------------------- diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index 878333b36e..9e292111a3 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -1502,6 +1502,8 @@ public: void mapSubElementsTo(std::vector& shapes, const char* op = nullptr) const; bool hasPendingElementMap() const; + virtual std::string getElementMapVersion() const; + void flushElementMap() const override; Data::ElementMapPtr resetElementMap( diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 31f4f70105..d24725bf0a 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -2057,6 +2057,29 @@ TopoShape TopoShape::getSubTopoShape(TopAbs_ShapeEnum type, int idx, bool silent return shapeMap.getTopoShape(*this, idx); } +static const std::string& _getElementMapVersion() +{ + static std::string _ver; + if (_ver.empty()) { + std::ostringstream ss; + unsigned occ_ver; + if ((OCC_VERSION_HEX & 0xFF0000) == 0x070000) { + occ_ver = 0x070200; + } + else { + occ_ver = OCC_VERSION_HEX; + } + ss << OpCodes::Version << '.' << std::hex << occ_ver << '.'; + _ver = ss.str(); + } + return _ver; +} + +std::string TopoShape::getElementMapVersion() const +{ + return _getElementMapVersion() + Data::ComplexGeoData::getElementMapVersion(); +} + TopoShape& TopoShape::makeElementEvolve(const TopoShape& spine, const TopoShape& profile, JoinType join,