#include "StabilityModel.h" #include #include "MessageHandle.h" #include "CmdDefine.h" #include "OCCStructDataMD.h" #include "BRepMesh_IncrementalMesh.hxx" #include "Logger.h" #include #include #include "Constants.h" #include "PathUtil.h" #include "CommandStreamProcessing.h" StabilityModel *StabilityModel::m_pStabilityModel = nullptr; #ifdef __cplusplus extern "C" { #endif StabilityModel *StabilityModel::getStabilityModelInstance() { if (m_pStabilityModel == nullptr) { m_pStabilityModel = new StabilityModel(); } return m_pStabilityModel; } void StabilityModel::destroy() { if (m_pStabilityModel != nullptr) { delete m_pStabilityModel; m_pStabilityModel = nullptr; } } void StabilityModel::loadXLSXFile(const QString &filePath) { if (!m_pDataManager) { return; } m_eLoadDataType = XMLFile_Type_xls; m_pDataManager->readFile(m_eLoadDataType, filePath); } DataManager *StabilityModel::getDataManagerPtr() { if (m_pDataManager) { return m_pDataManager; } return nullptr;; } StabilityModel *StabilityModel::getStabilityModelpPtr() { return m_pStabilityModel; } void StabilityModel::get3DObjColor(int type,int& iColor,bool& isShowName) { OptionDataColorSetting::getOptionDataColorSettingInstance().get3DObjColor((E_Stablity_ModelDisplay_Color)type,iColor,isShowName); } StabilityModel::StabilityModel() { // 获取主程序中的共享 logger 实例 OptionDataColorSetting::getOptionDataColorSettingInstance(); auto log_t = get_shared_logger(); spdlog::set_default_logger(log_t); // 设置为默认 logger ChangeFSPos::reset(); m_pDataManager = DataManager::getDataManagerModelInstance(); m_pDataMD = OCCModeling::GetDataMD(); std::vector data_t; push_undo_redo_data(-1, data_t); LOG_DEBUG("StabilityModel Constructed"); } StabilityModel::~StabilityModel() { DataManager::destroy(); m_pDataManager = nullptr; OCCModeling::ReInitData(); LOG_DEBUG("StabilityModel Destroyed"); } bool StabilityModel::showWindowsLog(QString &log) { if (getDataManagerPtr()) { return getDataManagerPtr()->showWindowsLog(log); } return false; } // log 不能有空格 void StabilityModel::addShowWindowsLog(QString log) { if (getDataManagerPtr()) { getDataManagerPtr()->addShowWindowsLog(log); } } //导入型值表 //横向横剖线 命令集 std::vector& StabilityModel::getTransverseProfile_commad() { return getDataManagerPtr()->getTransverseProfile_commad(); } //梁拱命令 std::vector& StabilityModel::getCamber_commad() { return getDataManagerPtr()->getCamber_commad(); } //绘制纵剖线 std::vector& StabilityModel::getLongitudinalProfile_commad() { return getDataManagerPtr()->getLongitudinalProfile_commad(); } //水线 std::vector& StabilityModel::getWaterLine_commad() { return getDataManagerPtr()->getWaterLine_commad(); } //空间线 std::vector& StabilityModel::getSpaceLine_commad() { return getDataManagerPtr()->getSpaceLine_commad(); } void StabilityModel::setImportOffsetOption(ImportOffsetOption& _option) { return getDataManagerPtr()->setImportOffsetOption(_option); } void StabilityModel::readFile(XMLFile_Type type, const QString &filePath) { LOG_DEBUG("trace"); if (!m_pDataManager) { return; } //type = XMLFile_Type_xls; m_eLoadDataType = type; switch (type) { case XMLFile_Type_csx: { OCCModeling::ReInitData(); m_pDataManager->readFile(type, filePath); ModelData &_modelData = m_pDataManager->getModelData(); // 读取完所有数据后,填充到Map里,为后续Command已有图元查找做准备 _modelData.UpdateModelMaps(); // 更新最大ID,为后续创建新对象做赋ID做准备 _modelData.UpdateMaxID(); // CheckMaxID() 是测试代码,暂时不需要 // _modelData.CheckMaxID(); InitGeometry(); InitHull(); ChangeFSPos::SetSecConvert(&_modelData); } break; case XMLFile_Type_xls: { loadXLSXFile(filePath); //loadXLSXFile("D:/COMPASS-I-F/trunk/doc/TestData/100m.xlsx"); } default: break; } } QString StabilityModel::updateDelete3dToJson(vector& names) { json namelist = nlohmann::json::object(); namelist["name"] = json::array(); // 初始化为空数组 for (auto strName : names) { namelist["name"].push_back(strName); } QString outJsonData = QString::fromStdString(namelist.dump()); return outJsonData; } QString StabilityModel::updateDelete3dToJson(string& name) { json namelist = nlohmann::json::object(); namelist["name"] = json::array(); // 初始化为空数组 namelist["name"].push_back(name); QString outJsonData = QString::fromStdString(namelist.dump()); return outJsonData; } void StabilityModel::update3dToJson(json &outjson,E_GEO_3D_OBJ_TYPE type, int id) { // 读取文件初始默认值给几何相关的信息 if (!outjson.contains("geometry")) { outjson["geometry"] = nlohmann::json::object(); } switch (type) { case E_GEO_3D_OBJ_TYPE_ALL: //0 全量数据传输 LOG_DEBUG("OCC ExportShapeToJSON_nolhmann begin.."); ExportShapeToJSON_nolhmann(outjson); LOG_DEBUG("OCC ExportShapeToJSON_nolhmann end.."); ExportHullToJSON_nolhmann(outjson); break; case E_GEO_3D_OBJ_TYPE_POINT3D: // 1 点数据传输 m_pointByFaceIndex.clear(); if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; if( id != index) { continue; } TopoDS_Shape shape = it->second; ShapeTom_pointByFaceIndex(index, shape); } } for (const auto &[facename, points] : m_pointByFaceIndex) { nlohmann::json pointData; for (const auto &point : points) { pointData["data"].push_back({point.v1[0], point.v1[1], point.v1[2]}); } pointData["attribute"] = ""; pointData["visible"] = points[0].visible; pointData["id"] = points.empty() ? -1 : points[0].id; pointData["color"] = points[0].color; // 追加数据,而不是覆盖 outjson["geometry"]["point"][facename] = pointData; } break; case E_GEO_3D_OBJ_TYPE_CURVE: //2 线数据传输 m_linesByFaceIndex.clear(); if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; if( id != index) { continue; } TopoDS_Shape shape = it->second; ShapeToLineByFaceIndex(index, shape); } } for (const auto &[facename, lines] : m_linesByFaceIndex) { nlohmann::json lineData; lineData["attribute"] = ""; lineData["visible"] = lines[0].visible; lineData["id"] = lines.empty() ? -1 : lines[0].id; lineData["color"] = lines[0].color; // ✅ 追加线数据(不覆盖已有的 pdata、dpdata、src 等字段) for (const auto &line : lines) { for (const auto &val : line.dp) lineData["dpdata"].push_back(val); for (const auto &val : line.src) lineData["src"].push_back(val); } // ✅ 追加线数据 outjson["geometry"]["lines"][facename] = lineData; } break; case E_GEO_3D_OBJ_TYPE_SURFACE: //3 面数据传输 m_trianglesByFaceIndex.clear(); if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; if( id != index) { continue; } TopoDS_Shape shape = it->second; ShapeToTriangleByFaceIndex(index, shape); } } for (const auto &[facename, triangles] : m_trianglesByFaceIndex) { nlohmann::json surfaceData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : triangles) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } surfaceData["data"] = tempData; surfaceData["attribute"] = ""; surfaceData["visible"] = triangles[0].visible; surfaceData["id"] = triangles.empty() ? -1 : triangles[0].id; surfaceData["color"] = triangles[0].color; // ✅ 追加面数据 outjson["geometry"]["surface"][facename] = surfaceData; } break; case E_GEO_3D_OBJ_TYPE_SOLID: //4 体数据传输 m_solidsByFaceIndex.clear(); if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; if( id != index) { continue; } TopoDS_Shape shape = it->second; ShapeToSolidByFaceIndex(index, shape); } } for (const auto &[facename, solids] : m_solidsByFaceIndex) { nlohmann::json solidData; std::vector tempData; // 存储所有坐标数据 for (const auto &solid : solids) { tempData.insert(tempData.end(), {solid.v1[0], solid.v1[1], solid.v1[2], solid.v2[0], solid.v2[1], solid.v2[2], solid.v3[0], solid.v3[1], solid.v3[2]}); } solidData["data"] = tempData; solidData["attribute"] = ""; solidData["visible"] = solids[0].visible; solidData["id"] = solids.empty() ? -1 : solids[0].id; solidData["color"] = solids[0].color; outjson["geometry"]["solid"][facename] = solidData; } break; case E_GEO_3D_OBJ_TYPE_HULL: //5 主船体数据传输 m_mainBodyByFaceIndex.clear(); if (!outjson.contains("hull")) { outjson["hull"] = nlohmann::json::object(); } if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; if( id != index) { continue; } TopoDS_Shape shape = it->second; ShapeTom_mainBodyByFaceIndex(index, shape); } } for (const auto &[facename, mainbody] : m_mainBodyByFaceIndex) { nlohmann::json mainbodyData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : mainbody) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } mainbodyData["data"] = tempData; mainbodyData["attribute"] = ""; mainbodyData["visible"] = mainbody[0].visible; mainbodyData["color"] = mainbody[0].color; mainbodyData["id"] = mainbody.empty() ? -1 : mainbody[0].id; // ✅ 追加面数据 outjson["hull"]["mainbody"][facename] = mainbodyData; } break; case E_GEO_3D_OBJ_TYPE_SPACE: //6 舱室数据传输 m_spaceByFaceIndex.clear(); if (!outjson.contains("hull")) { outjson["hull"] = nlohmann::json::object(); } if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; if( id != index) { continue; } TopoDS_Shape shape = it->second; ShapeTom_spaceByFaceIndex(index, shape); } } for (const auto &[facename, spaces] : m_spaceByFaceIndex) { nlohmann::json spaceData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : spaces) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } spaceData["data"] = tempData; spaceData["attribute"] = ""; spaceData["visible"] = spaces[0].visible; spaceData["color"] = spaces[0].color; spaceData["id"] = spaces.empty() ? -1 : spaces[0].id; // ✅ 追加面数据 if (spaces[0].isunit) { outjson["hull"]["unit"][facename] = spaceData; } else { outjson["hull"]["space"][facename] = spaceData; } } break; case E_GEO_3D_OBJ_TYPE_APPENDAGE: //7 附体数据传输 m_appendageByFaceIndex.clear(); if (!outjson.contains("hull")) { outjson["hull"] = nlohmann::json::object(); } if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; if( id != index) { continue; } TopoDS_Shape shape = it->second; ShapeTom_appendageByFaceIndex(index, shape); } } for (const auto &[facename, appendages] : m_appendageByFaceIndex) { nlohmann::json appendageData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : appendages) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } appendageData["data"] = tempData; appendageData["attribute"] = ""; appendageData["visible"] = appendages[0].visible; appendageData["color"] = appendages[0].color; appendageData["id"] = appendages.empty() ? -1 : appendages[0].id; // ✅ 追加面数据 outjson["hull"]["appendage"][facename] = appendageData; } break; default: break; } if(XMLFile_Type_csx == m_eLoadDataType) { int a = 0; } else if(XMLFile_Type_null == m_eLoadDataType) { } else if(XMLFile_Type_iges == m_eLoadDataType) { modifyOutJson_color(outjson,"color",0xFFFF00); } else if(XMLFile_Type_dxf == m_eLoadDataType) { modifyOutJson_color(outjson,"color",0xFFFF00); } // std::ofstream outFile("D://0430.json", std::ios::out); // if (!outFile.is_open()) return; // outFile << outjson.dump(4) ; // outFile.close(); } void StabilityModel::modifyOutJson_color(json& j, const std::string& key, int new_color_value) { if (j.contains(key)) { j[key] = new_color_value; } // 递归检查并修改嵌套的 color 字段 for (auto& el : j.items()) { if (el.value().is_object()) { modifyOutJson_color(el.value(), key, new_color_value); } } } // 捕获点的选择 void StabilityModel::snap_point(SNAP_POINTS_Type iSelect, int &errorCode, QString &outMsg, QString &data, const QString &message) { m_pDataManager->snap_point(iSelect, errorCode, outMsg, data, message); } std::vector StabilityModel::DiscretePoints(TopoDS_Edge &curve, double dAngle, double dTol) { // m_bOK = true; std::vector listDrawPoints; BRepAdaptor_Curve adaptor(curve); double U1 = adaptor.FirstParameter(); double U2 = adaptor.LastParameter(); const Standard_Integer nbinter = adaptor.NbIntervals(GeomAbs_C1); TColStd_Array1OfReal T(1, nbinter + 1); adaptor.Intervals(T, GeomAbs_C1); Standard_Real theU1, theU2; Standard_Integer NumberOfPoints, i, j; for (j = 1; j <= nbinter; j++) { theU1 = T(j); theU2 = T(j + 1); if (theU2 > U1 && theU1 < U2) { theU1 = (theU1 > U1) ? theU1 : U1; theU2 = (theU2 < U2) ? theU2 : U2; GCPnts_TangentialDeflection Algo(adaptor, theU1, theU2, dAngle, dTol); NumberOfPoints = Algo.NbPoints(); if (NumberOfPoints > 0) { for (i = 1; i <= NumberOfPoints; i++) { listDrawPoints.push_back(Algo.Value(i).X()); listDrawPoints.push_back(Algo.Value(i).Y()); listDrawPoints.push_back(Algo.Value(i).Z()); } } else { // m_bOK = false; } } } return listDrawPoints; } std::vector StabilityModel::DiscretePointsByAngle(Handle_Geom_BSplineCurve &curve, double dAngle, double dTol) { TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve); return DiscretePoints(edge, dAngle, dTol); } bool StabilityModel::ShapeToTriangleByFaceIndex(int &index, TopoDS_Shape &shape) { auto searchname = m_pDataMD->m_mapAllNames.find(index); auto surfacesearch = m_pDataMD->m_mapSurfaces.find(index); if (searchname == m_pDataMD->m_mapAllNames.end() || surfacesearch == m_pDataMD->m_mapSurfaces.end()) { return false; } const std::string &facename = searchname->second; if (facename.empty()) { return false; } int id = surfacesearch->second.ID; Standard_Real aDeflection = 0.05; BRepTools::Clean(shape); BRepMesh_IncrementalMesh(shape, aDeflection); for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next()) { TopoDS_Face F = TopoDS::Face(ex.Current()); BRepMesh_IncrementalMesh(F, aDeflection); TopLoc_Location L; Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); if (facing.IsNull()) continue; const Poly_Array1OfTriangle &triangles = facing->InternalTriangles(); Standard_Integer triLower = triangles.Lower(); Standard_Integer triUpper = triangles.Upper(); std::vector faceTriangles; for (Standard_Integer i = triLower; i <= triUpper; ++i) { Poly_Triangle tri = triangles.Value(i); Standard_Integer index1, index2, index3; tri.Get(index1, index2, index3); // 防止 index 越界访问 Node() if (index1 < 1 || index1 > facing->NbNodes() || index2 < 1 || index2 > facing->NbNodes() || index3 < 1 || index3 > facing->NbNodes()) { qDebug() << "非法三角形索引:" << index1 << index2 << index3; continue; // 跳过非法面,避免崩溃 } gp_Pnt p1 = facing->Node(index1); gp_Pnt p2 = facing->Node(index2); gp_Pnt p3 = facing->Node(index3); Triangle3D triangle; if (F.Orientation() == TopAbs_REVERSED) { triangle.v1 = {p3.X(), p3.Y(), p3.Z()}; triangle.v2 = {p2.X(), p2.Y(), p2.Z()}; triangle.v3 = {p1.X(), p1.Y(), p1.Z()}; } else { triangle.v1 = {p1.X(), p1.Y(), p1.Z()}; triangle.v2 = {p2.X(), p2.Y(), p2.Z()}; triangle.v3 = {p3.X(), p3.Y(), p3.Z()}; } triangle.id = id; triangle.visible = surfacesearch->second.Visible; triangle.color = surfacesearch->second.Color; faceTriangles.push_back(triangle); } if (faceTriangles.empty()) { continue; } m_trianglesByFaceIndex[facename].insert( m_trianglesByFaceIndex[facename].end(), std::make_move_iterator(faceTriangles.begin()), std::make_move_iterator(faceTriangles.end())); } return true; } bool StabilityModel::ShapeToLineByFaceIndex(int &index, TopoDS_Shape &shape) { auto searchname = m_pDataMD->m_mapAllNames.find(index); auto curvesearch = m_pDataMD->m_mapCurves.find(index); if (searchname == m_pDataMD->m_mapAllNames.end() || curvesearch == m_pDataMD->m_mapCurves.end()) { return false; } const std::string &facename = searchname->second; if (facename.empty()) { return false; } int id = curvesearch->second.ID; const auto &srcindex = curvesearch->second.Src; std::vector src; src.reserve(256 * 3); // 预分配最大可能大小,避免 `push_back` 导致的多次扩容 for (int i = 0; i < 256; ++i) { if (srcindex[i] != 0 && srcindex[i] < 100000) { const auto &point = m_pDataMD->m_mapPoints[srcindex[i]]; src.push_back(point.X); src.push_back(point.Y); src.push_back(point.Z); } } for (TopExp_Explorer ex(shape, TopAbs_EDGE); ex.More(); ex.Next()) { TopoDS_Edge E = TopoDS::Edge(ex.Current()); BRepAdaptor_Curve curve(E); Line3D line; line.id = id; line.dp = DiscretePoints(E, 3.1415926535 / 18, 0.001); line.src = std::move(src); // 直接移动 `src` 避免拷贝,提高效率 line.visible = curvesearch->second.Visible; line.color = curvesearch->second.Color; m_linesByFaceIndex[facename].emplace_back(std::move(line)); // 直接 `emplace_back` } return true; } bool StabilityModel::ShapeTom_pointByFaceIndex(int &index, TopoDS_Shape &shape) { auto searchname = m_pDataMD->m_mapAllNames.find(index); auto pointsearch = m_pDataMD->m_mapPoints.find(index); if (searchname == m_pDataMD->m_mapAllNames.end() || pointsearch == m_pDataMD->m_mapPoints.end()) { return false; } int id = pointsearch->second.ID; const std::string &facename = searchname->second; if (facename.empty()) { return false; } for (TopExp_Explorer ex(shape, TopAbs_VERTEX); ex.More(); ex.Next()) { TopoDS_Vertex V = TopoDS::Vertex(ex.Current()); gp_Pnt p = BRep_Tool::Pnt(V); m_Point3D point; point.v1.push_back(p.X()); point.v1.push_back(p.Y()); point.v1.push_back(p.Z()); point.id = id; point.visible = pointsearch->second.Visible; point.color = pointsearch->second.Color; m_pointByFaceIndex[facename].emplace_back(std::move(point)); } return true; } bool StabilityModel::ShapeToSolidByFaceIndex(int &index, TopoDS_Shape &shape) { auto searchname = m_pDataMD->m_mapAllNames.find(index); auto solidsearch = m_pDataMD->m_mapSolids.find(index); if (searchname == m_pDataMD->m_mapAllNames.end() || solidsearch == m_pDataMD->m_mapSolids.end()) { return false; } int id = solidsearch->second.ID; // 输出点数据 const std::string &facename = searchname->second; if (facename.empty()) { return false; } Standard_Real aDeflection = 0.05; BRepTools::Clean(shape); BRepMesh_IncrementalMesh(shape, aDeflection); for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next()) { TopoDS_Face F = TopoDS::Face(ex.Current()); BRepMesh_IncrementalMesh(F, aDeflection); TopLoc_Location L; Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); if (facing.IsNull()) continue; const Poly_Array1OfTriangle &triangles = facing->InternalTriangles(); Standard_Integer triLower = triangles.Lower(); Standard_Integer triUpper = triangles.Upper(); std::vector faceSolids; for (Standard_Integer i = triLower; i <= triUpper; ++i) { Poly_Triangle tri = triangles.Value(i); Standard_Integer index1, index2, index3; tri.Get(index1, index2, index3); // 防止 index 越界访问 Node() if (index1 < 1 || index1 > facing->NbNodes() || index2 < 1 || index2 > facing->NbNodes() || index3 < 1 || index3 > facing->NbNodes()) { qDebug() << "非法三角形索引:" << index1 << index2 << index3; continue; // 跳过非法面,避免崩溃 } gp_Pnt p1 = facing->Node(index1); gp_Pnt p2 = facing->Node(index2); gp_Pnt p3 = facing->Node(index3); m_Solid solid; if (F.Orientation() == TopAbs_REVERSED) { solid.v1 = {p3.X(), p3.Y(), p3.Z()}; solid.v2 = {p2.X(), p2.Y(), p2.Z()}; solid.v3 = {p1.X(), p1.Y(), p1.Z()}; } else { solid.v1 = {p1.X(), p1.Y(), p1.Z()}; solid.v2 = {p2.X(), p2.Y(), p2.Z()}; solid.v3 = {p3.X(), p3.Y(), p3.Z()}; } solid.id = id; solid.visible = solidsearch->second.Visible; solid.color = solidsearch->second.Color; faceSolids.push_back(solid); } m_solidsByFaceIndex[facename].insert( m_solidsByFaceIndex[facename].end(), std::make_move_iterator(faceSolids.begin()), std::make_move_iterator(faceSolids.end())); } return true; } bool StabilityModel::ShapeTom_mainBodyByFaceIndex(int &index, TopoDS_Shape &shape) { auto searchname = m_pDataMD->m_mapAllNames.find(index); auto hullsearch = m_pDataMD->m_mapHull.find(index); if (searchname == m_pDataMD->m_mapAllNames.end() || hullsearch == m_pDataMD->m_mapHull.end()) { return false; } int id = hullsearch->second.ID; // 输出点数据 const std::string &facename = searchname->second; if (facename.empty()) { return false; } Standard_Real aDeflection = 0.05; BRepTools::Clean(shape); BRepMesh_IncrementalMesh(shape, aDeflection); for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next()) { TopoDS_Face F = TopoDS::Face(ex.Current()); BRepMesh_IncrementalMesh(F, aDeflection); TopLoc_Location L; Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); if (facing.IsNull()) continue; const Poly_Array1OfTriangle &triangles = facing->InternalTriangles(); Standard_Integer triLower = triangles.Lower(); Standard_Integer triUpper = triangles.Upper(); std::vector faceMainBody; for (Standard_Integer i = triLower; i <= triUpper; ++i) { Poly_Triangle tri = triangles.Value(i); Standard_Integer index1, index2, index3; tri.Get(index1, index2, index3); // 防止 index 越界访问 Node() if (index1 < 1 || index1 > facing->NbNodes() || index2 < 1 || index2 > facing->NbNodes() || index3 < 1 || index3 > facing->NbNodes()) { qDebug() << "非法三角形索引:" << index1 << index2 << index3; continue; // 跳过非法面,避免崩溃 } gp_Pnt p1 = facing->Node(index1); gp_Pnt p2 = facing->Node(index2); gp_Pnt p3 = facing->Node(index3); m_mainbody mainbody; if (F.Orientation() == TopAbs_REVERSED) { mainbody.v1 = {p3.X(), p3.Y(), p3.Z()}; mainbody.v2 = {p2.X(), p2.Y(), p2.Z()}; mainbody.v3 = {p1.X(), p1.Y(), p1.Z()}; } else { mainbody.v1 = {p1.X(), p1.Y(), p1.Z()}; mainbody.v2 = {p2.X(), p2.Y(), p2.Z()}; mainbody.v3 = {p3.X(), p3.Y(), p3.Z()}; } mainbody.id = id; mainbody.visible = hullsearch->second.Visible; mainbody.color = hullsearch->second.Color; faceMainBody.push_back(mainbody); } m_mainBodyByFaceIndex[facename].insert( m_mainBodyByFaceIndex[facename].end(), std::make_move_iterator(faceMainBody.begin()), std::make_move_iterator(faceMainBody.end())); } return true; } bool StabilityModel::ShapeTom_spaceByFaceIndex(int &index, TopoDS_Shape &shape) { auto searchname = m_pDataMD->m_mapAllNames.find(index); auto spacesearch = m_pDataMD->m_mapSpace.find(index); if (searchname == m_pDataMD->m_mapAllNames.end() || spacesearch == m_pDataMD->m_mapSpace.end()) { return false; } int id = spacesearch->second.ID; // 输出点数据 const std::string &facename = searchname->second; if (facename.empty()) { return false; } Standard_Real aDeflection = 0.05; BRepTools::Clean(shape); BRepMesh_IncrementalMesh(shape, aDeflection); for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next()) { TopoDS_Face F = TopoDS::Face(ex.Current()); BRepMesh_IncrementalMesh(F, aDeflection); TopLoc_Location L; Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); if (facing.IsNull()) continue; const Poly_Array1OfTriangle &triangles = facing->InternalTriangles(); Standard_Integer triLower = triangles.Lower(); Standard_Integer triUpper = triangles.Upper(); std::vector faceSpace; for (Standard_Integer i = triLower; i <= triUpper; ++i) { Poly_Triangle tri = triangles.Value(i); Standard_Integer index1, index2, index3; tri.Get(index1, index2, index3); // 防止 index 越界访问 Node() if (index1 < 1 || index1 > facing->NbNodes() || index2 < 1 || index2 > facing->NbNodes() || index3 < 1 || index3 > facing->NbNodes()) { qDebug() << "非法三角形索引:" << index1 << index2 << index3; continue; // 跳过非法面,避免崩溃 } gp_Pnt p1 = facing->Node(index1); gp_Pnt p2 = facing->Node(index2); gp_Pnt p3 = facing->Node(index3); m_space space; if (F.Orientation() == TopAbs_REVERSED) { space.v1 = {p3.X(), p3.Y(), p3.Z()}; space.v2 = {p2.X(), p2.Y(), p2.Z()}; space.v3 = {p1.X(), p1.Y(), p1.Z()}; } else { space.v1 = {p1.X(), p1.Y(), p1.Z()}; space.v2 = {p2.X(), p2.Y(), p2.Z()}; space.v3 = {p3.X(), p3.Y(), p3.Z()}; } space.id = id; space.visible = spacesearch->second.Visible; space.isunit = spacesearch->second.isUnit; space.color = spacesearch->second.Color; faceSpace.push_back(space); } m_spaceByFaceIndex[facename].insert( m_spaceByFaceIndex[facename].end(), std::make_move_iterator(faceSpace.begin()), std::make_move_iterator(faceSpace.end())); } return true; } bool StabilityModel::ShapeTom_appendageByFaceIndex(int &index, TopoDS_Shape &shape) { auto searchname = m_pDataMD->m_mapAllNames.find(index); auto appendagesearch = m_pDataMD->m_mapAppendage.find(index); if (searchname == m_pDataMD->m_mapAllNames.end() || appendagesearch == m_pDataMD->m_mapAppendage.end()) { return false; } int id = appendagesearch->second.ID; // 输出点数据 const std::string &facename = searchname->second; if (facename.empty()) { return false; } Standard_Real aDeflection = 0.05; BRepTools::Clean(shape); BRepMesh_IncrementalMesh(shape, aDeflection); for (TopExp_Explorer ex(shape, TopAbs_FACE); ex.More(); ex.Next()) { TopoDS_Face F = TopoDS::Face(ex.Current()); BRepMesh_IncrementalMesh(F, aDeflection); TopLoc_Location L; Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L); if (facing.IsNull()) continue; const Poly_Array1OfTriangle &triangles = facing->InternalTriangles(); Standard_Integer triLower = triangles.Lower(); Standard_Integer triUpper = triangles.Upper(); std::vector faceAppendage; for (Standard_Integer i = triLower; i <= triUpper; ++i) { Poly_Triangle tri = triangles.Value(i); Standard_Integer index1, index2, index3; tri.Get(index1, index2, index3); // 防止 index 越界访问 Node() if (index1 < 1 || index1 > facing->NbNodes() || index2 < 1 || index2 > facing->NbNodes() || index3 < 1 || index3 > facing->NbNodes()) { qDebug() << "非法三角形索引:" << index1 << index2 << index3; continue; // 跳过非法面,避免崩溃 } m_Appendage appendage; gp_Pnt p1 = facing->Node(index1); gp_Pnt p2 = facing->Node(index2); gp_Pnt p3 = facing->Node(index3); if (F.Orientation() == TopAbs_REVERSED) { appendage.v1 = {p3.X(), p3.Y(), p3.Z()}; appendage.v2 = {p2.X(), p2.Y(), p2.Z()}; appendage.v3 = {p1.X(), p1.Y(), p1.Z()}; } else { appendage.v1 = {p1.X(), p1.Y(), p1.Z()}; appendage.v2 = {p2.X(), p2.Y(), p2.Z()}; appendage.v3 = {p3.X(), p3.Y(), p3.Z()}; } appendage.id = id; appendage.visible = appendagesearch->second.Visible; appendage.color = appendagesearch->second.Color; faceAppendage.push_back(appendage); } m_appendageByFaceIndex[facename].insert( m_appendageByFaceIndex[facename].end(), std::make_move_iterator(faceAppendage.begin()), std::make_move_iterator(faceAppendage.end())); } return true; } void StabilityModel::ExportShapeToJSON_nolhmann(nlohmann::json &jsonOutput) { m_trianglesByFaceIndex.clear(); m_linesByFaceIndex.clear(); m_pointByFaceIndex.clear(); m_solidsByFaceIndex.clear(); if (!jsonOutput.contains("geometry")) { jsonOutput["geometry"] = nlohmann::json::object(); } if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; TopoDS_Shape shape = it->second; if (ShapeTom_pointByFaceIndex(index, shape) || ShapeToLineByFaceIndex(index, shape) || ShapeToTriangleByFaceIndex(index, shape) || ShapeToSolidByFaceIndex(index, shape)) { continue; } } } for (const auto &[facename, points] : m_pointByFaceIndex) { nlohmann::json pointData; for (const auto &point : points) { pointData["data"].push_back({point.v1[0], point.v1[1], point.v1[2]}); } pointData["attribute"] = ""; pointData["visible"] = points[0].visible; pointData["id"] = points.empty() ? -1 : points[0].id; pointData["color"] = points[0].color; // 追加数据,而不是覆盖 jsonOutput["geometry"]["point"][facename] = pointData; } for (const auto &[facename, lines] : m_linesByFaceIndex) { nlohmann::json lineData; lineData["attribute"] = ""; lineData["visible"] = lines[0].visible; lineData["id"] = lines.empty() ? -1 : lines[0].id; lineData["color"] = lines[0].color; // ✅ 追加线数据(不覆盖已有的 pdata、dpdata、src 等字段) for (const auto &line : lines) { for (const auto &val : line.dp) lineData["dpdata"].push_back(val); for (const auto &val : line.src) lineData["src"].push_back(val); } // ✅ 追加线数据 jsonOutput["geometry"]["lines"][facename] = lineData; } for (const auto &[facename, triangles] : m_trianglesByFaceIndex) { nlohmann::json surfaceData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : triangles) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } surfaceData["data"] = tempData; surfaceData["attribute"] = ""; surfaceData["visible"] = triangles[0].visible; surfaceData["id"] = triangles.empty() ? -1 : triangles[0].id; surfaceData["color"] = triangles[0].color; // ✅ 追加面数据 jsonOutput["geometry"]["surface"][facename] = surfaceData; } // 体数据(示例) for (const auto &[facename, solids] : m_solidsByFaceIndex) { nlohmann::json solidData; std::vector tempData; // 存储所有坐标数据 for (const auto &solid : solids) { tempData.insert(tempData.end(), {solid.v1[0], solid.v1[1], solid.v1[2], solid.v2[0], solid.v2[1], solid.v2[2], solid.v3[0], solid.v3[1], solid.v3[2]}); } solidData["data"] = tempData; solidData["attribute"] = ""; solidData["visible"] = solids[0].visible; solidData["color"] = solids[0].color; solidData["id"] = solids.empty() ? -1 : solids[0].id; jsonOutput["geometry"]["solid"][facename] = solidData; } // std::ofstream outFile("D://0417.json", std::ios::out); // if (!outFile.is_open()) // { // return ; // } // outFile << jsonOutput.dump(4) ; // outFile.close(); return; } void StabilityModel::ExportHullToJSON_nolhmann(nlohmann::json &jsonOutput) { m_mainBodyByFaceIndex.clear(); m_spaceByFaceIndex.clear(); m_appendageByFaceIndex.clear(); jsonOutput["hull"] = nlohmann::json::object(); if (m_pDataMD->m_mapAllTopoShapes.size() > 0) { map::iterator it; for (it = m_pDataMD->m_mapAllTopoShapes.begin(); it != m_pDataMD->m_mapAllTopoShapes.end(); ++it) { int index = it->first; TopoDS_Shape shape = it->second; if (ShapeTom_mainBodyByFaceIndex(index, shape) || ShapeTom_spaceByFaceIndex(index, shape) || ShapeTom_appendageByFaceIndex(index, shape)) { continue; } } } for (const auto &[facename, mainbody] : m_mainBodyByFaceIndex) { nlohmann::json mainbodyData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : mainbody) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } mainbodyData["data"] = tempData; mainbodyData["attribute"] = ""; mainbodyData["visible"] = mainbody[0].visible; mainbodyData["color"] = mainbody[0].color; mainbodyData["id"] = mainbody.empty() ? -1 : mainbody[0].id; // ✅ 追加面数据 jsonOutput["hull"]["mainbody"][facename] = mainbodyData; } for (const auto &[facename, spaces] : m_spaceByFaceIndex) { nlohmann::json spaceData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : spaces) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } spaceData["data"] = tempData; spaceData["attribute"] = ""; spaceData["visible"] = spaces[0].visible; spaceData["color"] = spaces[0].color; spaceData["id"] = spaces.empty() ? -1 : spaces[0].id; // ✅ 追加面数据 if (spaces[0].isunit) { jsonOutput["hull"]["unit"][facename] = spaceData; } else { jsonOutput["hull"]["space"][facename] = spaceData; } } for (const auto &[facename, appendages] : m_appendageByFaceIndex) { nlohmann::json appendageData; std::vector tempData; // 存储所有坐标数据 for (const auto &tri : appendages) { tempData.insert(tempData.end(), {tri.v1[0], tri.v1[1], tri.v1[2], tri.v2[0], tri.v2[1], tri.v2[2], tri.v3[0], tri.v3[1], tri.v3[2]}); } appendageData["data"] = tempData; appendageData["attribute"] = ""; appendageData["visible"] = appendages[0].visible; appendageData["color"] = appendages[0].color; appendageData["id"] = appendages.empty() ? -1 : appendages[0].id; // ✅ 追加面数据 jsonOutput["hull"]["appendage"][facename] = appendageData; } // std::ofstream outFile("D://0424.json", std::ios::out); // if (!outFile.is_open()) // { // return jsonOutput; // } // outFile << jsonOutput.dump(4) ; // outFile.close(); return; } std::string StabilityModel::CurveTypeToString(GeomAbs_CurveType type) { switch (type) { case GeomAbs_Line: return "Line"; case GeomAbs_Circle: return "Circle"; case GeomAbs_Ellipse: return "Ellipse"; case GeomAbs_Hyperbola: return "Hyperbola"; case GeomAbs_Parabola: return "Parabola"; case GeomAbs_BezierCurve: return "BezierCurve"; case GeomAbs_BSplineCurve: return "BSplineCurve"; case GeomAbs_OtherCurve: return "OtherCurve"; default: return "Unknown"; } } void StabilityModel::saveFile(QString &savefilePath) { m_pDataManager->saveFile(savefilePath); } bool StabilityModel::create_point(std::string& singlecmdstring, QString &outJsonData) { m_eLoadDataType = XMLFile_Type_null; int errorCode = 0; QString strLog = ""; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->create_point(commandLines,strLog); if(errorCode) { strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } // const std::vector ids = m_pDataManager->getCurrentOperationId(); // json outjson; // outjson["geometry"] = nlohmann::json::object(); // for( auto id : ids) // { // update3dToJson(outjson, e_modeling_operate_POINT , id); // } // outJsonData = QString::fromStdString(outjson.dump(4)); outJsonData = getUpdate3dToJson(); strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::create_line(std::string& singlecmdstring, QString &outJsonData) { m_eLoadDataType = XMLFile_Type_null; int errorCode = 0; QString strLog = ""; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->create_line(commandLines,strLog); if(errorCode) { strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } const std::vector ids = m_pDataManager->getCurrentOperationId(); if(ids.size() < 1) { strLog += "创建失败" + PathUtil::getEndMark(); strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } json outjson; update3dToJson(outjson, E_GEO_3D_OBJ_TYPE_CURVE , ids[0]); outJsonData = QString::fromStdString(outjson.dump(4)); strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::create_surface(std::string& singlecmdstring, QString &outJsonData) { m_eLoadDataType = XMLFile_Type_null; int errorCode = 0; QString strLog = ""; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->create_surface(commandLines, strLog); if(errorCode) { strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } const std::vector ids = m_pDataManager->getCurrentOperationId(); if(ids.size() < 1) { strLog += "创建失败"; strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } json outjson; update3dToJson(outjson, E_GEO_3D_OBJ_TYPE_SURFACE, ids[0]); outJsonData = QString::fromStdString(outjson.dump(4)); strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::create_solid(std::string& singlecmdstring, QString &outJsonData) { m_eLoadDataType = XMLFile_Type_null; int errorCode = 0; QString strLog = ""; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->create_solid(commandLines, strLog); if(errorCode) { strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } const std::vector ids = m_pDataManager->getCurrentOperationId(); if(ids.size() < 1) { errorCode = 1; strLog += "创建失败"; strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } json outjson; update3dToJson(outjson, E_GEO_3D_OBJ_TYPE_SOLID, ids[0]); outJsonData = QString::fromStdString(outjson.dump(4)); strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::create_Hull(std::string& singlecmdstring, QString &outJsonData) { m_eLoadDataType = XMLFile_Type_null; QString strLog = ""; int errorCode = 0; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->create_Hull(commandLines,strLog); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } const std::vector ids = m_pDataManager->getCurrentOperationId(); if(ids.size() < 1) { strLog += "创建失败" + PathUtil::getEndMark(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } json outjson; update3dToJson(outjson, E_GEO_3D_OBJ_TYPE_HULL, ids[0]); outJsonData = QString::fromStdString(outjson.dump(4)); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::create_unit_and_space(std::string& singlecmdstring, QString &outJsonData) { m_eLoadDataType = XMLFile_Type_null; int errorCode = 0; QString strLog = ""; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->create_unit_and_space(commandLines,strLog); if(errorCode) { strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } const std::vector ids = m_pDataManager->getCurrentOperationId(); if(ids.size() < 1) { strLog += "创建失败" + PathUtil::getEndMark(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } json outjson; update3dToJson(outjson, E_GEO_3D_OBJ_TYPE_SPACE, ids[0]); outJsonData = QString::fromStdString(outjson.dump(4)); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::create_Appendage(std::string& singlecmdstring, QString &outJsonData) { m_eLoadDataType = XMLFile_Type_null; QString strLog = ""; int errorCode = 0; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->create_Appendage(commandLines, strLog); if(errorCode) { strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } const std::vector ids = m_pDataManager->getCurrentOperationId(); if(ids.size() < 1) { strLog += "创建失败" + PathUtil::getEndMark(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } json outjson; update3dToJson(outjson, E_GEO_3D_OBJ_TYPE_APPENDAGE, ids[0]); outJsonData = QString::fromStdString(outjson.dump(4)); strLog += PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } void StabilityModel::from(int &errorCode, QString &outMsg, QString &data, const QString &message) { } bool StabilityModel::setObjVisible(std::string& singlecmdstring, QString &outJsonData) { QString strLog = ""; int errorCode = 0; vector commandLines = CommandStreamProcessing::SplitCommand(singlecmdstring); strLog +=QString::fromStdString(singlecmdstring); bool bRet = m_pDataManager->setObjVisible(commandLines); if(bRet) { strLog += "命令执行成功" + PathUtil::getEndMark(); } else { strLog += "命令执行失败" + PathUtil::getEndMark(); } strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); outJsonData = getUpdate3dToJson(); // const std::vector ids = m_pDataManager->getCurrentOperationId(); // json outjson; // outjson["geometry"] = nlohmann::json::object(); // for( auto id : ids) // { // e_modeling_type type = CommandStreamProcessing::getObjTypeById(id); // update3dToJson(outjson, type , id); // } // outJsonData = QString::fromStdString(outjson.dump(4)); return bRet; } QString StabilityModel::getUpdate3dToJson(std::vector& ids) { json outjson; outjson["geometry"] = nlohmann::json::object(); for (auto id : ids) { E_GEO_3D_OBJ_TYPE type = CommandStreamProcessing::getObjTypeById(id); update3dToJson(outjson, type, id); } QString outJsonData = QString::fromStdString(outjson.dump(4)); return outJsonData; } QString StabilityModel::getUpdate3dToJson() { const std::vector ids = m_pDataManager->getCurrentOperationId(); json outjson; outjson["geometry"] = nlohmann::json::object(); for( auto id : ids) { E_GEO_3D_OBJ_TYPE type = CommandStreamProcessing::getObjTypeById(id); update3dToJson(outjson, type , id); } QString outJsonData = QString::fromStdString(outjson.dump(4)); return outJsonData; } QString StabilityModel::getUpdate_UI_StateJson() { if (!m_pDataManager) { return ""; } json outjson = nlohmann::json::object(); json undo_redo_startjson = nlohmann::json::object(); undo_redo_startjson["undo"] = (int)m_pDataManager->isCanUndo(); undo_redo_startjson["redo"] = (int)m_pDataManager->isCanRedo(); outjson["cmd_update_undo_redo_ui_state"] = undo_redo_startjson; QString outJsonData = QString::fromStdString(outjson.dump(4)); return outJsonData; } //bool StabilityModel::setObjVisible(int id,int value) //{ // return m_pDataManager->setObjVisible(id,value); //} void StabilityModel::stab_model_editor_hydro_static(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_hydro_static(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_tank_cap(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_tank_cap(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_intact(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_intact(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_allow_kg(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_allow_kg(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_damage(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_damage(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_damage_prob(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_damage_prob(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_inclining(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_inclining(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_check(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_check(errorCode, outMsg, data, message); } void StabilityModel::stab_model_editor_save(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->stab_model_editor_save(errorCode, outMsg, data, message); } void StabilityModel::InitGeometry() { ModelData &_modelData = m_pDataManager->getModelData(); std::vector> &mPointData = _modelData.getPoint3DModel(); std::vector> &mCurveData = _modelData.getCurveModle(); std::vector> &mSurfaceData = _modelData.getSurfaces(); std::vector> &mSolidData = _modelData.getSolids(); // 读取完所有数据后,填充到Map里,为后续Command已有图元查找做准备 vector vPoint3d; vector vCur; vector vSur; vector vSol; auto itPoint = mPointData.begin(); for (; itPoint != mPointData.end(); ++itPoint) { Point3D pd = itPoint->second.getGeoPoint(); vPoint3d.emplace_back(pd); } auto itCurve = mCurveData.begin(); for (; itCurve != mCurveData.end(); ++itCurve) { Curve cur = itCurve->second.getGeoCurve(); vCur.emplace_back(cur); } auto itSurface = mSurfaceData.begin(); for (; itSurface != mSurfaceData.end(); ++itSurface) { Surface sur = itSurface->second.getGeoSurface(); vSur.emplace_back(sur); } auto itSolid = mSolidData.begin(); for (; itSolid != mSolidData.end(); ++itSolid) { Solid sol = itSolid->second.getGeoSolid(); vSol.emplace_back(sol); } LOG_DEBUG("OCC InitData begin.."); OCCModeling::InitData(vPoint3d, vCur, vSur, vSol); LOG_DEBUG("OCC InitData end.."); // auto itp = vPoint3d.begin(); // for (; itp != vPoint3d.end(); ++itp) // { // itp->clear(); // } // auto itc = vCur.begin(); // for (; itc != vCur.end(); ++itc) // { // itc->clear(); // } } void StabilityModel::InitHull() { ModelData &_modelData = m_pDataManager->getModelData(); std::vector> m_Hulls = _modelData.getHulls(); std::vector> m_Spaces = _modelData.getSpaces(); std::vector> m_Appendages = _modelData.getAppendages(); vector vHull; vector vSpace; vector vAppendage; auto itH = m_Hulls.begin(); for (; itH != m_Hulls.end(); ++itH) { Hull hull = itH->second.getGeoHull(); vHull.emplace_back(hull); } auto itS = m_Spaces.begin(); for (; itS != m_Spaces.end(); ++itS) { Space space = itS->second.getGeoSpace(); vSpace.emplace_back(space); } auto itA = m_Appendages.begin(); for (; itA != m_Appendages.end(); ++itA) { Appendage appendage = itA->second.getGeoAppendage(); vAppendage.emplace_back(appendage); } LOG_DEBUG("OCC InitData HULL begin.."); OCCModeling::InitHullData(vHull, vSpace, vAppendage); LOG_DEBUG("OCC InitData HULL end.."); } void StabilityModel::analysis_show_tree(int &errorCode, QString &outMsg, QString &data, const QString &message) { // DataManager处理,通过 m_pDataManager->analysis_show_tree(errorCode, outMsg, data, message); } void StabilityModel::hull_show_tree(int &errorCode, QString &outMsg, QString &data, const QString &message) { json outjson; ExportHullToJSON_nolhmann(outjson); data = QString::fromStdString(outjson.dump(4)); errorCode = 0; outMsg = "Hull tree data exported successfully."; } long StabilityModel::ImportIGES(const json &j) { long lRet = 0; // if(j.contains("file_menu_import_iges_ok")) // { const json& file_menu_import_iges_ok = j; std::string filepath = PathUtil::jsonContainsKeyToString(file_menu_import_iges_ok,"file_path"); int i_check_box_pnt = PathUtil::jsonContainsKeyToInt(file_menu_import_iges_ok,"check_box_pnt"); int i_check_box_curve = PathUtil::jsonContainsKeyToInt(file_menu_import_iges_ok,"check_box_curve"); int i_check_box_face = PathUtil::jsonContainsKeyToInt(file_menu_import_iges_ok,"check_box_face"); int i_check_box_solid = PathUtil::jsonContainsKeyToInt(file_menu_import_iges_ok,"check_box_solid"); int impType = 0; if(i_check_box_pnt) { impType |= 0x01; } if(i_check_box_curve) { impType |= 0x02; } if(i_check_box_face) { impType |= 0x04; } double d_text_box_scale = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"text_box_scale"); double d_text_box_translate_x = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"text_box_translate_x"); double d_text_box_translate_y = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"text_box_translate_y"); double d_text_box_translate_z = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"text_box_translate_z"); double d_text_box_rotate_x = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"text_box_rotate_x"); double d_text_box_rotate_y = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"text_box_rotate_y"); double d_text_box_rotate_z = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"text_box_rotate_z"); vector vTransfromParams; // vTransfromParams.emplace_back(1); // vTransfromParams.emplace_back(0); // vTransfromParams.emplace_back(0); // vTransfromParams.emplace_back(0); // vTransfromParams.emplace_back(0); // vTransfromParams.emplace_back(0); // vTransfromParams.emplace_back(0); vTransfromParams.emplace_back(d_text_box_scale); vTransfromParams.emplace_back(d_text_box_translate_x); vTransfromParams.emplace_back(d_text_box_translate_y); vTransfromParams.emplace_back(d_text_box_translate_z); vTransfromParams.emplace_back(d_text_box_rotate_x); vTransfromParams.emplace_back(d_text_box_rotate_y); vTransfromParams.emplace_back(d_text_box_rotate_z); int i_radio_button_add = PathUtil::jsonContainsKeyToDouble(file_menu_import_iges_ok,"radio_button_add"); // std::string filepath = "D:/内河/内河2025/COMPASS2023/bin/Data/XF/40.igs"; // int impType = 7; // int i_radio_button_add = 1; lRet = ImportIGES(filepath,impType,vTransfromParams,(bool)i_radio_button_add); //} return lRet; } long StabilityModel::ImportIGES(std::string fileName, int impType, vector vTransfromParams, bool bIsAddMode) { if (vTransfromParams.size() != 7) { return 0; } m_eLoadDataType = XMLFile_Type_iges; const char *cstr = fileName.c_str(); // 返回 const char* // 如果需要 char*,可以做一个复制 char *modifiableCStr = new char[fileName.length() + 1]; std::strcpy(modifiableCStr, cstr); // 复制内容到新的 char* 数组 OCCModeling::ReInitData(); float transfromParams[7] = {0}; transfromParams[0] = vTransfromParams[0]; transfromParams[1] = vTransfromParams[1]; transfromParams[2] = vTransfromParams[2]; transfromParams[3] = vTransfromParams[3]; transfromParams[4] = vTransfromParams[4]; transfromParams[5] = vTransfromParams[5]; transfromParams[6] = vTransfromParams[6]; long ret = OCCModeling::ImportIGES(modifiableCStr, impType, transfromParams); delete[] modifiableCStr; return ret; } void StabilityModel::ExportIGES(const json &j) { long lRet = 0; // if (j.contains("file_menu_export_iges_ok")) // { const json &file_menu_export_iges_ok = j; std::string fileName = PathUtil::jsonContainsKeyToString(file_menu_export_iges_ok, "file_path"); int i_check_box_pnt = PathUtil::jsonContainsKeyToInt(file_menu_export_iges_ok, "check_box_pnt"); int i_check_box_curve = PathUtil::jsonContainsKeyToInt(file_menu_export_iges_ok, "check_box_curve"); int i_check_box_face = PathUtil::jsonContainsKeyToInt(file_menu_export_iges_ok, "check_box_face"); int i_check_box_solid = PathUtil::jsonContainsKeyToInt(file_menu_export_iges_ok, "check_box_solid"); int i_radio_button = PathUtil::jsonContainsKeyToInt(file_menu_export_iges_ok, "radio_button"); int i_selectedCnt = 3;//PathUtil::jsonContainsKeyToInt(file_menu_export_iges_ok, "selected_cnt"); int expOpt = 0x00; if (i_check_box_pnt) { expOpt |= 0x01; } if (i_check_box_curve) { expOpt |= 0x02; } if (i_check_box_face) { expOpt |= 0x04; } if (i_check_box_solid) { expOpt |= 0x08; } if (i_radio_button == 0) { expOpt |= 0x10; } else if (i_radio_button == 1) { expOpt |= 0x20; } else if (i_radio_button == 2) { expOpt |= 0x40; } int *selectLst = new int[i_selectedCnt]; const json &selectIDs = file_menu_export_iges_ok["selectIDs"]; if (selectIDs.is_array() && i_selectedCnt == selectIDs.size()) { int ik = 0; for (const auto &id : selectIDs) { selectLst[ik] = id; } } const char *cstr = fileName.c_str(); // 返回 const char* // 如果需要 char*,可以做一个复制 char *modifiableCStr = new char[fileName.length() + 1]; std::strcpy(modifiableCStr, cstr); // 复制内容到新的 char* 数组 OCCModeling::ExportIGES(modifiableCStr, expOpt, i_selectedCnt, selectLst); delete[] modifiableCStr; delete[] selectLst; //} } void StabilityModel::ImportDXF(QString filePath) { long lRet = 0; m_eLoadDataType = XMLFile_Type_dxf; QByteArray byteArray = filePath.toUtf8(); // 将QString转换为UTF-8的QByteArray const char* constCharPtr = byteArray.constData(); // 获取常量指针 // 如果你需要一个非const的char*,你可以复制数据到一个新的数组中 char* charPtr = new char[byteArray.size() + 1]; // 为null结尾符号分配空间 std::strcpy(charPtr, constCharPtr); // 复制数据 OCCModeling::ImportCAD(charPtr); int a = 0; delete[] charPtr; } bool StabilityModel::cmd_copy(std::string& singlecmdstring, QString &outJsonData) { // 适用对象:ALL int errorCode = 0; QString strLog = ""; strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->cmd_copy(singlecmdstring,strLog); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } const std::vector ids = m_pDataManager->getCurrentOperationId(); if(ids.size() < 1) { strLog += "创建失败" + PathUtil::getEndMark(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } outJsonData = getUpdate3dToJson(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::cmd_trim(std::string& singlecmdstring, QString &outJsonData) { // 适用对象:线、面 int errorCode = 0; QString strLog = ""; strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->cmd_trim(singlecmdstring,strLog); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } outJsonData = getUpdate3dToJson(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::cmd_mirror(std::string& singlecmdstring, QString &outJsonData) { // 适用对象:所有图元 int errorCode = 0; QString strLog = ""; strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->cmd_mirror(singlecmdstring,strLog); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } outJsonData = getUpdate3dToJson(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::cmd_intersection(std::string& singlecmdstring, QString &outJsonData) { // 适用对象:面 int errorCode = 0; QString strLog = ""; strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->cmd_intersection(singlecmdstring,strLog); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } outJsonData = getUpdate3dToJson(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::cmd_join(std::string& singlecmdstring, QString &outJsonData) { // 适用对象:线、面 int errorCode = 0; QString strLog = ""; strLog +=QString::fromStdString(singlecmdstring); m_pDataManager->cmd_join(singlecmdstring,strLog); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } outJsonData = getUpdate3dToJson(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::cmd_delete(std::string& singlecmdstring, QString &outJsonData) { // 适用对象:所有图元 int id = -1; int type = 0; int errorCode = 0; QString strLog = ""; strLog +=QString::fromStdString(singlecmdstring); std::vector vDeleteObjName; errorCode = m_pDataManager->cmd_delete(singlecmdstring,strLog,vDeleteObjName); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } outJsonData = updateDelete3dToJson(vDeleteObjName); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } //bool StabilityModel::cmd_delete(std::string& singlecmdstring, QString& outJsonData) bool StabilityModel::cmd_tool_show_obj_command(std::string& singlecmdstring, QString &outJsonData) { int errorCode = 0; QString strLog = ""; strLog +=QString::fromStdString(singlecmdstring); errorCode = m_pDataManager->cmd_tool_show_obj_command(singlecmdstring,strLog); if(errorCode) { strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return false; } strLog +="命令执行成功" + PathUtil::getEndMark(); strLog +=PathUtil::getLogEndLine(); addShowWindowsLog(strLog); return true; } bool StabilityModel::Menu_toolbar_show_obj_infor_XYZ(std::vector& ids,QString& outStr ) //获取obj XYZ infor { if(ids.size() == 0) { return false; } QString strcmd = ""; for (size_t i = 0; i < ids.size(); i++) { std::string obName = ids[i]; IModel *pObj = DataManager::GetObjectByName(obName); if (!pObj) { continue; } if(pObj->GetCommand().isEmpty()) { continue; } int objid = pObj->GetID(); strcmd += pObj->GetName() + PathUtil::getEndMark(); // 分割命令行 QString allCommandLine = pObj->GetCommand().trimmed(); QStringList commandLines = allCommandLine.split(PathUtil::getEndMark()); if(commandLines.size() < 2) { continue; } else { QString SSS = commandLines[1]; QString command = commandLines[1].trimmed(); // 使用 trimmed() 去除空格 // 查找空格的位置 int index = command.indexOf(' '); if (index == -1) { } else { QString ss = commandLines[1].left(index); // Extract substring ss = ss.toUpper(); // Convert to uppercase QString tmp = ""; QString tmpPos = ""; QString commandFirstLine = commandLines[0]; commandFirstLine = commandFirstLine.toUpper(); // Convert to uppercase if (commandFirstLine.startsWith("POINT")) { // Point3D p = GetPointByID(1); // Replace with real logic for point retrieval if(pObj->getObjType() == E_GEO_3D_OBJ_TYPE_POINT3D) { Point3D_M* p = (Point3D_M*)pObj; tmp += QString::number(p->m_X) + "," + QString::number(p->m_Y) + "," + QString::number(p->m_Z) + PathUtil::getEndMark(); } } else if (commandFirstLine.startsWith("CURVE") || commandFirstLine.startsWith("ELLIPSE") || commandFirstLine.startsWith("PARABOLA")) { Curve_M* crv = (Curve_M*)pObj;; if (ss == "X") { for (size_t ii = 0; ii < crv->m_KnotID.size(); ii++) { if (crv->m_KnotID[ii] != 0) { Point3D_M *p = (Point3D_M*)DataManager::GetObjectByID(crv->m_KnotID[ii]); if(!p) { continue; } tmpPos = ss + " " + QString::number(p->m_X) + PathUtil::getEndMark(); tmp += QString::number(ii + 1) + " " + QString::number(p->m_Y) + "," + QString::number(p->m_Z) + PathUtil::getEndMark(); } } } else if (ss == "Y") { for (size_t ii = 0; ii < crv->m_KnotID.size(); ii++) { if (crv->m_KnotID[ii] != 0) { //Point3D p = GetPointByID(crv.KnotID[ii]); Point3D_M *p = (Point3D_M*)DataManager::GetObjectByID(crv->m_KnotID[ii]); if(!p) { continue; } tmpPos = ss + " " + QString::number(p->m_Y) + PathUtil::getEndMark(); tmp += QString::number(ii + 1) + " " + QString::number(p->m_X) + "," + QString::number(p->m_Z) + PathUtil::getEndMark(); } } } else if (ss == "Z") { for (size_t ii = 0; ii < crv->m_KnotID.size(); ii++) { if (crv->m_KnotID[ii] != 0) { // Point3D p = GetPointByID(crv.KnotID[ii]); Point3D_M *p = (Point3D_M*)DataManager::GetObjectByID(crv->m_KnotID[ii]); if(!p) { continue; } tmpPos = ss + " " + QString::number(p->m_Z) + PathUtil::getEndMark(); tmp += QString::number(ii + 1) + " " + QString::number(p->m_X) + "," + QString::number(p->m_Y) + PathUtil::getEndMark(); } } } else { for (size_t ii = 0; ii < crv->m_KnotID.size(); ii++) { if (crv->m_KnotID[ii] != 0) { //Point3D p = GetPointByID(crv.KnotID[ii]); Point3D_M *p = (Point3D_M*)DataManager::GetObjectByID(crv->m_KnotID[ii]); if(!p) { continue; } tmp += QString::number(ii + 1) + " " + QString::number(p->m_X) + "," + QString::number(p->m_Y) + "," + QString::number(p->m_Z) + PathUtil::getEndMark(); } } } } else { vector pointList = DataManager::GetCurvePointByFSEx(objid, 3); //QVector pointList; // Replace with real logic to get points if (pointList.size() < 2) { } else { tmp += "1 " + QString::number(pointList[0].X) + "," + QString::number(pointList[0].Y) + "," + QString::number(pointList[0].Z) + "\r\n"; tmp += "2 " + QString::number(pointList[pointList.size() - 1].X) + "," + QString::number(pointList[pointList.size() - 1].Y) + "," + QString::number(pointList[pointList.size() - 1].Z) + "\r\n"; } } strcmd += tmpPos; strcmd += tmp; } } } if(!strcmd.isEmpty()) { QString retStr = strcmd + PathUtil::getLogEndLine(); m_pDataManager->addShowWindowsLog(retStr); return true; } else { return false; } } bool StabilityModel::cmd_tool_show_curve_rib_crd(std::vector& ids,bool isShowCoordF,QString& outStr ) { if(ids.size() == 0) { return false; } std::set curve_ids; for (size_t i = 0; i < ids.size(); i++) { std::string objName = ids[i]; IModel *pObj = DataManager::GetObjectByName(objName); if (!pObj) { continue; } if(E_GEO_3D_OBJ_TYPE_CURVE == pObj->getObjType()) { curve_ids.insert(pObj->GetID()); } } QString cmd = ""; //int count = 0; for(auto id_tmp :curve_ids) { IModel *pObj = DataManager::GetObjectByID(id_tmp); if (!pObj) { continue; } cmd += pObj->GetName() + PathUtil::getEndMark(); string tmp = ""; vector pointList; if (isShowCoordF) { pointList =DataManager::GetCurvePointByFSEx(id_tmp, 1); } else { pointList =DataManager::GetCurvePointByFSEx(id_tmp, 2); } for (int ii = 0; ii < pointList.size(); ii++) { Point3D& p = pointList[ii]; if (ii == 0 || ii == (int)pointList.size() - 1) { if (isShowCoordF) { tmp += "(" + StringHelper::tostring_fix(p.X,4) + "," + StringHelper::tostring_fix(p.Y,4) + "," + StringHelper::tostring_fix(p.Z,4) + ")" + PathUtil::getEndMark().toStdString(); } else { tmp += "(" + StringHelper::tostring_fix(p.X,4) + "," + StringHelper::tostring_fix(p.Y,4) + "," + StringHelper::tostring_fix(p.Z,4) + ")" + PathUtil::getEndMark().toStdString(); } } else { if (isShowCoordF) { tmp += "(" + ChangeFSPos::ShowF(::to_string(p.X)) + "," + StringHelper::tostring_fix(p.Y,4) + "," + StringHelper::tostring_fix(p.Z,4) + ")" + PathUtil::getEndMark().toStdString(); } else { tmp += "(" + ChangeFSPos::ShowS(::to_string(p.X)) + "," + StringHelper::tostring_fix(p.Y,4) + "," + StringHelper::tostring_fix(p.Z,4) + ")" + PathUtil::getEndMark().toStdString(); } } } cmd += QString::fromStdString(tmp); //count++; } if (curve_ids.size() == 0) { return false; } else { QString retStr = cmd + PathUtil::getLogEndLine(); m_pDataManager->addShowWindowsLog(retStr); return true; } } void StabilityModel::push_undo_redo_data(int icommandid, std::vector& data) { m_pDataManager->push_undo_redo_data(icommandid, data); } void StabilityModel::cmd_undo(QString& strDeleteJson, QString& strChangeJson) { bool isCanUndo = false; bool isCanRedo = false; std::vector disCardObjsName; std::vector changesObjsID; m_pDataManager->cmd_undo(disCardObjsName, changesObjsID,isCanUndo, isCanRedo); if (disCardObjsName.size() > 0) { strDeleteJson = updateDelete3dToJson(disCardObjsName); } if (changesObjsID.size() > 0) { strChangeJson = getUpdate3dToJson(changesObjsID); } } void StabilityModel::cmd_redo(QString& strDeleteJson, QString& strChangeJson) { bool isCanUndo = false; bool isCanRedo = false; std::vector disCardObjsName; std::vector changesObjsID; m_pDataManager->cmd_redo(disCardObjsName, changesObjsID, isCanUndo, isCanRedo); if (disCardObjsName.size() > 0) { strDeleteJson = updateDelete3dToJson(disCardObjsName); } if (changesObjsID.size() > 0) { strChangeJson = getUpdate3dToJson(changesObjsID); } } #ifdef __cplusplus } #endif