+ save Brep in binary format for recovery files

This commit is contained in:
wmayer 2015-09-16 22:58:47 +02:00
parent 739e643f2f
commit 32367b1744
7 changed files with 151 additions and 81 deletions

View File

@ -319,7 +319,7 @@ void Base::XMLReader::readFiles(zipios::ZipInputStream &zipstream) const
// no file name for the current entry in the zip was registered.
if (jt != FileList.end()) {
try {
Base::Reader reader(zipstream,DocumentSchema);
Base::Reader reader(zipstream, jt->FileName, DocumentSchema);
jt->Object->RestoreDocFile(reader);
}
catch(...) {
@ -506,11 +506,16 @@ void Base::XMLReader::resetErrors()
// ----------------------------------------------------------
Base::Reader::Reader(std::istream& str, int version)
: std::istream(str.rdbuf()), _str(str), fileVersion(version)
Base::Reader::Reader(std::istream& str, const std::string& name, int version)
: std::istream(str.rdbuf()), _str(str), _name(name), fileVersion(version)
{
}
std::string Base::Reader::getFileName() const
{
return this->_name;
}
int Base::Reader::getFileVersion() const
{
return fileVersion;

View File

@ -257,12 +257,14 @@ protected:
class BaseExport Reader : public std::istream
{
public:
Reader(std::istream&, int version);
int getFileVersion() const;
Reader(std::istream&, const std::string&, int version);
std::istream& getStream();
std::string getFileName() const;
int getFileVersion() const;
private:
std::istream& _str;
std::string _name;
int fileVersion;
};

View File

@ -108,6 +108,24 @@ int Writer::getFileVersion() const
return fileVersion;
}
void Writer::setMode(const std::string& mode)
{
Modes.insert(mode);
}
bool Writer::getMode(const std::string& mode) const
{
std::set<std::string>::const_iterator it = Modes.find(mode);
return (it != Modes.end());
}
void Writer::clearMode(const std::string& mode)
{
std::set<std::string>::iterator it = Modes.find(mode);
if (it != Modes.end())
Modes.erase(it);
}
std::string Writer::addFile(const char* Name,const Base::Persistence *Object)
{
// always check isForceXML() before requesting a file!

View File

@ -24,6 +24,7 @@
#define BASE_WRITER_H
#include <set>
#include <string>
#include <sstream>
#include <vector>
@ -80,6 +81,12 @@ public:
virtual void writeFiles(void)=0;
/// get all registered file names
const std::vector<std::string>& getFilenames() const;
/// Set mode
void setMode(const std::string& mode);
/// Get mode
bool getMode(const std::string& mode) const;
/// Clear mode
void clearMode(const std::string& mode);
//@}
/** @name pretty formating for XML */
@ -105,6 +112,7 @@ protected:
};
std::vector<FileEntry> FileList;
std::vector<std::string> FileNames;
std::set<std::string> Modes;
short indent;
char indBuf[1024];

View File

@ -139,6 +139,8 @@ void AutoSaver::saveDocument(const std::string& name)
Base::ofstream file(tmp, std::ios::out | std::ios::binary);
if (file.is_open()) {
Base::ZipWriter writer(file);
if (hGrp->GetBool("SaveBinaryBrep", true))
writer.setMode("BinaryBrep");
writer.setComment("AutoRecovery file");
writer.setLevel(1); // apparently the fastest compression

View File

@ -232,9 +232,16 @@ void PropertyPartShape::Save (Base::Writer &writer) const
{
if(!writer.isForceXML()) {
//See SaveDocFile(), RestoreDocFile()
writer.Stream() << writer.ind() << "<Part file=\""
<< writer.addFile("PartShape.brp", this)
<< "\"/>" << std::endl;
if (writer.getMode("BinaryBrep")) {
writer.Stream() << writer.ind() << "<Part file=\""
<< writer.addFile("PartShape.bin", this)
<< "\"/>" << std::endl;
}
else {
writer.Stream() << writer.ind() << "<Part file=\""
<< writer.addFile("PartShape.brp", this)
<< "\"/>" << std::endl;
}
}
}
@ -261,92 +268,107 @@ void PropertyPartShape::SaveDocFile (Base::Writer &writer) const
const TopoDS_Shape& myShape = copy.Shape();
BRepTools::Clean(myShape); // remove triangulation
// create a temporary file and copy the content to the zip stream
// once the tmp. filename is known use always the same because otherwise
// we may run into some problems on the Linux platform
static Base::FileInfo fi(Base::FileInfo::getTempFileName());
if (!BRepTools::Write(myShape,(const Standard_CString)fi.filePath().c_str())) {
// Note: Do NOT throw an exception here because if the tmp. file could
// not be created we should not abort.
// We only print an error message but continue writing the next files to the
// stream...
App::PropertyContainer* father = this->getContainer();
if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
App::DocumentObject* obj = static_cast<App::DocumentObject*>(father);
Base::Console().Error("Shape of '%s' cannot be written to BRep file '%s'\n",
obj->Label.getValue(),fi.filePath().c_str());
}
else {
Base::Console().Error("Cannot save BRep file '%s'\n", fi.filePath().c_str());
}
if (writer.getMode("BinaryBrep")) {
TopoShape shape;
shape._Shape = myShape;
shape.exportBinary(writer.Stream());
}
else {
// create a temporary file and copy the content to the zip stream
// once the tmp. filename is known use always the same because otherwise
// we may run into some problems on the Linux platform
static Base::FileInfo fi(Base::FileInfo::getTempFileName());
Base::ifstream file(fi, std::ios::in | std::ios::binary);
if (file){
unsigned long ulSize = 0;
std::streambuf* buf = file.rdbuf();
if (buf) {
unsigned long ulCurr;
ulCurr = buf->pubseekoff(0, std::ios::cur, std::ios::in);
ulSize = buf->pubseekoff(0, std::ios::end, std::ios::in);
buf->pubseekoff(ulCurr, std::ios::beg, std::ios::in);
}
// read in the ASCII file and write back to the stream
std::strstreambuf sbuf(ulSize);
file >> &sbuf;
writer.Stream() << &sbuf;
}
file.close();
// remove temp file
fi.deleteFile();
}
void PropertyPartShape::RestoreDocFile(Base::Reader &reader)
{
BRep_Builder builder;
// create a temporary file and copy the content from the zip stream
Base::FileInfo fi(Base::FileInfo::getTempFileName());
// read in the ASCII file and write back to the file stream
Base::ofstream file(fi, std::ios::out | std::ios::binary);
unsigned long ulSize = 0;
if (reader) {
std::streambuf* buf = file.rdbuf();
reader >> buf;
file.flush();
ulSize = buf->pubseekoff(0, std::ios::cur, std::ios::in);
}
file.close();
// Read the shape from the temp file, if the file is empty the stored shape was already empty.
// If it's still empty after reading the (non-empty) file there must occurred an error.
TopoDS_Shape shape;
if (ulSize > 0) {
if (!BRepTools::Read(shape, (const Standard_CString)fi.filePath().c_str(), builder)) {
// Note: Do NOT throw an exception here because if the tmp. created file could
// not be read it's NOT an indication for an invalid input stream 'reader'.
// We only print an error message but continue reading the next files from the
if (!BRepTools::Write(myShape,(const Standard_CString)fi.filePath().c_str())) {
// Note: Do NOT throw an exception here because if the tmp. file could
// not be created we should not abort.
// We only print an error message but continue writing the next files to the
// stream...
App::PropertyContainer* father = this->getContainer();
if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
App::DocumentObject* obj = static_cast<App::DocumentObject*>(father);
Base::Console().Error("BRep file '%s' with shape of '%s' seems to be empty\n",
fi.filePath().c_str(),obj->Label.getValue());
Base::Console().Error("Shape of '%s' cannot be written to BRep file '%s'\n",
obj->Label.getValue(),fi.filePath().c_str());
}
else {
Base::Console().Warning("Loaded BRep file '%s' seems to be empty\n", fi.filePath().c_str());
Base::Console().Error("Cannot save BRep file '%s'\n", fi.filePath().c_str());
}
}
Base::ifstream file(fi, std::ios::in | std::ios::binary);
if (file){
unsigned long ulSize = 0;
std::streambuf* buf = file.rdbuf();
if (buf) {
unsigned long ulCurr;
ulCurr = buf->pubseekoff(0, std::ios::cur, std::ios::in);
ulSize = buf->pubseekoff(0, std::ios::end, std::ios::in);
buf->pubseekoff(ulCurr, std::ios::beg, std::ios::in);
}
// read in the ASCII file and write back to the stream
std::strstreambuf sbuf(ulSize);
file >> &sbuf;
writer.Stream() << &sbuf;
}
file.close();
// remove temp file
fi.deleteFile();
}
}
// delete the temp file
fi.deleteFile();
void PropertyPartShape::RestoreDocFile(Base::Reader &reader)
{
Base::FileInfo brep(reader.getFileName());
if (brep.hasExtension("bin")) {
TopoShape shape;
shape.importBinary(reader);
setValue(shape);
}
else {
BRep_Builder builder;
setValue(shape);
// create a temporary file and copy the content from the zip stream
Base::FileInfo fi(Base::FileInfo::getTempFileName());
// read in the ASCII file and write back to the file stream
Base::ofstream file(fi, std::ios::out | std::ios::binary);
unsigned long ulSize = 0;
if (reader) {
std::streambuf* buf = file.rdbuf();
reader >> buf;
file.flush();
ulSize = buf->pubseekoff(0, std::ios::cur, std::ios::in);
}
file.close();
// Read the shape from the temp file, if the file is empty the stored shape was already empty.
// If it's still empty after reading the (non-empty) file there must occurred an error.
TopoDS_Shape shape;
if (ulSize > 0) {
if (!BRepTools::Read(shape, (const Standard_CString)fi.filePath().c_str(), builder)) {
// Note: Do NOT throw an exception here because if the tmp. created file could
// not be read it's NOT an indication for an invalid input stream 'reader'.
// We only print an error message but continue reading the next files from the
// stream...
App::PropertyContainer* father = this->getContainer();
if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) {
App::DocumentObject* obj = static_cast<App::DocumentObject*>(father);
Base::Console().Error("BRep file '%s' with shape of '%s' seems to be empty\n",
fi.filePath().c_str(),obj->Label.getValue());
}
else {
Base::Console().Warning("Loaded BRep file '%s' seems to be empty\n", fi.filePath().c_str());
}
}
}
// delete the temp file
fi.deleteFile();
setValue(shape);
}
}
// -------------------------------------------------------------------------

View File

@ -34,6 +34,7 @@
#include <Base/Console.h>
#include <Base/Interpreter.h>
#include <Base/GeometryPyCXX.h>
#include <Base/Reader.h>
#include <Base/VectorPy.h>
#include <CXX/Extensions.hxx>
#include <CXX/Objects.hxx>
@ -194,6 +195,8 @@ public:
{
add_varargs_method("interactiveFilletArc",&SandboxModuleGui::interactiveFilletArc,
"Interactive fillet arc");
add_varargs_method("xmlReader",&SandboxModuleGui::xmlReader,
"Read XML");
initialize("This module is the SandboxGui module"); // register with Python
}
@ -223,6 +226,16 @@ private:
}
return Py::None();
}
Py::Object xmlReader(const Py::Tuple& args)
{
std::string file = static_cast<std::string>(Py::String(args[0]));
App::Document* doc = App::GetApplication().newDocument();
std::ifstream str(file.c_str(), std::ios::in);
Base::XMLReader reader(file.c_str(), str);
doc->Restore(reader);
return Py::None();
}
};