LAMPCAE/src/Geometry/geometrySet.cpp

530 lines
13 KiB
C++

/**
* @file geometrySet.cpp
* @brief 几何形状表示类源文件
* @author LAMPCAE研发小组(LAMPCAE@diso.cn)
* @version 2.5.0
* @date 2022-03-24 11:03
* @copyright Copyright (c) Since 2020 青岛数智船海科技有限公司 All rights reserved.
*
* ============================================================================
* Program: LAMPCAE
*
* Copyright (c) Since 2020 青岛数智船海科技有限公司 All rights reserved.
* See License or http://www.LAMPCAE.com/ for details.
*
* BSD 3-Clause License
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.
* ==================================================================================
*/
#include "geometrySet.h"
#include "Geometry/geometryModelParaBase.h"
#include "geometryModelParaBase.h"
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
#include <QCoreApplication>
#include <QDataStream>
#include <QDebug>
#include <QDomAttr>
#include <QDomDocument>
#include <QDomElement>
#include <QDomText>
#include <QString>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Shape.hxx>
#include <vtkDataSet.h>
#include <vtkDataSetWriter.h>
#include <vtkPolyData.h>
#include <vtkPolyDataReader.h>
namespace Geometry {
int GeometrySet::idOffset = 0;
TopoDS_Shape* GeometrySet::tempShape = new TopoDS_Shape;
int GeometrySet::getMaxID()
{
return idOffset;
}
GeometrySet::GeometrySet(GeometryType type, bool need)
{
_type = type;
if(need) {
idOffset++;
setID(idOffset);
}
appendProperty(QString("Visible"), _visible);
}
GeometrySet::~GeometrySet()
{
if(_shape != nullptr)
delete _shape;
if(_parameter != nullptr)
delete _parameter;
}
void GeometrySet::dataToStream(QDataStream* s)
{
*s << _id << _name << _visible;
}
// void GeometrySet::setFilePath(const QString& filepath)
// {
// _filePath = filepath;
// appendProperty(QString("Path"), _filePath);
// }
// QString GeometrySet::getFilePath()
// {
// return _filePath;
// }
void GeometrySet::setVisible(bool v)
{
_visible = v;
appendProperty(QString("Visible"), _visible);
}
bool GeometrySet::isVisible()
{
return _visible;
}
void GeometrySet::setType(GeometryType t)
{
_type = t;
}
GeometryType GeometrySet::getType()
{
return _type;
}
void GeometrySet::setShape(TopoDS_Shape* shape)
{
_shape = shape;
int i = 0;
for(TopExp_Explorer faceExp(*shape, TopAbs_FACE); faceExp.More(); faceExp.Next())
++i;
appendProperty(QObject::tr("Surfaces"), i);
}
TopoDS_Shape* GeometrySet::getShape()
{
return _shape;
}
void GeometrySet::setPoly(vtkPolyData* poly)
{
_polyData = poly;
}
vtkPolyData* GeometrySet::getPoly()
{
return _polyData;
}
TopoDS_Shape* GeometrySet::getShape(int type, int index)
{
*tempShape = TopoDS_Shape();
TopAbs_ShapeEnum shapeType;
switch(type) {
case 1:
shapeType = TopAbs_VERTEX;
break;
case 2:
shapeType = TopAbs_EDGE;
break;
case 3:
shapeType = TopAbs_FACE;
break;
case 4:
shapeType = TopAbs_SOLID;
break;
default:
return tempShape;
}
TopExp_Explorer ptExp(*_shape, shapeType);
for(int i = 0; ptExp.More(); ptExp.Next(), ++i) {
if(i == index) {
*tempShape = ptExp.Current();
break;
}
}
return tempShape;
}
const TopoDS_Shape& GeometrySet::getRealShape(int type, int index)
{
*tempShape = TopoDS_Shape();
TopAbs_ShapeEnum shapeType;
switch(type) {
case 1:
shapeType = TopAbs_VERTEX;
break;
case 2:
shapeType = TopAbs_EDGE;
break;
case 3:
shapeType = TopAbs_FACE;
break;
case 4:
shapeType = TopAbs_SOLID;
break;
default:
return *tempShape;
}
TopExp_Explorer ptExp(*_shape, shapeType);
for(int i = 0; ptExp.More(); ptExp.Next(), ++i) {
if(i == index)
*tempShape = ptExp.Current();
}
return *tempShape;
}
// void GeometrySet::setStlDataSet(vtkSmartPointer<vtkDataSet> polyData)
// {
// _polyData = polyData;
// appendProperty(QObject::tr("Triangles"), (int)polyData->GetNumberOfCells());
// }
// vtkDataSet* GeometrySet::getStlDataSet()
// {
// return _polyData;
// }
QDomElement& GeometrySet::writeToProjectFile(QDomDocument* doc, QDomElement* ele, bool isDiso)
{
QDomElement element = doc->createElement("GeoSet"); // 创建子节点
QDomAttr idattr = doc->createAttribute("ID");
idattr.setValue(QString::number(_id));
element.setAttributeNode(idattr);
QDomAttr visible = doc->createAttribute("Visible");
visible.setValue("True");
if(!_visible)
visible.setValue("False");
element.setAttributeNode(visible);
QDomAttr isSTL = doc->createAttribute("ISSTL");
isSTL.setValue("True");
if(_type != STL)
isSTL.setValue("False");
element.setAttributeNode(isSTL);
QDomElement nameele = doc->createElement("Name");
QDomText nameText = doc->createTextNode(_name);
nameele.appendChild(nameText);
element.appendChild(nameele);
// QDomElement pathele = doc->createElement("Path");
// QDomText pathtext = doc->createTextNode(_filePath);
// pathele.appendChild(pathtext);
// element.appendChild(pathele);
ele->appendChild(element); // 子节点挂载
if(_parameter != nullptr)
_parameter->writeToProjectFile(doc, &element);
if(isDiso) {
QString exelPath = QCoreApplication::applicationDirPath();
const QString tempPath = exelPath + "/../tempIO/" + QString("%1.brep").arg(_id);
if(_type != STL)
this->writeBrep(tempPath);
else
this->writePoly(tempPath);
}
for(int i = 0; i < _subSetList.size(); ++i) {
GeometrySet* subset = _subSetList.at(i);
subset->writeSubSet(doc, &element, isDiso);
}
return element;
}
void GeometrySet::setID(int id)
{
DataBase::setID(id);
if(id > idOffset)
idOffset = id;
}
void GeometrySet::resetMaxID()
{
idOffset = 0;
}
void GeometrySet::readDataFromProjectFile(QDomElement* element, bool isDiso)
{
QDomNodeList subNodeList = element->elementsByTagName("SubSet");
const int nsub = subNodeList.size();
for(int i = 0; i < nsub; ++i) {
QDomElement subele = subNodeList.at(0).toElement();
GeometrySet* subset = new GeometrySet;
subset->readSubSet(&subele, isDiso);
_subSetList.append(subset);
element->removeChild(subele);
}
int id = element->attribute("ID").toInt();
this->setID(id);
bool visible = true;
QString vis = element->attribute("Visible");
if(vis.toLower() == "false")
visible = false;
this->setVisible(visible);
QString isSTL = element->attribute("ISSTL");
if(isSTL.toLower() == "true")
this->setType(STL);
QDomNodeList nameNode = element->elementsByTagName("Name");
if(nameNode.size() != 1)
return;
QString name = nameNode.at(0).toElement().text();
// qDebug() << name;
this->setName(name);
QDomNodeList paraList = element->elementsByTagName("Parameter");
if(paraList.size() == 1) {
QDomElement paraele = paraList.at(0).toElement();
QString type = paraele.attribute("Type");
// qDebug() << type;
_parameter = GeometryModelParaBase::createParaByString(type);
if(_parameter != nullptr)
_parameter->readDataFromProjectFile(&paraele);
}
if(isDiso) {
QString exelPath = QCoreApplication::applicationDirPath();
const QString tempPath = exelPath + "/../tempIO/" + QString("%1.brep").arg(_id);
if(_type != STL)
this->readBrep(tempPath);
else
this->readPoly(tempPath);
}
}
void GeometrySet::removeSubSet(GeometrySet* set)
{
_subSetList.removeOne(set);
}
void GeometrySet::appendSubSet(GeometrySet* set)
{
_subSetList.append(set);
}
int GeometrySet::getSubSetCount()
{
return _subSetList.size();
}
GeometrySet* GeometrySet::getSubSetAt(int index)
{
if(index >= 0 && index < _subSetList.size()) {
return _subSetList.at(index);
}
return nullptr;
}
bool GeometrySet::writeBrep(QString name)
{
QByteArray arr = name.toLatin1();
char* ch = arr.data();
TopoDS_Compound aRes;
BRep_Builder aBuilder;
aBuilder.MakeCompound(aRes);
if(_shape == nullptr)
return false;
aBuilder.Add(aRes, *_shape);
return BRepTools::Write(aRes, ch);
}
bool GeometrySet::writePoly(QString name)
{
QByteArray arr = name.toLatin1();
char* ch = arr.data();
vtkDataSetWriter* w = vtkDataSetWriter::New();
w->SetInputData(_polyData);
w->SetFileName(ch);
w->SetFileTypeToBinary();
w->Update();
w->Delete();
return true;
}
void GeometrySet::setParameter(GeometryModelParaBase* p)
{
_parameter = p;
}
GeometryModelParaBase* GeometrySet::getParameter()
{
return _parameter;
}
bool GeometrySet::isEditable()
{
return _parameter != nullptr;
}
bool GeometrySet::readBrep(QString name)
{
QByteArray arr = name.toLatin1();
char* ch = arr.data();
TopoDS_Shape* ashape = new TopoDS_Shape;
BRep_Builder builder;
BRepTools::Read(*ashape, (const Standard_CString)ch, builder);
if(ashape->IsNull()) {
delete ashape;
return false;
}
_shape = ashape;
return true;
}
bool GeometrySet::readPoly(QString name)
{
QByteArray arr = name.toLatin1();
char* ch = arr.data();
_polyData = vtkPolyData::New();
auto reader = vtkPolyDataReader::New();
reader->SetFileName(ch);
reader->Update();
auto poly = reader->GetOutput();
int n = poly->GetNumberOfCells();
_polyData->DeepCopy(reader->GetOutput());
reader->Delete();
return true;
}
void GeometrySet::writeSubSet(QDomDocument* doc, QDomElement* parent, bool isdiso)
{
QDomElement element = doc->createElement("SubSet"); // 创建子节点
QDomAttr idattr = doc->createAttribute("ID");
idattr.setValue(QString::number(_id));
element.setAttributeNode(idattr);
QDomAttr visible = doc->createAttribute("Visible");
visible.setValue("True");
if(!_visible)
visible.setValue("False");
element.setAttributeNode(visible);
QDomAttr isSTL = doc->createAttribute("ISSTL");
isSTL.setValue("True");
if(_type != STL)
isSTL.setValue("False");
element.setAttributeNode(isSTL);
QDomElement nameele = doc->createElement("Name");
QDomText nameText = doc->createTextNode(_name);
nameele.appendChild(nameText);
element.appendChild(nameele);
parent->appendChild(element); // 子节点挂载
if(_parameter != nullptr)
_parameter->writeToProjectFile(doc, &element);
if(isdiso) {
QString exelPath = QCoreApplication::applicationDirPath();
const QString tempPath = exelPath + "/../tempIO/" + QString("%1.brep").arg(_id);
if(_type != STL)
this->writeBrep(tempPath);
else
this->writePoly(tempPath);
}
}
void GeometrySet::readSubSet(QDomElement* element, bool isDiso /*= false*/)
{
int id = element->attribute("ID").toInt();
this->setID(id);
bool visible = true;
QString vis = element->attribute("Visible");
if(vis.toLower() == "false")
visible = false;
this->setVisible(visible);
QString isSTL = element->attribute("ISSTL");
if(isSTL.toLower() == "true")
this->setType(STL);
QDomNodeList nameNode = element->elementsByTagName("Name");
if(nameNode.size() != 1)
return;
QString name = nameNode.at(0).toElement().text();
// qDebug() << name;
this->setName(name);
QDomNodeList paraList = element->elementsByTagName("Parameter");
if(paraList.size() == 1) {
QDomElement paraele = paraList.at(0).toElement();
QString type = paraele.attribute("Type");
_parameter = GeometryModelParaBase::createParaByString(type);
if(_parameter != nullptr)
_parameter->readDataFromProjectFile(&paraele);
}
if(isDiso) {
QString exelPath = QCoreApplication::applicationDirPath();
const QString tempPath = exelPath + "/../tempIO/" + QString("%1.brep").arg(_id);
if(_type != STL)
this->readBrep(tempPath);
else
this->readPoly(tempPath);
}
}
GeometrySet* GeometrySet::getSetByID(int id)
{
GeometrySet* s = nullptr;
if(id == _id)
s = this;
else {
const int n = _subSetList.size();
for(int i = 0; i < n; ++i) {
GeometrySet* temp = _subSetList.at(i);
if(id == temp->getID()) {
s = temp;
break;
}
}
}
return s;
}
int GeometrySet::getGeoMemberCount(int type)
{
TopAbs_ShapeEnum shapeType;
switch(type) {
case 1:
shapeType = TopAbs_VERTEX;
break;
case 2:
shapeType = TopAbs_EDGE;
break;
case 3:
shapeType = TopAbs_FACE;
break;
case 4:
shapeType = TopAbs_SOLID;
break;
default:
return -1;
}
TopExp_Explorer ptExp(*_shape, shapeType);
QList<Handle(TopoDS_TShape)> tshapelist;
for(int index = 0; ptExp.More(); ptExp.Next(), ++index) {
TopoDS_Shape s = ptExp.Current();
Handle(TopoDS_TShape) ts = s.TShape();
if(tshapelist.contains(ts))
continue;
tshapelist.append(ts);
}
return tshapelist.size();
}
void GeometrySet::releaseSubSet()
{
for(int i = 0; i < _subSetList.size(); ++i) {
delete _subSetList.at(i);
}
_subSetList.clear();
}
} // namespace Geometry