+ save Brep in binary format for recovery files
This commit is contained in:
parent
739e643f2f
commit
32367b1744
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user