530 lines
13 KiB
C++
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(¶ele);
|
|
}
|
|
|
|
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(¶ele);
|
|
}
|
|
|
|
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
|