BaseIO.h 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528
  1. /*******************************************************************************
  2. 包含文件说明:
  3. 1. RandomColorGenerator.h:
  4. 基于HSV色彩模式定义的一个颜色生成器,过滤掉一些不适合显示模型的颜色,比如纯色;
  5. 另外,生成的相邻颜色差别也较大,避免颜色过于相似
  6. 2. tcl_5.0.6
  7. 树结构的库,由于版本比较老,所以DCiP编译时会有一些警告和错误;
  8. 一个是继承binary_function出现错误,这个可以直接注释掉;
  9. 一个是一些allocate内存的警告,可以通过定义宏的方式过滤
  10. _SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
  11. 一些函数说明:
  12. 1. GetFaceMap:获取hashcode与TopoDS_Face的映射
  13. 2. GetJson:获取用于显示树形结构的Json数据
  14. 3. CreateBrepById:根据id获取到Face后,生成Brep
  15. 4. CreateCenterById:根据id获取到Face后,生成中心点
  16. *******************************************************************************/
  17. #ifndef BASEIO_H
  18. #define BASEIO_H
  19. #ifdef new
  20. #undef new
  21. #endif // new
  22. #include <vector>
  23. #include <map>
  24. #include <string>
  25. #include <iostream>
  26. #include <random>
  27. #include <set>
  28. #include <unordered_set>
  29. #include <algorithm>
  30. #include <assert.h>
  31. #include <NCollection_IndexedDataMap.hxx>
  32. #include <NCollection_Map.hxx>
  33. #include <TDF_ChildIterator.hxx>
  34. #include <TDocStd_Document.hxx>
  35. #include <TopExp.hxx>
  36. #include <TopoDS.hxx>
  37. #include <XCAFDoc_ShapeTool.hxx>
  38. #include <XCAFDoc_ColorTool.hxx>
  39. #include <XCAFDoc_DocumentTool.hxx>
  40. #include <XCAFDoc_ShapeTool.hxx>
  41. #include <Quantity_Color.hxx>
  42. #include <BRepBuilderAPI_Sewing.hxx>
  43. #include <TopoDS_Shape.hxx>
  44. #include <Quantity_NameOfColor.hxx>
  45. #include <TDF_Tool.hxx>
  46. #include <TDataStd_Integer.hxx>
  47. #include <TopoDS_TShape.hxx>
  48. #include <IMeshTools_Parameters.hxx>
  49. #include <BRepMesh_IncrementalMesh.hxx>
  50. #include <TColStd_HSequenceOfExtendedString.hxx>
  51. #include <XCAFDoc_LayerTool.hxx>
  52. #include <XCAFDoc_VisMaterialTool.hxx>
  53. #include <XCAFPrs_IndexedDataMapOfShapeStyle.hxx>
  54. #include <TopLoc_IndexedMapOfLocation.hxx>
  55. #include <TNaming_NamedShape.hxx>
  56. #include <TDataStd_Name.hxx>
  57. #include <XCAFDoc_GraphNode.hxx>
  58. #include <XCAFPrs_Style.hxx>
  59. #include <NCollection_Sequence.hxx>
  60. #include <Poly_Connect.hxx>
  61. #include <Poly.hxx>
  62. #include <TDocStd_Document.hxx>
  63. #include <STEPCAFControl_Reader.hxx>
  64. #include <GeomLib.hxx>
  65. #include <BRepCheck_Analyzer.hxx>
  66. #include <ShapeAnalysis.hxx>
  67. #include <ShapeFix_Wire.hxx>
  68. #include <ShapeFix_Shape.hxx>
  69. #include <BRepGProp_Face.hxx>
  70. #include <BRepBndLib.hxx>
  71. #include <Bnd_Box.hxx>
  72. #include <gp_Pnt.hxx>
  73. #include <TopoDS_Shape.hxx>
  74. #include <TopoDS_Edge.hxx>
  75. #include <IGESCAFControl_Writer.hxx>
  76. #include <TopTools_DataMapOfShapeShape.hxx>
  77. #include <GProp_GProps.hxx>
  78. #include <BRepGProp.hxx>
  79. #include <BRepTools.hxx>
  80. #include <TopExp_Explorer.hxx>
  81. #include "occ_compatible.h"
  82. #include "tcl_5.0.6/tree.h"
  83. #include "jsoncpp/json/json.h"
  84. //#include"jsoncpp/jsoncpp.cpp"
  85. #include "RandomColorGenerator.h"
  86. #include "FaceProperty.h"
  87. #include "TreeLabel.h"
  88. #include "GeoAPIUtil.h"
  89. #include <BRepAlgoAPI_Fuse.hxx>
  90. using namespace std;
  91. using namespace tcl;
  92. using namespace Json;
  93. class CompareLess {
  94. public:
  95. bool operator()(const TreeLabel& lhs, const TreeLabel& rhs) const {
  96. return lhs.id < rhs.id;
  97. }
  98. };
  99. typedef tree<TreeLabel, CompareLess> CTree;
  100. //typedef tree<TreeLabel> CTree;
  101. class BaseIO
  102. {
  103. public:
  104. BaseIO()
  105. {
  106. aMeshParams.Deflection = 0.02; //For Fine Model: 0.02
  107. aMeshParams.Angle = 0.5;
  108. aMeshParams.Relative = Standard_True;
  109. aMeshParams.InParallel = Standard_True;
  110. //aMeshParams.MinSize = Precision::Confusion();
  111. aMeshParams.InternalVerticesMode = Standard_True;
  112. aMeshParams.ControlSurfaceDeflection = Standard_True;
  113. defaultCurveColor.SetValues(1.0, 1.0, 1.0, 1.0);
  114. defaultSurfColor.SetValues(static_cast<float>(0.64), static_cast<float>(0.64), static_cast<float>(1.0), static_cast<float>(1.0));
  115. sewFlag = false;
  116. faceStartId = 1000000;
  117. componentStartId = 6000000;
  118. edgeStartId = 10000000;
  119. }
  120. ~BaseIO() {}
  121. inline void Perform();
  122. void GetFaceMap(NCollection_IndexedDataMap<int, FaceProperty> &_faceMap);
  123. void SetSewModel(const bool &flag);
  124. void CreateBrepById(const vector<int>& _hashCode, const string& filePath);
  125. void CreateCenterById(const int &_id, double &x, double &y, double &z);
  126. bool CreateStpById(const int &_id, const string &filePath);
  127. bool CreateComponentStpById(const int& _id, const string& filePath); //创建通过面ID生成面所在组件的step文件
  128. inline void GetEdgeMap(map<int, TopoDS_Edge>& edges);
  129. inline void GetDocument(Handle(TDocStd_Document)& document);
  130. string GetJson(bool faceFlag = true);
  131. string GetJsonEx(bool faceFlag, vector<int>& faces, vector<int>& components, NCollection_DataMap<Standard_Integer, Standard_Integer>& faceID_ComponentIDMap);
  132. string jsonPath;
  133. string modelTrees;
  134. CTree modelTree;
  135. int currentComponentId = 0;
  136. void SetShape(TopoDS_Shape input);
  137. TopoDS_Shape GetShape();
  138. NCollection_IndexedDataMap<int, FaceProperty> idFacePropertyMap;
  139. NCollection_IndexedDataMap<int, TopoDS_Edge> idEdgeMap;
  140. NCollection_IndexedDataMap<int, TopoDS_Shape> idShapeMap;
  141. NCollection_Map<TopoDS_Shape, TopTools_ShapeMapHasher> parseComponentCodes;
  142. protected:
  143. typedef NCollection_IndexedDataMap<TopoDS_Shape, CTree *, TopTools_ShapeMapHasher> IndexedDataMapOfShapeTreeNode;
  144. typedef NCollection_IndexedDataMap<TopoDS_Shape, CTree *, TopTools_ShapeMapHasher>::Iterator DataMapIteratorOfIndexedDataMapOfShapeTreeNode;
  145. typedef NCollection_IndexedDataMap<TopoDS_Face, FaceProperty, TopTools_ShapeMapHasher> IndexedDataMapOfFaceProperty;
  146. typedef NCollection_IndexedDataMap<TopoDS_Edge, int, TopTools_ShapeMapHasher> IndexedDataMapOfEdgeId;
  147. typedef NCollection_IndexedDataMap<TopoDS_Shape, int, TopTools_ShapeMapHasher> IndexedDataMapOfShapeId;
  148. TopoDS_Shape currentShape;
  149. int faceStartId;
  150. int componentStartId;
  151. int edgeStartId;
  152. int gFaceId;
  153. int gEdgeId;
  154. int gComponentId;
  155. bool sewFlag;
  156. Handle(TDocStd_Document) doc;
  157. Handle(XCAFDoc_ShapeTool) ST;
  158. Handle(XCAFDoc_ColorTool) CT;
  159. IMeshTools_Parameters aMeshParams;
  160. Quantity_ColorRGBA defaultCurveColor;
  161. Quantity_ColorRGBA defaultSurfColor;
  162. RandomColorGenerator colorGen;
  163. map<Standard_Integer, set<Standard_Integer> > mapEdgeType;
  164. XCAFPrs_IndexedDataMapOfShapeStyle aSettings;
  165. IndexedDataMapOfFaceProperty faceFacepropertyMap;
  166. IndexedDataMapOfEdgeId edgeIdMap;
  167. IndexedDataMapOfShapeId shapeIdMap;
  168. TopoDS_Shape SewModel(const TopoDS_Shape& objShape);
  169. TCollection_ExtendedString GetLabelName(const TDF_Label &label);
  170. void DefineDataId();
  171. void GetEdgeType(const TopoDS_Shape &objShape);
  172. TopoDS_Face FixFace(const TopoDS_Face& face);
  173. void fillStyleColors(XCAFPrs_Style& theStyle, const Handle(XCAFDoc_ColorTool)& theTool, const TDF_Label& theLabel);
  174. Standard_Boolean getShapesOfSHUO(TopLoc_IndexedMapOfLocation& theaPrevLocMap, const Handle(XCAFDoc_ShapeTool)& theSTool, const TDF_Label& theSHUOlab, TopTools_SequenceOfShape& theSHUOShapeSeq);
  175. void CollectStyleSettings(const TDF_Label& theLabel, const TopLoc_Location& theLoc, XCAFPrs_IndexedDataMapOfShapeStyle& theSettings,
  176. IndexedDataMapOfShapeTreeNode& aShapeTreeNodeMapping, CTree::iterator iter, const Quantity_ColorRGBA& theLayerColor = Quantity_ColorRGBA(Quantity_NOC_WHITE), int level = 1);
  177. void BuildFaceData(const TopoDS_Shape& shape, const XCAFPrs_Style& style, CTree* treeNode);
  178. void Node2Json(CTree* node, Json::Value &jsonNode, bool faceFlag);
  179. void Node2JsonEx(CTree* node, Json::Value& jsonNode, bool faceFlag, vector<int>& faces, vector<int>& components,
  180. NCollection_DataMap<Standard_Integer, Standard_Integer>& faceID_ComponentIDMap);
  181. bool compareJsonValue(const Json::Value& a, const Json::Value& b);
  182. void sortJsonArrays(Json::Value& node);
  183. void displayJsonTree(const Json::Value& node, int indent = 0);
  184. void sortFaceId(Json::Value& node);
  185. void SetStartId(const int &faceStartId, const int &componentStartId, const int &edgeStartId);
  186. void GetTree(CTree& Tree);
  187. string rgbToHex(int r, int g, int b);
  188. //template <typename T>
  189. //void coutRed(const T &str)
  190. //{
  191. // HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  192. // SetConsoleTextAttribute(hConsole, FOREGROUND_RED); // 设置文字颜色为红色
  193. // std::cout << str << std::endl;
  194. // SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); // 重置为默认颜色
  195. //}
  196. #ifdef OCCTEST
  197. public:
  198. void Render();
  199. void SetAISInteractiveContext(Handle(AIS_InteractiveContext) _myAISContext);
  200. Handle(AIS_InteractiveContext) myAISContext;
  201. #endif
  202. };
  203. inline void BaseIO::SetStartId(const int &faceStartId, const int &componentStartId, const int &edgeStartId)
  204. {
  205. this->faceStartId = faceStartId;
  206. this->componentStartId = componentStartId;
  207. this->edgeStartId = edgeStartId;
  208. }
  209. inline void BaseIO::SetSewModel(const bool &flag)
  210. {
  211. sewFlag = flag;
  212. }
  213. inline void BaseIO::SetShape(TopoDS_Shape input)
  214. {
  215. currentShape = input;
  216. }
  217. inline TopoDS_Shape BaseIO::GetShape()
  218. {
  219. return currentShape;
  220. }
  221. inline void BaseIO::Perform()
  222. {
  223. colorGen.ResetRef();
  224. // 这里重新赋值,否则切换窗口重新读入时,id会继续累加
  225. gFaceId = faceStartId;
  226. gEdgeId = edgeStartId;
  227. gComponentId = componentStartId;
  228. ST = XCAFDoc_DocumentTool::ShapeTool(doc->Main());
  229. CT = XCAFDoc_DocumentTool::ColorTool(doc->Main());
  230. TDF_LabelSequence Labels;
  231. ST->GetFreeShapes(Labels);
  232. modelTree.clear();
  233. idFacePropertyMap.Clear();
  234. idEdgeMap.Clear();
  235. idShapeMap.Clear();
  236. int faceCount = 0;
  237. //计算模型包含face数目,确定模型的大小
  238. for (int idx = 1; idx <= Labels.Length(); ++idx)
  239. {
  240. TDF_Label theLabel = Labels.ChangeValue(idx);
  241. TopoDS_Shape objShape;
  242. ST->GetShape(theLabel, objShape);
  243. SetShape(objShape);
  244. // 创建一个TopExp_Explorer对象,用于遍历形状中的面
  245. TopExp_Explorer explorer(objShape, TopAbs_FACE);
  246. // 当还有更多的面可以遍历的时候
  247. while (explorer.More()) {
  248. // 面的数量加1
  249. faceCount++;
  250. // 移动到下一个面
  251. explorer.Next();
  252. }
  253. }
  254. //如果模型相对较小,可以采用较高的精度
  255. if (faceCount < 50)
  256. {
  257. aMeshParams.Deflection = 0.005;
  258. }
  259. else if (faceCount < 100)
  260. {
  261. aMeshParams.Deflection = 0.01;
  262. }
  263. else if (faceCount < 200)
  264. {
  265. aMeshParams.Deflection = 0.02;
  266. }
  267. cout << "Total Face Count:" << faceCount << endl;
  268. // 划分网格
  269. for (int idx = 1; idx <= Labels.Length(); ++idx)
  270. {
  271. TDF_Label theLabel = Labels.ChangeValue(idx);
  272. TopoDS_Shape objShape;
  273. ST->GetShape(theLabel, objShape);
  274. if (objShape.IsNull())
  275. {
  276. continue;
  277. }
  278. if (sewFlag)
  279. {
  280. SewModel(objShape);
  281. }
  282. BRepTools::Clean(objShape);
  283. BRepMesh_IncrementalMesh(objShape, aMeshParams);
  284. }
  285. DefineDataId();
  286. //// 检查重复的Hashcode
  287. //for (int idx = 1; idx <= Labels.Length(); ++idx)
  288. //{
  289. // TDF_Label theLabel = Labels.ChangeValue(idx);
  290. // TopoDS_Shape objShape;
  291. // ST->GetShape(theLabel, objShape);
  292. // map<size_t, TopoDS_Face> mapFaces;
  293. // NCollection_IndexedDataMap<TopoDS_Face, int, TopTools_ShapeMapHasher> faceIndexMap;
  294. // int faceCount = 0;
  295. // for (TopExp_Explorer faceExp(objShape, TopAbs_FACE); faceExp.More(); faceExp.Next())
  296. // {
  297. // const TopoDS_Face &objFace = TopoDS::Face(faceExp.Current());
  298. // faceIndexMap.Add(objFace, faceCount);
  299. // size_t hashcode = std::hash<TopoDS_Face>{}(objFace);
  300. // faceCount++;
  301. // if (mapFaces.find(hashcode) != mapFaces.end()) {
  302. // //比较面积,重心坐标
  303. // GProp_GProps system;
  304. // GProp_GProps props;
  305. // BRepGProp::VolumeProperties(mapFaces[hashcode], system);
  306. // gp_Pnt centerOfMass = system.CentreOfMass();
  307. // Standard_Real x = centerOfMass.X();
  308. // Standard_Real y = centerOfMass.Y();
  309. // Standard_Real z = centerOfMass.Z();
  310. // BRepGProp::SurfaceProperties(mapFaces[hashcode], props);
  311. // Standard_Real area = props.Mass();
  312. // cout << "Origin: " << hashcode << " " << x << " " << y << " " << z << " " << area << endl;
  313. // BRepGProp::VolumeProperties(objFace, system);
  314. // centerOfMass = system.CentreOfMass();
  315. // x = centerOfMass.X();
  316. // y = centerOfMass.Y();
  317. // z = centerOfMass.Z();
  318. // BRepGProp::SurfaceProperties(objFace, props);
  319. // area = props.Mass();
  320. // cout << "Repeat: " << hashcode << " " << x << " " << y << " " << z << " " << area << endl;
  321. // continue;
  322. // }
  323. // mapFaces.insert(make_pair(hashcode, objFace));
  324. // }
  325. // cout << "Face Counts: " << faceCount << endl;
  326. // cout << "Map Size: " << mapFaces.size() << endl;
  327. // cout << "faceIndexMap Size: " << faceIndexMap.Size() << endl;
  328. //}
  329. modelTree.get()->id = componentStartId;
  330. std::cout << "Labels.Length(): " << Labels.Length() << std::endl;
  331. // 遍历所有的Free Label,构建Tree
  332. for (int idx = 1; idx <= Labels.Length(); ++idx)
  333. {
  334. TDF_Label theLabel = Labels.ChangeValue(idx);
  335. TopoDS_Shape objShape;
  336. ST->GetShape(theLabel, objShape);
  337. if (objShape.IsNull())
  338. {
  339. continue;
  340. }
  341. TreeLabel _treeLabel(theLabel, objShape, TreeShape, 1);
  342. _treeLabel.id = ++gComponentId;
  343. idShapeMap.Add(_treeLabel.id, objShape);
  344. shapeIdMap.Add(objShape, _treeLabel.id);
  345. CTree::iterator it = modelTree.insert(_treeLabel);
  346. TopLoc_Location aLoc;
  347. GetEdgeType(objShape);
  348. IndexedDataMapOfShapeTreeNode aShapeTreeNodeMapping;
  349. CollectStyleSettings(theLabel, aLoc, aSettings, aShapeTreeNodeMapping, it, Quantity_ColorRGBA(Quantity_NOC_WHITE), 1);
  350. for (Standard_Integer anIter = aSettings.Extent(); anIter >= 1; --anIter)
  351. {
  352. XCAFPrs_Style aProp = aSettings.FindFromIndex(anIter);
  353. }
  354. //for (Standard_Integer anIter = 1; anIter <= aSettings.Extent(); ++anIter)
  355. for (Standard_Integer anIter = aSettings.Extent(); anIter >= 1; --anIter)
  356. {
  357. BuildFaceData(aSettings.FindKey(anIter), aSettings.FindFromIndex(anIter), *(aShapeTreeNodeMapping.Seek(aSettings.FindKey(anIter))));
  358. }
  359. aSettings.Clear();
  360. aShapeTreeNodeMapping.Clear();
  361. }
  362. Labels.Clear();
  363. for (Standard_Integer anIter = 1; anIter <= faceFacepropertyMap.Size(); ++anIter)
  364. {
  365. idFacePropertyMap.Add(faceFacepropertyMap.FindFromIndex(anIter).id, faceFacepropertyMap.FindFromIndex(anIter));
  366. }
  367. faceFacepropertyMap.Clear();
  368. }
  369. inline void BaseIO::DefineDataId()
  370. {
  371. TDF_LabelSequence Labels;
  372. ST->GetFreeShapes(Labels);
  373. for (int idx = 1; idx <= Labels.Length(); ++idx)
  374. {
  375. TDF_Label theLabel = Labels.ChangeValue(idx);
  376. TopoDS_Shape objShape;
  377. ST->GetShape(theLabel, objShape);
  378. for (TopExp_Explorer faceExp(objShape, TopAbs_FACE); faceExp.More(); faceExp.Next())
  379. {
  380. const TopoDS_Face &objFace = TopoDS::Face(faceExp.Current());
  381. // 这里是针对subshape定义颜色
  382. FaceProperty *pFaceProp = faceFacepropertyMap.ChangeSeek(objFace);
  383. if (pFaceProp != NULL)
  384. {
  385. continue;
  386. }
  387. FaceProperty faceProp;
  388. faceProp.faceObj = objFace;
  389. faceProp.id = gFaceId++;
  390. faceFacepropertyMap.Add(objFace, faceProp);
  391. }
  392. // 公共边会重复,所以需要判断一下键值是否已经存在了,否则一个公共边会有两个不同的id
  393. for (TopExp_Explorer edgeExp(objShape, TopAbs_EDGE); edgeExp.More(); edgeExp.Next())
  394. {
  395. const TopoDS_Edge &objEdge = TopoDS::Edge(edgeExp.Current());
  396. int edgeId;
  397. if (!edgeIdMap.FindFromKey(objEdge, edgeId))
  398. {
  399. idEdgeMap.Add(gEdgeId, objEdge);
  400. edgeIdMap.Add(objEdge, gEdgeId++);
  401. }
  402. }
  403. }
  404. // 避免面数过多,face id与ComponentId重复
  405. if (gComponentId < gFaceId)
  406. {
  407. componentStartId = gFaceId + 1;
  408. gComponentId = gFaceId + 1;
  409. }
  410. }
  411. inline void BaseIO::GetFaceMap(NCollection_IndexedDataMap<int, FaceProperty> &_faceMap)
  412. {
  413. _faceMap = idFacePropertyMap;
  414. }
  415. inline void BaseIO::GetTree(CTree& Tree)
  416. {
  417. Tree = modelTree;
  418. }
  419. inline void BaseIO::sortFaceId(Json::Value& node)
  420. {
  421. if (node.isArray()) {
  422. for (auto& element : node) {
  423. if (element["type"] == "Face")
  424. {
  425. gFaceId++;
  426. element["faceId"] = to_string(gFaceId);
  427. string tail;
  428. if (gFaceId < 10)
  429. {
  430. tail = "_0000" + to_string(gFaceId);
  431. }
  432. else if (gFaceId < 100)
  433. {
  434. tail = "_000" + to_string(gFaceId);
  435. }
  436. else if (gFaceId < 1000)
  437. {
  438. tail = "_00" + to_string(gFaceId);
  439. }
  440. else if (gFaceId < 10000)
  441. {
  442. tail = "_0" + to_string(gFaceId);
  443. }
  444. else
  445. {
  446. tail = "_" + to_string(gFaceId);
  447. }
  448. element["name"] = "Face" + tail;
  449. }
  450. else
  451. {
  452. element["faceId"] = "0";
  453. }
  454. }
  455. for (auto& element : node) {
  456. sortFaceId(element);
  457. }
  458. }
  459. else if (node.isObject()) {
  460. //if (node["name"] == "Model")
  461. //{
  462. // node["faceId"] = "0";
  463. //}
  464. for (auto& key : node.getMemberNames()) {
  465. sortFaceId(node[key]);
  466. }
  467. }
  468. }
  469. inline string BaseIO::GetJson(bool faceFlag)
  470. {
  471. Json::Value jsonNode;
  472. Node2Json(&modelTree, jsonNode, faceFlag);
  473. sortJsonArrays(jsonNode);
  474. gFaceId = 0;
  475. //sortFaceId(jsonNode);
  476. //displayJsonTree(jsonNode);
  477. Json::StreamWriterBuilder builder;
  478. builder["commentStyle"] = "None";
  479. builder["emitUTF8"] = true; // 直接输出 UTF-8 字符
  480. builder["indentation"] = " ";
  481. //builder["indentation"] = ""; // 压缩格式,没有换行和不必要的空白字符
  482. // 用于输出json,测试用
  483. if (!jsonPath.empty())
  484. {
  485. ofstream outfile(jsonPath.c_str());
  486. outfile << Json::writeString(builder, jsonNode) << endl;
  487. outfile.close();
  488. }
  489. return Json::writeString(builder, jsonNode);
  490. }
  491. inline string BaseIO::GetJsonEx(bool faceFlag, vector<int>& faces, vector<int>& components,
  492. NCollection_DataMap<Standard_Integer, Standard_Integer>& faceID_ComponentIDMap)
  493. {
  494. Json::Value jsonNode;
  495. Node2JsonEx(&modelTree, jsonNode, faceFlag, faces, components, faceID_ComponentIDMap);
  496. sortJsonArrays(jsonNode);
  497. gFaceId = 0;
  498. //sortFaceId(jsonNode);
  499. //displayJsonTree(jsonNode);
  500. Json::StreamWriterBuilder builder;
  501. builder["commentStyle"] = "None";
  502. builder["emitUTF8"] = true; // 直接输出 UTF-8 字符
  503. builder["indentation"] = " ";
  504. //builder["indentation"] = ""; // 压缩格式,没有换行和不必要的空白字符
  505. // 用于输出json,测试用
  506. if (!jsonPath.empty())
  507. {
  508. ofstream outfile(jsonPath.c_str());
  509. outfile << Json::writeString(builder, jsonNode) << endl;
  510. outfile.close();
  511. }
  512. return Json::writeString(builder, jsonNode);
  513. }
  514. // 比较函数,用于比较两个Json::Value类型元素(假设这里比较的是数值类型元素,你可按需修改比较逻辑)
  515. inline bool BaseIO::compareJsonValue(const Json::Value& a, const Json::Value& b) {
  516. if (a.isObject() && b.isObject())
  517. {
  518. if (a["name"].isString() && b["name"].isString()) {
  519. std::string nameA = a["name"].asString();
  520. std::string nameB = b["name"].asString();
  521. return nameA < nameB;
  522. }
  523. }
  524. else
  525. {
  526. return a < b;
  527. }
  528. return false;
  529. }
  530. // 递归函数,用于处理JSON结构中所有的数组元素排序
  531. inline void BaseIO::sortJsonArrays(Json::Value& node) {
  532. if (node.isArray()) {
  533. std::vector<Json::Value> arrayElements;
  534. for (auto& element : node) {
  535. arrayElements.push_back(element);
  536. }
  537. std::sort(arrayElements.begin(), arrayElements.end(), [this](const Json::Value& a, const Json::Value& b) {
  538. return this->compareJsonValue(a, b);
  539. });
  540. node.clear();
  541. for (const auto& element : arrayElements) {
  542. node.append(element);
  543. }
  544. // 递归处理数组中的每个元素(如果元素是对象或者数组)
  545. for (auto& element : node) {
  546. sortJsonArrays(element);
  547. }
  548. }
  549. else if (node.isObject()) {
  550. for (auto& key : node.getMemberNames()) {
  551. sortJsonArrays(node[key]);
  552. }
  553. }
  554. }
  555. inline void BaseIO::displayJsonTree(const Json::Value& node, int indent) {
  556. if (node.isObject()) {
  557. bool hasName = false;
  558. for (const auto& key : node.getMemberNames()) {
  559. if (key == "name") {
  560. hasName = true;
  561. }
  562. displayJsonTree(node[key], indent + 1);
  563. }
  564. if (!hasName) {
  565. for (const auto& key : node.getMemberNames()) {
  566. displayJsonTree(node[key], indent + 1);
  567. }
  568. }
  569. }
  570. else if (node.isArray()) {
  571. for (const auto& element : node) {
  572. displayJsonTree(element, indent + 1);
  573. }
  574. }
  575. }
  576. inline void BaseIO::BuildFaceData(const TopoDS_Shape& shape, const XCAFPrs_Style& style, CTree* treeNode)
  577. {
  578. std::cout << "parseComponentCodes.Size(): " << parseComponentCodes.Size() << std::endl;
  579. if (!parseComponentCodes.Contains(shape))
  580. {
  581. return;
  582. }
  583. //new
  584. // 先创建并挂载叶子节点本身
  585. TreeLabel leafNode(shape, TreeShape, 1);
  586. leafNode.id = ++gComponentId; // 使用全局ID生成器
  587. CTree::iterator leafIt = treeNode->insert(leafNode);
  588. // 更新映射关系
  589. shapeIdMap.Add(shape, leafNode.id);
  590. idShapeMap.Add(leafNode.id, shape);
  591. //====
  592. Quantity_Color color = style.GetColorSurf();
  593. // 遍历所有Face
  594. for (TopExp_Explorer faceExp(shape, TopAbs_FACE); faceExp.More(); faceExp.Next())
  595. {
  596. TopoDS_Face &objFace = const_cast<TopoDS_Face &> (TopoDS::Face(faceExp.Current()));
  597. TopLoc_Location location;
  598. opencascade::handle<Poly_Triangulation> triFace = BRep_Tool::Triangulation(objFace, location);
  599. if (triFace.IsNull())
  600. {
  601. continue;
  602. /*
  603. // 下面是为了修复不合格曲面做的措施,实际测试中极少有曲面可以被修复,
  604. // 由于病态曲面即使修复后得到的曲面也大概率是病态曲面,因此这里注释掉;
  605. // 强行打开程序会报错,因为会受到FaceFacepropertyMap, edgeIdMap的影响;
  606. // 需要重新定义FaceFacepropertyMap, edgeIdMap才能运行
  607. TopoDS_Face fixFace = FixFace(objFace);
  608. BRepMesh_IncrementalMesh(fixFace, 1.0);
  609. opencascade::handle<Poly_Triangulation> _triFace = BRep_Tool::Triangulation(fixFace, location);
  610. if (_triFace.IsNull())
  611. {
  612. continue;
  613. }
  614. else
  615. {
  616. triFace = _triFace;
  617. faceFacepropertyMap.ChangeSeek(objFace)->faceObj = fixFace;
  618. }
  619. */
  620. }
  621. // 这里是针对subshape定义颜色
  622. FaceProperty *pFaceProp = faceFacepropertyMap.ChangeSeek(objFace);
  623. assert(pFaceProp);
  624. pFaceProp->faceObj = objFace;
  625. pFaceProp->SetColor(color);
  626. //pFaceProp->BuildPoints(triFace->Nodes(), location);
  627. pFaceProp->BuildPoints(POLY_TRIGULATION_NODES(triFace), location);
  628. pFaceProp->BuildElements(POLY_TRIGULATION_TRIANGLES(triFace));
  629. pFaceProp->ComputeNormals();
  630. for (TopExp_Explorer edgeExp(pFaceProp->faceObj, TopAbs_EDGE); edgeExp.More(); edgeExp.Next())
  631. {
  632. const TopoDS_Edge &objEdge = TopoDS::Edge(edgeExp.Current());
  633. opencascade::handle<Poly_PolygonOnTriangulation> triEdge = BRep_Tool::PolygonOnTriangulation(objEdge, triFace, location);
  634. if (triEdge.IsNull())
  635. {
  636. continue;
  637. }
  638. Standard_Integer edgeId = edgeIdMap.FindFromKey(objEdge);
  639. EdgeType _edgeType;
  640. if (mapEdgeType[edgeId].size() == 1)
  641. {
  642. _edgeType = FreeEdge;
  643. }
  644. else if (mapEdgeType[edgeId].size() == 2)
  645. {
  646. _edgeType = InnerEdge;
  647. }
  648. else
  649. {
  650. _edgeType = ShareEdge;
  651. }
  652. EdgeProperty _edgeProperty;
  653. _edgeProperty.edgeType = _edgeType;
  654. _edgeProperty.id = edgeId;
  655. for (TColStd_Array1OfInteger::Iterator anIter(triEdge->Nodes()); anIter.More(); anIter.Next())
  656. {
  657. _edgeProperty.edges.push_back(anIter.Value() - 1);
  658. }
  659. pFaceProp->edgeProperties.insert(_edgeProperty);
  660. }
  661. // 将Face插入到节点
  662. TreeLabel _node(objFace, TreeFace);
  663. _node.id = pFaceProp->id;
  664. //new
  665. (*leafIt.node()).get()->subFaceIds.push_back(pFaceProp->id); // 记录到组件节点的subFaceIds
  666. leafIt.node()->insert(_node); // 挂载到新建的组件节点下
  667. /*
  668. (*treeNode).get()->subFaceIds.push_back(pFaceProp->id);
  669. treeNode->insert(_node);
  670. */
  671. }
  672. }
  673. // 函数用于修复给定的面
  674. inline TopoDS_Face BaseIO::FixFace(const TopoDS_Face& face)
  675. {
  676. // 创建ShapeFix_Shape对象来修复形状
  677. ShapeFix_Shape fixer(face);
  678. if (fixer.Perform())
  679. {
  680. TopoDS_Face _face = TopoDS::Face(fixer.Shape());
  681. return _face;
  682. }
  683. else
  684. {
  685. return face;
  686. }
  687. }
  688. inline void BaseIO::GetEdgeType(const TopoDS_Shape &objShape)
  689. {
  690. for (TopExp_Explorer faceExp(objShape, TopAbs_FACE); faceExp.More(); faceExp.Next())
  691. {
  692. TopoDS_Shape shapeChild = faceExp.Current();
  693. const TopoDS_Face &objFace = TopoDS::Face(faceExp.Current());
  694. int faceId = faceFacepropertyMap.FindFromKey(objFace).id;
  695. for (TopExp_Explorer edgeExp(objFace, TopAbs_EDGE); edgeExp.More(); edgeExp.Next())
  696. {
  697. const TopoDS_Edge &objEdge = TopoDS::Edge(edgeExp.Current());
  698. int edgeId = edgeIdMap.FindFromKey(objEdge);
  699. if (mapEdgeType.find(edgeId) == mapEdgeType.end())
  700. {
  701. set<Standard_Integer> tempFaces;
  702. tempFaces.insert(faceId);
  703. mapEdgeType.insert(make_pair(edgeId, tempFaces));
  704. }
  705. else
  706. {
  707. mapEdgeType[edgeId].insert(faceId);
  708. }
  709. }
  710. }
  711. }
  712. inline TopoDS_Shape BaseIO::SewModel(const TopoDS_Shape& objShape)
  713. {
  714. BRepBuilderAPI_Sewing aSewingTool;
  715. aSewingTool.Init(0.5);
  716. aSewingTool.Load(objShape);
  717. aSewingTool.Perform();
  718. TopoDS_Shape aShape = aSewingTool.SewedShape();
  719. if (aShape.IsNull())
  720. aShape = objShape;
  721. return aShape;
  722. }
  723. inline TCollection_ExtendedString BaseIO::GetLabelName(const TDF_Label &label)
  724. {
  725. if (label.IsNull())
  726. {
  727. return "The Label is Null.";
  728. }
  729. Handle(TDataStd_Name) anAttribute;
  730. TCollection_ExtendedString str;
  731. if (label.FindAttribute(TDataStd_Name::GetID(), anAttribute))
  732. {
  733. str = anAttribute->Get();
  734. }
  735. return str;
  736. }
  737. inline void BaseIO::fillStyleColors(XCAFPrs_Style& theStyle, const Handle(XCAFDoc_ColorTool)& theTool, const TDF_Label& theLabel)
  738. {
  739. Quantity_ColorRGBA aColor;
  740. if (theTool->GetColor(theLabel, XCAFDoc_ColorGen, aColor))
  741. {
  742. theStyle.SetColorCurv(aColor.GetRGB());
  743. theStyle.SetColorSurf(aColor);
  744. return;
  745. }
  746. if (theTool->GetColor(theLabel, XCAFDoc_ColorSurf, aColor))
  747. {
  748. theStyle.SetColorSurf(aColor);
  749. }
  750. else
  751. {
  752. //theStyle.SetColorSurf(defaultSurfColor);
  753. Quantity_Color _color = colorGen.GetColor();
  754. theStyle.SetColorSurf(_color);
  755. }
  756. if (theTool->GetColor(theLabel, XCAFDoc_ColorCurv, aColor))
  757. {
  758. theStyle.SetColorCurv(aColor.GetRGB());
  759. }
  760. else
  761. {
  762. theStyle.SetColorCurv(defaultCurveColor.GetRGB());
  763. }
  764. }
  765. inline Standard_Boolean BaseIO::getShapesOfSHUO(TopLoc_IndexedMapOfLocation& theaPrevLocMap,
  766. const Handle(XCAFDoc_ShapeTool)& theSTool,
  767. const TDF_Label& theSHUOlab,
  768. TopTools_SequenceOfShape& theSHUOShapeSeq)
  769. {
  770. Handle(XCAFDoc_GraphNode) SHUO;
  771. TDF_LabelSequence aLabSeq;
  772. theSTool->GetSHUONextUsage(theSHUOlab, aLabSeq);
  773. if (aLabSeq.Length() >= 1)
  774. for (Standard_Integer i = 1; i <= aLabSeq.Length(); i++) {
  775. TDF_Label aSubCompL = aLabSeq.Value(i);
  776. TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation(aSubCompL.Father());
  777. // create new map of laocation (to not merge locations from different shapes)
  778. TopLoc_IndexedMapOfLocation aNewPrevLocMap;
  779. for (Standard_Integer m = 1; m <= theaPrevLocMap.Extent(); m++)
  780. aNewPrevLocMap.Add(theaPrevLocMap.FindKey(m));
  781. aNewPrevLocMap.Add(compLoc);
  782. // got for the new sublocations and corresponding shape
  783. getShapesOfSHUO(aNewPrevLocMap, theSTool, aSubCompL, theSHUOShapeSeq);
  784. }
  785. else {
  786. TopoDS_Shape aSHUO_NUSh = theSTool->GetShape(theSHUOlab.Father());
  787. if (aSHUO_NUSh.IsNull()) return Standard_False;
  788. // cause got shape with location already.
  789. TopLoc_Location nullLoc;
  790. aSHUO_NUSh.Location(nullLoc);
  791. // multiply the locations
  792. Standard_Integer intMapLenght = theaPrevLocMap.Extent();
  793. if (intMapLenght < 1)
  794. return Standard_False; // should not be, but to avoid exception...?
  795. TopLoc_Location SupcompLoc;
  796. SupcompLoc = theaPrevLocMap.FindKey(intMapLenght);
  797. if (intMapLenght > 1) {
  798. Standard_Integer l = intMapLenght - 1;
  799. while (l >= 1) {
  800. SupcompLoc = theaPrevLocMap.FindKey(l).Multiplied(SupcompLoc);
  801. l--;
  802. }
  803. }
  804. aSHUO_NUSh.Location(SupcompLoc);
  805. theSHUOShapeSeq.Append(aSHUO_NUSh);
  806. }
  807. return (theSHUOShapeSeq.Length() > 0);
  808. }
  809. inline void BaseIO::CollectStyleSettings(const TDF_Label& theLabel, const TopLoc_Location& theLoc, XCAFPrs_IndexedDataMapOfShapeStyle& theSettings,
  810. IndexedDataMapOfShapeTreeNode& aShapeTreeNodeMapping,
  811. CTree::iterator iter,
  812. const Quantity_ColorRGBA& theLayerColor,
  813. int level)
  814. {
  815. // 检查是否有Face
  816. {
  817. TopoDS_Shape _shape = ST->GetShape(theLabel);
  818. TopExp_Explorer faceExp(_shape, TopAbs_FACE);
  819. if (!faceExp.More())
  820. {
  821. return;
  822. }
  823. }
  824. bool isLowestComponent = true;
  825. // for references, first collect colors of referred shape
  826. {
  827. TDF_Label aLabelRef;
  828. if (XCAFDoc_ShapeTool::GetReferredShape(theLabel, aLabelRef))
  829. {
  830. Quantity_ColorRGBA aLayerColor = theLayerColor;
  831. Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(theLabel);
  832. Handle(TColStd_HSequenceOfExtendedString) aLayerNames = new TColStd_HSequenceOfExtendedString();
  833. aLayerTool->GetLayers(theLabel, aLayerNames);
  834. if (aLayerNames->Length() == 1)
  835. {
  836. TDF_Label aLayer = aLayerTool->FindLayer(aLayerNames->First());
  837. Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theLabel);
  838. Quantity_ColorRGBA aColor;
  839. if (aColorTool->GetColor(aLayer, XCAFDoc_ColorGen, aColor))
  840. aLayerColor = aColor;
  841. }
  842. TopLoc_Location aLocSub = theLoc.Multiplied(XCAFDoc_ShapeTool::GetLocation(theLabel));
  843. TreeLabel _treeLabel(aLabelRef, ST->GetShape(aLabelRef), TreeShape, level);
  844. _treeLabel.id = iter->id;
  845. *iter = _treeLabel;
  846. shapeIdMap.Add(ST->GetShape(aLabelRef), _treeLabel.id);
  847. (*idShapeMap.ChangeSeek(_treeLabel.id)) = ST->GetShape(aLabelRef);
  848. isLowestComponent = false;
  849. CollectStyleSettings(aLabelRef, aLocSub, theSettings, aShapeTreeNodeMapping, iter, aLayerColor, level);
  850. }
  851. }
  852. // for assemblies, first collect colors defined in components
  853. {
  854. TDF_LabelSequence aComponentLabSeq;
  855. if (XCAFDoc_ShapeTool::GetComponents(theLabel, aComponentLabSeq)
  856. && !aComponentLabSeq.IsEmpty())
  857. {
  858. for (TDF_LabelSequence::Iterator aComponentIter(aComponentLabSeq); aComponentIter.More(); aComponentIter.Next())
  859. {
  860. const TDF_Label& aComponentLab = aComponentIter.Value();
  861. TopoDS_Shape _shape = ST->GetShape(aComponentLab);
  862. TopExp_Explorer faceExp(_shape, TopAbs_FACE);
  863. if (!faceExp.More())
  864. {
  865. continue;
  866. }
  867. TreeLabel _treeLabel(aComponentLab, ST->GetShape(aComponentLab), TreeShape, level + 1);
  868. _treeLabel.id = ++gComponentId;
  869. CTree::iterator it = iter.node()->insert(_treeLabel);
  870. shapeIdMap.Add(ST->GetShape(aComponentLab), _treeLabel.id);
  871. idShapeMap.Add(_treeLabel.id, ST->GetShape(aComponentLab));
  872. isLowestComponent = false;
  873. CollectStyleSettings(aComponentLab, theLoc, theSettings, aShapeTreeNodeMapping, it, theLayerColor, level + 1);
  874. }
  875. }
  876. }
  877. // collect settings on subshapes
  878. Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theLabel);
  879. Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool(theLabel);
  880. TDF_LabelSequence aLabSeq;
  881. XCAFDoc_ShapeTool::GetSubShapes(theLabel, aLabSeq);
  882. // and add the shape itself
  883. aLabSeq.Append(theLabel);
  884. //aLabSeq.InsertBefore(1, theLabel);
  885. for (TDF_LabelSequence::Iterator aLabIter(aLabSeq); aLabIter.More(); aLabIter.Next())
  886. {
  887. const TDF_Label& aLabel = aLabIter.Value();
  888. XCAFPrs_Style aStyle;
  889. aStyle.SetVisibility(aColorTool->IsVisible(aLabel));
  890. aStyle.SetMaterial(aMatTool->GetShapeMaterial(aLabel));
  891. Handle(TColStd_HSequenceOfExtendedString) aLayerNames;
  892. Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool(aLabel);
  893. if (aStyle.IsVisible())
  894. {
  895. aLayerNames = new TColStd_HSequenceOfExtendedString();
  896. aLayerTool->GetLayers(aLabel, aLayerNames);
  897. Standard_Integer aNbHidden = 0;
  898. for (TColStd_HSequenceOfExtendedString::Iterator aLayerIter(*aLayerNames); aLayerIter.More(); aLayerIter.Next())
  899. {
  900. const TCollection_ExtendedString& aLayerName = aLayerIter.Value();
  901. if (!aLayerTool->IsVisible(aLayerTool->FindLayer(aLayerName)))
  902. {
  903. ++aNbHidden;
  904. }
  905. }
  906. aStyle.SetVisibility(aNbHidden == 0
  907. || aNbHidden != aLayerNames->Length());
  908. }
  909. if (aColorTool->IsColorByLayer(aLabel))
  910. {
  911. Quantity_ColorRGBA aLayerColor = theLayerColor;
  912. if (aLayerNames.IsNull())
  913. {
  914. aLayerNames = new TColStd_HSequenceOfExtendedString();
  915. aLayerTool->GetLayers(aLabel, aLayerNames);
  916. }
  917. if (aLayerNames->Length() == 1)
  918. {
  919. TDF_Label aLayer = aLayerTool->FindLayer(aLayerNames->First());
  920. Quantity_ColorRGBA aColor;
  921. if (aColorTool->GetColor(aLayer, XCAFDoc_ColorGen, aColor))
  922. {
  923. aLayerColor = aColor;
  924. }
  925. }
  926. aStyle.SetColorCurv(aLayerColor.GetRGB());
  927. aStyle.SetColorSurf(aLayerColor);
  928. }
  929. else
  930. {
  931. fillStyleColors(aStyle, aColorTool, aLabel);
  932. }
  933. // PTV try to set color from SHUO structure
  934. const Handle(XCAFDoc_ShapeTool)& aShapeTool = aColorTool->ShapeTool();
  935. if (aShapeTool->IsComponent(aLabel))
  936. {
  937. TDF_AttributeSequence aShuoAttribSeq;
  938. aShapeTool->GetAllComponentSHUO(aLabel, aShuoAttribSeq);
  939. for (TDF_AttributeSequence::Iterator aShuoAttribIter(aShuoAttribSeq); aShuoAttribIter.More(); aShuoAttribIter.Next())
  940. {
  941. Handle(XCAFDoc_GraphNode) aShuoNode = Handle(XCAFDoc_GraphNode)::DownCast(aShuoAttribIter.Value());
  942. if (aShuoNode.IsNull())
  943. {
  944. continue;
  945. }
  946. const TDF_Label aShuolab = aShuoNode->Label();
  947. {
  948. TDF_LabelSequence aShuoLabSeq;
  949. aShapeTool->GetSHUONextUsage(aShuolab, aShuoLabSeq);
  950. if (aShuoLabSeq.IsEmpty())
  951. {
  952. continue;
  953. }
  954. }
  955. XCAFPrs_Style aShuoStyle;
  956. aShuoStyle.SetMaterial(aMatTool->GetShapeMaterial(aShuolab));
  957. aShuoStyle.SetVisibility(aColorTool->IsVisible(aShuolab));
  958. fillStyleColors(aShuoStyle, aColorTool, aShuolab);
  959. if (aShuoStyle.IsEmpty())
  960. {
  961. aShuoStyle.SetColorCurv(defaultCurveColor.GetRGB());
  962. //aShuoStyle.SetColorSurf(defaultSurfColor);
  963. aShuoStyle.SetColorSurf(colorGen.GetColor());
  964. //continue;
  965. }
  966. /*
  967. // may be work, but static it returns excess shapes. It is more faster to use OLD version.
  968. // PTV 14.02.2003 NEW version using API of ShapeTool
  969. TopTools_SequenceOfShape aShuoShapeSeq;
  970. aShapeTool->GetAllStyledComponents (aShuoNode, aShuoShapeSeq);
  971. for (TopTools_SequenceOfShape::Iterator aShuoShapeIter (aShuoShapeSeq); aShuoShapeIter.More(); aShuoShapeIter.Next())
  972. {
  973. const TopoDS_Shape& aShuoShape = aShuoShapeIter.Value();
  974. if (!aShuoShape.IsNull())
  975. theSettings.Bind (aShuoShape, aShuoStyle);
  976. }*/
  977. // OLD version that was written before ShapeTool API, and it FASTER for presentation
  978. // get TOP location of SHUO component
  979. TopLoc_Location compLoc = XCAFDoc_ShapeTool::GetLocation(aLabel);
  980. TopLoc_IndexedMapOfLocation aPrevLocMap;
  981. // get previous set location
  982. if (!theLoc.IsIdentity())
  983. {
  984. aPrevLocMap.Add(theLoc);
  985. }
  986. aPrevLocMap.Add(compLoc);
  987. // get shapes of SHUO Next_Usage components
  988. TopTools_SequenceOfShape aShuoShapeSeq;
  989. getShapesOfSHUO(aPrevLocMap, aShapeTool, aShuolab, aShuoShapeSeq);
  990. for (TopTools_SequenceOfShape::Iterator aShuoShapeIter(aShuoShapeSeq); aShuoShapeIter.More(); aShuoShapeIter.Next())
  991. {
  992. const TopoDS_Shape& aShuoShape = aShuoShapeIter.Value();
  993. XCAFPrs_Style* aMapStyle = theSettings.ChangeSeek(aShuoShape);
  994. if (aMapStyle == NULL)
  995. theSettings.Add(aShuoShape, aShuoStyle);
  996. else
  997. *aMapStyle = aShuoStyle;
  998. CTree** _treeNode = aShapeTreeNodeMapping.ChangeSeek(aShuoShape);
  999. if (_treeNode == NULL)
  1000. {
  1001. aShapeTreeNodeMapping.Add(aShuoShape, iter.node());
  1002. }
  1003. }
  1004. continue;
  1005. }
  1006. }
  1007. if (aStyle.IsEmpty())
  1008. {
  1009. aStyle.SetColorCurv(defaultCurveColor.GetRGB());
  1010. //aStyle.SetColorSurf(defaultSurfColor);
  1011. Quantity_Color _color = colorGen.GetColor();
  1012. aStyle.SetColorSurf(_color);
  1013. }
  1014. TopoDS_Shape aSubshape = XCAFDoc_ShapeTool::GetShape(aLabel);
  1015. if (aSubshape.ShapeType() == TopAbs_COMPOUND)
  1016. {
  1017. if (aSubshape.NbChildren() == 0)
  1018. {
  1019. continue;
  1020. }
  1021. }
  1022. aSubshape.Move(theLoc);
  1023. XCAFPrs_Style* aMapStyle = theSettings.ChangeSeek(aSubshape);
  1024. if (aMapStyle == NULL)
  1025. {
  1026. theSettings.Add(aSubshape, aStyle);
  1027. }
  1028. else
  1029. *aMapStyle = aStyle;
  1030. CTree** _treeNode = aShapeTreeNodeMapping.ChangeSeek(aSubshape);
  1031. if (_treeNode == NULL)
  1032. {
  1033. aShapeTreeNodeMapping.Add(aSubshape, iter.node());
  1034. }
  1035. //new
  1036. // 判断是否是最底层的Shape,如果是,放到parseComponentCodes中,后续将不Build
  1037. if (isLowestComponent) {
  1038. // 确保是实体类型(排除复合形状等)
  1039. if (aSubshape.ShapeType() == TopAbs_SOLID) {
  1040. // 检查是否已存在,避免重复添加
  1041. if (!parseComponentCodes.Contains(aSubshape))
  1042. parseComponentCodes.Add(aSubshape);
  1043. }
  1044. }
  1045. }
  1046. }
  1047. inline void BaseIO::Node2Json(CTree* node, Json::Value& jsonNode, bool faceFlag)
  1048. {
  1049. int _id = node->get()->id;
  1050. TreeType NodeType = node->get()->NodeType;
  1051. if (!faceFlag && NodeType == TreeFace && _id != 0)
  1052. {
  1053. return;
  1054. }
  1055. FaceProperty fProp;
  1056. if (idFacePropertyMap.FindFromKey(_id, fProp))
  1057. {
  1058. //string color16 = rgbToHex(idFacePropertyMap.Seek(_id)->red, idFacePropertyMap.Seek(_id)->green, idFacePropertyMap.Seek(_id)->blue);
  1059. string color16 = rgbToHex(fProp.red, fProp.green, fProp.blue);
  1060. jsonNode["color"] = color16;
  1061. //jsonNode["faceId"] = fProp.faceId;
  1062. }
  1063. else
  1064. {
  1065. jsonNode["color"] = "#FFFFFF";
  1066. //jsonNode["faceId"] = node->get()->faceId;
  1067. }
  1068. if (NodeType == TreeFace)
  1069. {
  1070. node->get()->id = fProp.id;
  1071. //必须为小写,否则DCiP不能识别
  1072. jsonNode["name"] = node->get()->GetJsonName();
  1073. jsonNode["type"] = "Face";
  1074. }
  1075. else
  1076. {
  1077. jsonNode["name"] = node->get()->Name;
  1078. jsonNode["type"] = "Shape";
  1079. }
  1080. jsonNode["id"] = node->get()->id;
  1081. Json::Value jsonChildren;
  1082. typename CTree::iterator it = node->begin();
  1083. for (; it != node->end(); it++) {
  1084. Json::Value _jsonNode;
  1085. Node2Json(it.node(), _jsonNode, faceFlag);
  1086. if (!_jsonNode.empty())
  1087. {
  1088. jsonChildren.append(_jsonNode);
  1089. }
  1090. }
  1091. if (!jsonChildren.empty())
  1092. {
  1093. jsonNode["children"] = jsonChildren;
  1094. }
  1095. }
  1096. inline void BaseIO::Node2JsonEx(CTree* node, Json::Value &jsonNode, bool faceFlag, vector<int>& faces, vector<int>& components,
  1097. NCollection_DataMap<Standard_Integer, Standard_Integer>& faceID_ComponentIDMap)
  1098. {
  1099. int _id = node->get()->id;
  1100. //cout << "id: " << _id << endl;
  1101. TreeType NodeType = node->get()->NodeType;
  1102. //cout << "type: " << NodeType << endl;
  1103. if (!faceFlag && NodeType == TreeFace && _id != 0)
  1104. {
  1105. return;
  1106. }
  1107. FaceProperty fProp;
  1108. if (idFacePropertyMap.FindFromKey(_id, fProp))
  1109. {
  1110. //string color16 = rgbToHex(idFacePropertyMap.Seek(_id)->red, idFacePropertyMap.Seek(_id)->green, idFacePropertyMap.Seek(_id)->blue);
  1111. string color16 = rgbToHex(fProp.red, fProp.green, fProp.blue);
  1112. jsonNode["color"] = color16;
  1113. //jsonNode["faceId"] = fProp.faceId;
  1114. }
  1115. else
  1116. {
  1117. jsonNode["color"] = "#FFFFFF";
  1118. //jsonNode["faceId"] = node->get()->faceId;
  1119. }
  1120. if (NodeType == TreeFace)
  1121. {
  1122. node->get()->id = fProp.id;
  1123. //必须为小写,否则DCiP不能识别
  1124. jsonNode["name"] = node->get()->GetJsonName();
  1125. //cout << "faceName " << node->get()->GetJsonName() << endl;
  1126. //cout << "faceID " << node->get()->id << endl;
  1127. faces.push_back(node->get()->id);
  1128. faceID_ComponentIDMap.Bind(node->get()->id, currentComponentId);
  1129. jsonNode["type"] = "Face";
  1130. }
  1131. else
  1132. {
  1133. jsonNode["name"] = node->get()->Name;
  1134. //cout << "ShapeName " << node->get()->GetJsonName() << endl;
  1135. //cout << "ShapeID " << node->get()->id << endl;
  1136. currentComponentId = node->get()->id;
  1137. if (node->get()->id != 6000000) {
  1138. components.push_back(node->get()->id);
  1139. }
  1140. jsonNode["type"] = "Shape";
  1141. }
  1142. jsonNode["id"] = node->get()->id;
  1143. Json::Value jsonChildren;
  1144. typename CTree::iterator it = node->begin();
  1145. for (; it != node->end(); it++) {
  1146. Json::Value _jsonNode;
  1147. Node2JsonEx(it.node(), _jsonNode, faceFlag, faces, components, faceID_ComponentIDMap);
  1148. if (!_jsonNode.empty())
  1149. {
  1150. jsonChildren.append(_jsonNode);
  1151. }
  1152. }
  1153. if (!jsonChildren.empty())
  1154. {
  1155. jsonNode["children"] = jsonChildren;
  1156. }
  1157. }
  1158. inline string BaseIO::rgbToHex(int r, int g, int b)
  1159. {
  1160. stringstream ss;
  1161. ss << "#"
  1162. << std::setfill('0') << std::setw(2) << std::hex << std::uppercase << r
  1163. << std::setw(2) << g
  1164. << std::setw(2) << b;
  1165. return ss.str();
  1166. }
  1167. inline void BaseIO::CreateBrepById(const vector<int>& _hashCode, const string& filePath)
  1168. {
  1169. TopoDS_Compound compound;
  1170. BRep_Builder builder;
  1171. builder.MakeCompound(compound);
  1172. for (auto& elem : _hashCode)
  1173. {
  1174. if (elem < componentStartId)
  1175. {
  1176. TopoDS_Shape data = idFacePropertyMap.FindFromKey(elem).faceObj;
  1177. builder.Add(compound, data);
  1178. }
  1179. else
  1180. {
  1181. BRepTools::Write(idShapeMap.FindFromKey(elem), filePath.c_str());
  1182. TopoDS_Shape data1 = idShapeMap.FindFromKey(elem);
  1183. builder.Add(compound, data1);
  1184. }
  1185. }
  1186. BRepTools::Write(compound, filePath.c_str());
  1187. /*
  1188. if (_id < componentStartId)
  1189. {
  1190. BRepTools::Write(idFacePropertyMap.FindFromKey(_id).faceObj, filePath.c_str());
  1191. }
  1192. else
  1193. {
  1194. BRepTools::Write(idShapeMap.FindFromKey(_id), filePath.c_str());
  1195. }
  1196. */
  1197. }
  1198. inline void BaseIO::CreateCenterById(const int &_id, double &x, double &y, double &z)
  1199. {
  1200. // 支持Face,不支持Component
  1201. if (_id >= componentStartId)
  1202. {
  1203. return;
  1204. }
  1205. BRepGProp_Face analysisFace(idFacePropertyMap.FindFromKey(_id).faceObj);
  1206. Standard_Real umin, umax, vmin, vmax;
  1207. analysisFace.Bounds(umin, umax, vmin, vmax);
  1208. Standard_Real midU = (umin + umax) / 2;
  1209. Standard_Real midV = (vmin + vmax) / 2;
  1210. gp_Vec norm;
  1211. gp_Pnt midPoint;
  1212. analysisFace.Normal(midU, midV, midPoint, norm);
  1213. x = midPoint.X();
  1214. y = midPoint.Y();
  1215. z = midPoint.Z();
  1216. }
  1217. inline bool BaseIO::CreateComponentStpById(const int& _id, const string& filePath) {
  1218. TopoDS_Shape aShape;
  1219. //GetJson();
  1220. //*(aShapeTreeNodeMapping.Seek(aSettings.FindKey(anIter)))
  1221. //(*treeNode).get();
  1222. //idFacePropertyMap
  1223. /*
  1224. TopoDS_Shape result;
  1225. if (_id < componentStartId)
  1226. {
  1227. aShape = idFacePropertyMap.FindFromKey(_id).faceObj;
  1228. BRepAlgoAPI_Fuse fuse(result, aShape);
  1229. }
  1230. else
  1231. {
  1232. aShape = idShapeMap.FindFromKey(_id);
  1233. BRepAlgoAPI_Fuse fuse(result, aShape);
  1234. }
  1235. return GeoAPIUtil::CreateStpByShape(result, filePath);*/
  1236. }
  1237. inline bool BaseIO::CreateStpById(const int &_id, const string &filePath)
  1238. {
  1239. TopoDS_Shape aShape;
  1240. //idFacePropertyMap
  1241. if (_id < componentStartId)
  1242. {
  1243. aShape = idFacePropertyMap.FindFromKey(_id).faceObj;
  1244. }
  1245. else
  1246. {
  1247. aShape = idShapeMap.FindFromKey(_id);
  1248. }
  1249. return GeoAPIUtil::CreateStpByShape(aShape, filePath);
  1250. }
  1251. inline void BaseIO::GetEdgeMap(map<int, TopoDS_Edge>& edges)
  1252. {
  1253. for (NCollection_IndexedDataMap<int, TopoDS_Edge>::Iterator aKeyEdgeIter(idEdgeMap); aKeyEdgeIter.More(); aKeyEdgeIter.Next())
  1254. {
  1255. edges.insert(make_pair(aKeyEdgeIter.Key(), aKeyEdgeIter.Value()));
  1256. }
  1257. }
  1258. inline void BaseIO::GetDocument(Handle(TDocStd_Document)& document)
  1259. {
  1260. document = doc;
  1261. }
  1262. #ifdef OCCTEST
  1263. inline void BaseIO::SetAISInteractiveContext(Handle(AIS_InteractiveContext) _myAISContext)
  1264. {
  1265. myAISContext = _myAISContext;
  1266. }
  1267. inline void BaseIO::Render()
  1268. {
  1269. Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(doc->Main());
  1270. NCollection_IndexedDataMap<int, FaceProperty> _faceMap;
  1271. GetFaceMap(_faceMap);
  1272. for (NCollection_IndexedDataMap<int, FaceProperty>::Iterator aKeyFaceIter(_faceMap); aKeyFaceIter.More(); aKeyFaceIter.Next())
  1273. {
  1274. FaceProperty aProp = aKeyFaceIter.Value();
  1275. Handle(AIS_Shape) myAISSurf = ::new AIS_Shape(aProp.faceObj);
  1276. Quantity_Color color(aKeyFaceIter.Value().red / 255.0, aKeyFaceIter.Value().green / 255.0, aKeyFaceIter.Value().blue / 255.0, Quantity_TOC_RGB);
  1277. myAISSurf->SetColor(color);
  1278. myAISContext->Display(myAISSurf, Standard_False);
  1279. }
  1280. }
  1281. #endif
  1282. #endif