/** * @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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 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 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