cmdmainprocess.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. #include "stdafx.h"
  2. #include <QFile>
  3. #include <QTextStream>
  4. #include <QDateTime>
  5. #include <QProcess>
  6. #include <QDir>
  7. #include <qdebug.h>
  8. #include "cmdmainprocess.h"
  9. #include "dpmvolclass.h"
  10. #include "ga_api.hxx"
  11. #include "at_str.hxx"
  12. #include "at_int.hxx"
  13. // Global variables to control the demonstration of advanced meshing functionalities
  14. // 0 - skip; 1 - apply
  15. //int USE_LOCAL_PHYSICAL_SIZE = 0; // 3DPM-CadSurf
  16. //int APPLY_PERIODICITY = 0; // 3DPM-CadSurf
  17. //int USE_TETRA = 1; // 3DPM-Tetra
  18. //int USE_HEXA = 0; // 3DPM-Hexa
  19. int USE_LOCAL_PHYSICAL_SIZE = 0; // 3DPM-CadSurf,1:physical_size_mode,2:geometry_size_mode
  20. int APPLY_PERIODICITY = 0; // 3DPM-CadSurf
  21. int USE_TETRA = 0; // 3DPM-Tetra
  22. int USE_HEXA = 0; // 3DPM-Hexa
  23. int USE_HYBIRD = 0;//3DPM-Hybird
  24. extern void unlock_license();
  25. class DPMvolClass;
  26. cmdMainProcess::cmdMainProcess()
  27. {
  28. //init some parameter
  29. szmp_iso_face_t_ = nullptr;
  30. szmp_iso_edge_t_ = nullptr;
  31. szmp_iso_point_t_ = nullptr;
  32. SampleUtils_ = NULL;//new DPMvolClass();
  33. object = NULL;
  34. }
  35. cmdMainProcess::~cmdMainProcess()
  36. {
  37. if(object)
  38. object = NULL;
  39. }
  40. /**
  41. * @brief iniACIS
  42. * Start ACIS to generate data
  43. * @param[in]
  44. * @return
  45. * @author
  46. * @date
  47. * @reviser
  48. * @date
  49. */
  50. void cmdMainProcess::iniACIS()
  51. {
  52. unlock_license();
  53. exit_on_bad_outcome(api_start_modeller(0));//启动ACIS,生成内部数据结构
  54. exit_on_bad_outcome(api_initialize_3dpm_bridge());
  55. printf("Successful initialization\n");
  56. }
  57. /**
  58. * @brief closeACIS
  59. * Delete ACIS
  60. * @param[in]
  61. * @return
  62. * @author qiyan
  63. * @date 2022-11-16
  64. * @reviser
  65. * @date
  66. */
  67. void cmdMainProcess::closeACIS()
  68. {
  69. exit_on_bad_outcome(api_terminate_3dpm_bridge());
  70. exit_on_bad_outcome(api_stop_modeller());//删除内部数据结构
  71. }
  72. /*
  73. * @brief:set boostjsonobject into cmdmainprocess
  74. * @param:[in]object
  75. * @ret:void
  76. * @birth:created by czm in 20230831
  77. */
  78. void cmdMainProcess::setJsonObject(boostJsonObject *object)
  79. {
  80. this->object = object;
  81. }
  82. /**
  83. * @brief CreateProcess Geometry
  84. *
  85. * @param[in] geometry
  86. * @return
  87. * @author qiyan
  88. * @date 2023-04-24
  89. * @reviser
  90. * @date
  91. */
  92. bool cmdMainProcess::CreateProcess_(string pathGeo)
  93. {
  94. iniACIS();
  95. //1.--read cad surf parameter
  96. //Get ENTITY_LIST;
  97. ENTITY_LIST Whole_ents;
  98. ENTITY_LIST cells;
  99. ENTITY_LIST ent;
  100. int externGeo = 0;
  101. if (externGeo == 0) {
  102. GeometryImExporter* geo = new GeometryImExporter();
  103. geo->LoadGeometryFile(pathGeo);
  104. ENTITY_LIST readRowEnt = geo->GetEntities();
  105. printf("Read all entity body count is %d;\n", readRowEnt.count());
  106. for (ENTITY *entC = readRowEnt.first(); entC != 0; entC = readRowEnt.next())
  107. {
  108. if (is_BODY(entC)) ent.add(entC);
  109. printf("current body is %s;\n", (is_closed_solid_body(entC) ? "closed" : "not closed"));//判断是否闭合?
  110. }
  111. printf("\n Body's count is %d;", ent.count());
  112. //--获取边的信息
  113. ENTITY_LIST EdgeEnt = geo->GetEdges();
  114. const char *name = "entity_index";
  115. for (int kk = 0; kk<EdgeEnt.count(); kk++)
  116. {
  117. if (find_named_attrib(EdgeEnt[kk], name) == 0) {
  118. //printf("not find EdgeEnt name : %s\n", name);
  119. }
  120. else {
  121. //ATTRIB_GEN_STRING* pId = NULL;
  122. ATTRIB_GEN_INTEGER* pId = NULL;
  123. outcome result = api_find_named_attribute(EdgeEnt[kk], name, reinterpret_cast<ATTRIB_GEN_NAME*&>(pId));
  124. printf("find result : %d\n", result.ok());
  125. if (pId && (result.ok() == TRUE))
  126. {
  127. /* const char*name = pId->value();
  128. printf("find pId name : %s\n", name);*/
  129. int names = pId->value();
  130. printf("find EdgeEnt pId name : %d\n", names);
  131. }
  132. }
  133. }
  134. //--获取面信息
  135. ENTITY_LIST FaceEnt = geo->GetFaces();
  136. for (int kk = 0; kk < FaceEnt.count(); kk++)
  137. {
  138. if (find_named_attrib(FaceEnt[kk], name) == 0) {
  139. //printf("not find FaceEnt name : %s\n", name);
  140. }
  141. else {
  142. //ATTRIB_GEN_STRING* pId = NULL;
  143. ATTRIB_GEN_INTEGER* pId = NULL;
  144. outcome result = api_find_named_attribute(FaceEnt[kk], name, reinterpret_cast<ATTRIB_GEN_NAME*&>(pId));
  145. printf("find result : %d\n", result.ok());
  146. if (pId && (result.ok() == TRUE))
  147. {
  148. /* const char*name = pId->value();
  149. printf("find pId name : %s\n", name);*/
  150. int names = pId->value();
  151. printf("find FaceEnt pId name : %d\n", names);
  152. }
  153. }
  154. }
  155. exit_on_bad_outcome(api_n_body_unite(ent, false));
  156. printf("Whole_ents after unite is : %d\n", ent.count());
  157. for (int kk = 0; kk < ent.count(); kk++)
  158. {
  159. printf("kk%d is %d; ", kk, is_BODY(ent[kk]));
  160. }
  161. // Attach cellular topology to non-regular union (necessary for the Spa3dpm::Cell_VolumeElem_Assoc class below to function correctly).
  162. exit_on_bad_outcome(api_ct_attach(ent));
  163. printf("Whole_ents after attach is : %d\n", ent.count());
  164. for (int kk = 0; kk < ent.count(); kk++)
  165. {
  166. printf("kk%d is %d; ", kk, is_BODY(ent[kk]));
  167. }
  168. //start stitch---
  169. GeometryStitch *geomStitch = new GeometryStitch;
  170. geomStitch->aei_STITCH_FULL(ent, Whole_ents);
  171. printf("geomStitch count is %d;\n ", Whole_ents.count());
  172. if(geo!=NULL){//0804append
  173. delete geo;
  174. geo = NULL;
  175. }
  176. }
  177. else {//self create
  178. Whole_ents = CreateSelfGeo();
  179. }
  180. printf("Load Geometry OK!"); //
  181. printf("Whole_ents is : %d\n", Whole_ents.count());
  182. //--test begin--
  183. api_ct_get_all_cells(Whole_ents, cells);
  184. printf("Cells Count: %d\n", cells.count());
  185. ENTITY_LIST lumps_list;
  186. api_get_lumps(Whole_ents[0], lumps_list);
  187. printf("Lumps Count: %d\n", lumps_list.count());
  188. ENTITY_LIST shell_list;
  189. api_get_shells(Whole_ents[0], shell_list);
  190. printf("Shells Count: %d\n", shell_list.count());
  191. ENTITY_LIST face_list;
  192. api_get_faces(Whole_ents[0], face_list);
  193. printf("Face count : %d\n", face_list.count());
  194. ENTITY_LIST loops_list;
  195. api_get_loops(Whole_ents[0], loops_list);
  196. printf("Loops count : %d\n", loops_list.count());
  197. ENTITY_LIST wires_list;
  198. api_get_wires(Whole_ents[0], wires_list);
  199. printf("Wires count : %d\n", wires_list.count());
  200. ENTITY_LIST edge_list;
  201. api_get_edges(Whole_ents[0], edge_list);
  202. printf("Edge count is : %d\n", edge_list.count());
  203. ENTITY_LIST coedges_list;
  204. api_get_coedges(Whole_ents[0], coedges_list);
  205. printf("Coedges count is : %d\n", coedges_list.count());
  206. ENTITY_LIST vertices_list;
  207. api_get_vertices(Whole_ents[0], vertices_list);
  208. printf("Vertices count is : %d\n", vertices_list.count());
  209. ENTITY_LIST tedges_list;
  210. api_get_tedges(Whole_ents[0], tedges_list);
  211. printf("tedges count is : %d\n", tedges_list.count());
  212. ENTITY_LIST tcoedges_list;
  213. api_get_tcoedges(Whole_ents[0], tcoedges_list);
  214. printf("tcoedges count is : %d\n", tcoedges_list.count());
  215. closeACIS();
  216. return true;
  217. }
  218. /**
  219. * @brief CreateProcess
  220. * Create the whole Process
  221. * @param[in]pathGeo ,pathParam
  222. pathGeo : geo file path(eq: "E:/xx.igs")
  223. pathParam: xml file path(eq: "E:/xx.xml")
  224. * @param[out]
  225. * @return bool
  226. * @author QiYan
  227. * @date 20221202
  228. */
  229. bool cmdMainProcess::CreateProcess_(string pathGeo, string pathParam)
  230. {
  231. Q_UNUSED(pathParam);
  232. // Note that 3DPM-Hexa does not respect the input surface mesh //3dpm-hexa不遵循曲面网格
  233. // If USE_HEXA is set to 1,
  234. // then both APPLY_PERIODICITY and USE_LOCAL_PHYSICAL_SIZE are set to 0
  235. iniACIS();
  236. //1.--read cad surf parameter
  237. //Get ENTITY_LIST;
  238. ENTITY_LIST Whole_ents;
  239. ENTITY_LIST cells;
  240. ENTITY_LIST ent;
  241. int externGeo = 0;
  242. if (externGeo == 0) {
  243. GeometryImExporter* geo = new GeometryImExporter();
  244. geo->LoadGeometryFile(pathGeo);
  245. ENTITY_LIST readRowEnt = geo->GetEntities();
  246. printf("Read all entity body count is %d;\n", readRowEnt.count());
  247. for (ENTITY *entC = readRowEnt.first(); entC != 0; entC = readRowEnt.next())
  248. {
  249. if (is_BODY(entC)) ent.add(entC);
  250. printf("current body is %s;", (is_closed_solid_body(entC)?"true":"face"));//判断是否闭合?
  251. }
  252. printf("\n Body's count is %d;", ent.count());
  253. //--获取边的信息
  254. ENTITY_LIST EdgeEnt = geo->GetEdges();
  255. const char *name = "entity_index";
  256. for (int kk=0;kk<EdgeEnt.count();kk++)
  257. {
  258. if (find_named_attrib(EdgeEnt[kk], name) == 0) {
  259. //printf("not find EdgeEnt name : %s\n", name);
  260. }else {
  261. //ATTRIB_GEN_STRING* pId = NULL;
  262. ATTRIB_GEN_INTEGER* pId = NULL;
  263. outcome result = api_find_named_attribute(EdgeEnt[kk], name, reinterpret_cast<ATTRIB_GEN_NAME*&>(pId));
  264. printf("find result : %d\n", result.ok());
  265. if (pId && (result.ok() == TRUE))
  266. {
  267. /* const char*name = pId->value();
  268. printf("find pId name : %s\n", name);*/
  269. int names = pId->value();
  270. printf("find EdgeEnt pId name : %d\n", names);
  271. }
  272. }
  273. }
  274. //--获取面信息
  275. ENTITY_LIST FaceEnt = geo->GetFaces();
  276. for (int kk=0; kk < FaceEnt.count(); kk++)
  277. {
  278. if (find_named_attrib(FaceEnt[kk], name) == 0) {
  279. //printf("not find FaceEnt name : %s\n", name);
  280. }else {
  281. //ATTRIB_GEN_STRING* pId = NULL;
  282. ATTRIB_GEN_INTEGER* pId = NULL;
  283. outcome result = api_find_named_attribute(FaceEnt[kk] , name, reinterpret_cast<ATTRIB_GEN_NAME*&>(pId));
  284. printf("find result : %d\n", result.ok());
  285. if (pId && (result.ok() == TRUE))
  286. {
  287. /* const char*name = pId->value();
  288. printf("find pId name : %s\n", name);*/
  289. int names = pId->value();
  290. printf("find FaceEnt pId name : %d\n", names);
  291. }
  292. }
  293. }
  294. ENTITY_LIST testEnt=ent;
  295. exit_on_bad_outcome(api_n_body_unite(testEnt, false));
  296. printf("Whole_ents after unite is : %d,then use stitch function\n", testEnt.count());
  297. if (testEnt.count()==1)
  298. {
  299. //exit_on_bad_outcome(api_n_body_unite(ent, false));
  300. //printf("Whole_ents after unite is : %d\n", ent.count());
  301. //for (int kk = 0; kk < ent.count(); kk++)
  302. //{
  303. // printf("kk%d is %d; ", kk, is_BODY(ent[kk]));
  304. //}
  305. //// Attach cellular topology to non-regular union (necessary for the Spa3dpm::Cell_VolumeElem_Assoc class below to function correctly).
  306. exit_on_bad_outcome(api_ct_attach(testEnt));
  307. printf("Whole_ents after attach is : %d\n", testEnt.count());
  308. /*for (int kk = 0; kk < ent.count(); kk++)
  309. {
  310. printf("kk%d is %d; ", kk, is_BODY(ent[kk]));
  311. }
  312. int tt = is_closed_solid_body(ent[0]);
  313. printf("closed solid body is : %d\n", tt);*/
  314. Whole_ents = testEnt;
  315. }else {
  316. //start stitch---
  317. GeometryStitch *geomStitch = new GeometryStitch;
  318. geomStitch->aei_STITCH_FULL(ent, Whole_ents);
  319. printf("geomStitch count is %d;\n ", Whole_ents.count());
  320. }
  321. //--
  322. //api_copy_entity(ent[0], &Whole_ents);
  323. if(geo!=NULL){//0804 append
  324. delete geo;
  325. geo = NULL;
  326. }
  327. }else {//self create
  328. Whole_ents = CreateSelfGeo();
  329. }
  330. printf("Load Geometry OK!"); //
  331. printf("Whole_ents is : %d\n", Whole_ents.count());
  332. ENTITY_LIST ents;
  333. ents = Whole_ents;
  334. //--test begin
  335. ENTITY_LIST face_list;
  336. api_get_faces(Whole_ents[0], face_list);
  337. printf("face count : %d\n", face_list.count());
  338. ENTITY_LIST edge_list;
  339. api_get_edges(Whole_ents[0], edge_list);
  340. printf("edge count is : %d\n", edge_list.count());
  341. //api_ct_get_all_cells(face_list[0], cells);
  342. api_ct_get_all_cells(ents, cells);
  343. printf("Cells Count: %d\n", cells.count());
  344. //const char*cpName = ((ATTRIB_GEN_STRING *)tNAME)->value();
  345. //--test end
  346. //2.--read cad surf parameter
  347. QString dDir=QDir::currentPath();
  348. printf("path:%s\n",dDir.toLatin1().data());
  349. ADIParam_.useDefaultParam();
  350. CRWriteFile* crw = new CRWriteFile();
  351. //if (!crw->ReadXmlParamFile(ADIParam_, pathParam.c_str()))
  352. //return false;
  353. if (!crw->ReadXmlParam(ADIParam_,object))//0831append
  354. return false;
  355. //3.--create surf.0
  356. Createcadsurf(ents, cadsurf_);
  357. //4.--Set parameters and create mesh
  358. cadsurfParams_ = setADIParamTo3dpm(ADIParam_);
  359. //-4.1-size map for vol
  360. CreateLocalSizeMap();
  361. //5.--output surfmesh with cleaner or not
  362. if(!OutPutSurfMesh(cadsurf_, surfMesh_, &cadsurfParams_))return 1;
  363. //-5.1-for vol
  364. printf("style=%d\n", ADIParam_.style);
  365. if(ADIParam_.style)
  366. {
  367. createVol(ADIParam_.style, cells);
  368. }
  369. //6. Save the surface mesh to .mesh (optional)
  370. QString appPath = dDir+"\\Data\\";//qy 2023-03-24修改路径
  371. QDateTime data = QDateTime::currentDateTime();
  372. QString strName;
  373. if (ADIParam_.strResultFormat == ".ugrid")
  374. {
  375. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "Result.ugrid";
  376. crw->WirteUgridFoamFile(surfMesh_, QString(appPath + strName).toLatin1());
  377. }
  378. else if (ADIParam_.strResultFormat == ".vtk") {
  379. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "Result.vtk";
  380. crw->WirteVtkFoamFile(surfMesh_, QString(appPath + strName).toLatin1());
  381. }
  382. else if (ADIParam_.strResultFormat == ".bdf") {
  383. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "Result.bdf";
  384. crw->WirteBDFFoamFile(surfMesh_, QString(appPath + strName).toLatin1());
  385. }
  386. else if (ADIParam_.strResultFormat == ".neu") {
  387. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "Result.neu";
  388. crw->WriteNeuFoamFile(surfMesh_, QString(appPath + strName).toLatin1());
  389. }
  390. exit_on_bad_outcome(api_3dpm_save_mesh(surfMesh_, "3dpmSample_surfMesh.mesh"));
  391. printf("Successfully wrote SurfMesh to .mesh format\n");
  392. //-6.1Deletesome Clean up MeshGems Sizemaps
  393. if (szmp_iso_face_t_)
  394. meshgems_sizemap_delete(szmp_iso_face_t_);
  395. if (szmp_iso_edge_t_)
  396. meshgems_sizemap_delete(szmp_iso_edge_t_);
  397. if (szmp_iso_point_t_)
  398. meshgems_sizemap_delete(szmp_iso_point_t_);
  399. //7. Termination
  400. closeACIS();
  401. if(crw!=NULL)
  402. {
  403. delete crw;
  404. crw = NULL;
  405. }
  406. //8.start show
  407. //QProcess *process = new QProcess;
  408. //process->setWorkingDirectory("..\\");
  409. //process->setWorkingDirectory("E:\\QY_Case\\MainWndTest\\case01\\trunk\\x64\\Release202010\\Release\\gmsh-4.3.0-Windows64");
  410. //QStringList strLName;
  411. //strLName << QString(appPath+strName);
  412. #ifdef _WIN32
  413. //process->start("E:\\QY_Case\\MainWndTest\\case01\\trunk\\x64\\Release202010\\Release\\gmsh-4.3.0-Windows64\\gmsh.exe", strLName);
  414. //process->start("..\\..\\Libs\\gmsh\\win\\gmsh-git-Windows64-sdk\\bin\\gmsh.exe",strLName);
  415. #else
  416. #endif
  417. return 1;
  418. }
  419. /**
  420. * @brief set ADIParam To Spa3dpm::Parameters
  421. For this sample we look at each API outcome and exit when something fails.
  422. In general your application may want to rethrow its own type of exception,
  423. or do something else.
  424. Be careful if you nest API blocks to make sure to rethrow acis_exceptions
  425. from the inner API block using check_outcome. Otherwise transactional behavior for
  426. APIs will not work.
  427. * @param[in] o
  428. * @return
  429. * @author qiyan
  430. * @date 2022-11-16
  431. * @reviser
  432. * @date
  433. */
  434. void cmdMainProcess::exit_on_bad_outcome(const outcome &o)
  435. {
  436. if (!o.ok())
  437. if (const message_list *ml = get_message(o.error_number()))
  438. {
  439. printf("*** ERROR: %s: %s\n", ml->ident, ml->message);
  440. exit(1);
  441. }
  442. }
  443. /**
  444. * @brief set ADIParam To Spa3dpm::Parameters
  445. *
  446. * @param[in] p
  447. * @return cadsurfParams
  448. * @author qiyan
  449. * @date 2022-11-16
  450. * @reviser
  451. * @date
  452. */
  453. Spa3dpm::Parameters cmdMainProcess::setADIParamTo3dpm(const DPM_ADIParam &p)
  454. {
  455. Spa3dpm::Parameters cadsurfParams;
  456. //cadsurfParams.SetParam("global_physical_size", "0.01"); // default: ModelDiagonal/100
  457. //cadsurfParams.SetParam("element_order", "quadratic");
  458. if (!p.surfParam_.SurfStyle.isEmpty())
  459. {
  460. cadsurfParams.SetParam("element_generation", p.surfParam_.SurfStyle.toLatin1().data());//"full_quad");//"quad_dominant");
  461. }
  462. if (!p.surfParam_.max_size.isEmpty())
  463. {
  464. cadsurfParams.SetParam("max_size", p.surfParam_.max_size.toLatin1().data());//"full_quad");//"quad_dominant");
  465. }
  466. if (!p.surfParam_.min_size.isEmpty())
  467. {
  468. cadsurfParams.SetParam("min_size", p.surfParam_.min_size.toLatin1().data());//"full_quad");//"quad_dominant");
  469. }
  470. if (!p.surfParam_.Global_physical_size.isEmpty())
  471. {
  472. cadsurfParams.SetParam("global_physical_size", p.surfParam_.Global_physical_size.toLatin1().data());//"full_quad");//"quad_dominant");
  473. }
  474. if (!p.surfParam_.gradation.isEmpty())
  475. {
  476. cadsurfParams.SetParam("gradation", p.surfParam_.gradation.toLatin1().data());//"full_quad");//"quad_dominant");
  477. }
  478. //optim
  479. if (!p.surfParam_.element_order.isEmpty())
  480. {
  481. //"full_quad");//"quad_dominant");
  482. if (p.surfParam_.element_order=="quadratic" )
  483. {
  484. cadsurfParams.SetParam("element_order", p.surfParam_.element_order.toLatin1().data());
  485. if (!p.surfParam_.scaled_jacobian_threshold_value.isEmpty())
  486. {
  487. cadsurfParams.SetParam("scaled_jacobian_threshold_value", p.surfParam_.scaled_jacobian_threshold_value.toLatin1().data());
  488. }
  489. }
  490. }
  491. if (!p.surfParam_.remove_duplicate_cad_faces.isEmpty()&& p.surfParam_.remove_duplicate_cad_faces=="no")
  492. {
  493. cadsurfParams.SetParam("remove_duplicate_cad_faces", p.surfParam_.remove_duplicate_cad_faces.toLatin1().data());
  494. }
  495. if (!p.surfParam_.correct_surface_intersections.isEmpty())
  496. {
  497. if (p.surfParam_.correct_surface_intersections=="no"&& p.surfParam_.optimisation=="yes")
  498. {
  499. cadsurfParams.SetParam("correct_surface_intersections", p.surfParam_.correct_surface_intersections.toLatin1().data());
  500. cadsurfParams.SetParam("optimisation", p.surfParam_.optimisation.toLatin1().data());
  501. }
  502. }
  503. //more setting
  504. if (!p.surfParam_.debug.isEmpty())
  505. {
  506. cadsurfParams.SetParam("debug", p.surfParam_.debug.toLatin1().data());
  507. }
  508. if (!p.surfParam_.closed_geometry.isEmpty())
  509. {
  510. cadsurfParams.SetParam("closed_geometry", p.surfParam_.closed_geometry.toLatin1().data());
  511. }
  512. if (!p.surfParam_.anisotropic_ratio.isEmpty())
  513. {
  514. cadsurfParams.SetParam("anisotropic_ratio", p.surfParam_.anisotropic_ratio.toLatin1().data());
  515. }
  516. if (!p.surfParam_.bad_surface_element_aspect_ratio.isEmpty())
  517. {
  518. cadsurfParams.SetParam("bad_surface_element_aspect_ratio", p.surfParam_.bad_surface_element_aspect_ratio.toLatin1().data());
  519. }
  520. if (!p.surfParam_.chordal_error.isEmpty())
  521. {
  522. cadsurfParams.SetParam("chordal_error", p.surfParam_.chordal_error.toLatin1().data());
  523. }
  524. if (!p.surfParam_.closed_geometry.isEmpty())
  525. {
  526. cadsurfParams.SetParam("closed_geometry", p.surfParam_.closed_geometry.toLatin1().data());
  527. }
  528. if (!p.surfParam_.discard_input_topology.isEmpty())
  529. {
  530. cadsurfParams.SetParam("discard_input_topology", p.surfParam_.discard_input_topology.toLatin1().data());
  531. }
  532. if (!p.surfParam_.create_tag_on_collision.isEmpty())
  533. {
  534. cadsurfParams.SetParam("create_tag_on_collision", p.surfParam_.create_tag_on_collision.toLatin1().data());
  535. }
  536. if (!p.surfParam_.chordal_error.isEmpty())
  537. {
  538. cadsurfParams.SetParam("chordal_error", ADIParam_.surfParam_.chordal_error.toLatin1().data());
  539. printf("chordal_error set\n");
  540. }
  541. if (!p.surfParam_.geometric_approximation_angle.isEmpty())
  542. {
  543. cadsurfParams.SetParam("geometric_approximation_angle", ADIParam_.surfParam_.geometric_approximation_angle.toLatin1().data());
  544. printf("geometric_approximation_angle set\n");
  545. }
  546. //--mg
  547. if (!p.surfParam_.physical_size_mode.isEmpty()&& p.surfParam_.physical_size_mode=="local"){
  548. USE_LOCAL_PHYSICAL_SIZE = 1;
  549. printf("print the physical_size_mode");
  550. //}else{ //if (p.surfParam_.physical_size_mode=="global"){
  551. }else if (!p.surfParam_.physical_size_mode.isEmpty()){
  552. cadsurfParams.SetParam("physical_size_mode", p.surfParam_.physical_size_mode.toLatin1().data());
  553. }
  554. if (!p.surfParam_.geometric_size_mode.isEmpty() && p.surfParam_.geometric_size_mode == "local") {
  555. USE_LOCAL_PHYSICAL_SIZE = 2;
  556. printf("print the geometric_size_mode");
  557. //}else {//if (p.surfParam_.geometric_size_mode == "global") {
  558. }else if (!p.surfParam_.geometric_size_mode.isEmpty()) {
  559. cadsurfParams.SetParam("geometric_size_mode", p.surfParam_.geometric_size_mode.toLatin1().data());
  560. printf("*** geometric_size_mode: %s\n", p.surfParam_.geometric_size_mode.toLatin1().data());
  561. }
  562. return cadsurfParams;
  563. }
  564. /**
  565. * @brief get Spa3dpm::Parameters
  566. Create a cadsurf session that will convert the
  567. Acis model(the non - regular union of two blocks and the sphere)
  568. into a surface mesh.
  569. * @param[in] ents、 cadsurf
  570. * @return bool
  571. * @author qiyan
  572. * @date 2022-11-16
  573. * @reviser
  574. * @date
  575. */
  576. bool cmdMainProcess::Createcadsurf(const ENTITY_LIST &ents, Spa3dpm::CadSurfSession &cadsurf)
  577. {
  578. exit_on_bad_outcome(api_3dpm_create_cadsurf_session(ents, cadsurf));
  579. printf("Successfully created cadsurf session\n");
  580. return true;
  581. }
  582. /**
  583. * @brief get output mesh
  584. Create a cadsurf session that will convert the
  585. Acis model(the non - regular union of two blocks and the sphere)
  586. into a surface mesh.
  587. * @param[in] ents、 cadsurf
  588. * @return bool
  589. * @author qiyan
  590. * @date 2022-11-16
  591. * @reviser
  592. * @date
  593. */
  594. bool cmdMainProcess::OutPutSurfMesh(Spa3dpm::MgSession &inSession, Spa3dpm::Mesh &outMesh, const Spa3dpm::Parameters *inParams)
  595. {
  596. printf("start created 3dpm_compute_mesh\n");
  597. exit_on_bad_outcome(api_3dpm_compute_mesh(inSession, outMesh, inParams));
  598. printf("Successfully created surface mesh\n");
  599. if (ADIParam_.bCleanerSection)//open cleaner or not
  600. {
  601. printf("start created create_cleaner_session\n");
  602. Spa3dpm::CleanerSession cleantetra;
  603. exit_on_bad_outcome(api_3dpm_create_cleaner_session(outMesh, cleantetra));
  604. Spa3dpm::Parameters cleanerParams;
  605. //--set cleaner parameter
  606. if (!ADIParam_.clrParam.folding_angle.isEmpty())
  607. {
  608. cleanerParams.SetParam("folding_angle", ADIParam_.clrParam.folding_angle.toLatin1().data());
  609. printf("cleanerParams folding_angle:\n");
  610. }
  611. if (!ADIParam_.clrParam.use_default_settings_for.isEmpty())//默认设置
  612. {
  613. cleanerParams.SetParam("use_default_settings_for", ADIParam_.clrParam.use_default_settings_for.toLatin1().data());
  614. printf("start cleaner session use_default_settings_for...\n");
  615. }else {//可编辑
  616. if (!ADIParam_.clrParam.resolution_length.isEmpty())
  617. {
  618. cleanerParams.SetParam("resolution_length", ADIParam_.clrParam.resolution_length.toLatin1().data());
  619. printf("start cleaner session resolution_length...\n");
  620. }
  621. if (!ADIParam_.clrParam.overlap_angle.isEmpty())
  622. {
  623. cleanerParams.SetParam("overlap_angle", ADIParam_.clrParam.overlap_angle.toLatin1().data());
  624. printf("start cleaner session overlap_angle...\n");
  625. }
  626. }
  627. printf("Successfully set cleaner session\n");
  628. exit_on_bad_outcome(api_3dpm_compute_mesh(cleantetra, outMesh, &cleanerParams));
  629. printf("Successfully created cleaner surface mesh\n");
  630. }
  631. return true;
  632. }
  633. /**
  634. * @brief CreateSelfGeo
  635. * --create geo for test
  636. * @param[in]
  637. * @param[out]
  638. * @return ENTITY_LIST
  639. * @author QiYan
  640. * @date 20221202
  641. */
  642. ENTITY_LIST cmdMainProcess::CreateSelfGeo()
  643. {
  644. ENTITY_LIST ents;
  645. // Create the first solid block
  646. BODY *block = nullptr;
  647. exit_on_bad_outcome(api_solid_block(SPAposition(0, 0, 0), SPAposition(10, 5, 10), block));
  648. ents.add(block);
  649. // Create a hanging face inside the first block
  650. FACE *face = nullptr;
  651. exit_on_bad_outcome(api_face_plane(SPAposition(1, 1, 5), 8, 3, &SPAvector(0.0, 0.0, 1.0), face));
  652. //exit_on_bad_outcome(api_face_plane(SPAposition(1, 1, 1), 4, 1, &SPAvector(0.0, 0.0, 1.0), face));
  653. BODY * sheet = nullptr;
  654. api_sheet_from_ff(1, &face, sheet);
  655. ents.add(sheet);
  656. //FACE *face2 = nullptr;
  657. ////exit_on_bad_outcome(api_face_plane(SPAposition(1, 1, 5), 8, 3, &SPAvector(0.0, 0.0, 1.0), face));
  658. //exit_on_bad_outcome(api_face_plane(SPAposition(2, 2, 2), 4, 1, &SPAvector(0.0, 0.0, 1.0), face2));
  659. //BODY * sheet2 = nullptr;
  660. //api_sheet_from_ff(1, &face2, sheet2);
  661. //ents.add(sheet2);
  662. // Create the second solid cube with edge length 10, adjacent to the first block
  663. BODY *cube = nullptr;
  664. exit_on_bad_outcome(api_solid_block(SPAposition(0, 5, 0), SPAposition(10, 15, 10), cube));
  665. ents.add(cube);
  666. // Create a sphere of radius 4 that lies insides the second block
  667. BODY *sphere = nullptr;
  668. exit_on_bad_outcome(api_solid_sphere(SPAposition(5, 10, 5), 4, sphere));
  669. ents.add(sphere);
  670. printf("Entity Count not unite: %d\n", ents.count());
  671. // Non-regularized unite of the blocks and the sphere. All faces are kept and used to divide the output body into cells (in Acis) and subdomains (in 3DPM).
  672. exit_on_bad_outcome(api_n_body_unite(ents, false));
  673. // Attach cellular topology to non-regular union (necessary for the Spa3dpm::Cell_VolumeElem_Assoc class below to function correctly).
  674. exit_on_bad_outcome(api_ct_attach(ents));
  675. //printf("Successfully attached cellular topology to body\n");
  676. //ENTITY_LIST cells;
  677. //api_ct_get_all_cells(ents, cells);
  678. //printf("Cells Count: %d\n", cells.count());
  679. printf("Entity Count after unite: %d\n", ents.count());
  680. return ents;
  681. }
  682. /**
  683. * @brief CreateLocalSizeMap
  684. * --use local size
  685. * @param[in]
  686. * @param[out]
  687. * @return ENTITY_LIST
  688. * @author QiYan
  689. * @date 20221202
  690. */
  691. void cmdMainProcess::CreateLocalSizeMap()
  692. {
  693. // Sizemaps to be set
  694. //USE_LOCAL_PHYSICAL_SIZE = 1;
  695. if (USE_LOCAL_PHYSICAL_SIZE==1)//physical_size_mode must be "local"
  696. {
  697. // Apply physical size functions, sizemaps应用物理尺寸函数、尺寸映射
  698. //if (!ADIParam_.surfParam_.physical_size_mode.isEmpty())
  699. //{
  700. cadsurfParams_.SetParam("physical_size_mode", ADIParam_.surfParam_.physical_size_mode.toLatin1().data());
  701. //}
  702. // default: "none"; when use_local_physical_size需要設置為 "local"
  703. // Create a sizemap associated with faces创建与面关联的尺寸映射
  704. SampleUtils_ = new DPMvolClass();
  705. if (ADIParam_.surfParam_.Global_physical_size.isEmpty())
  706. {
  707. printf("error : global_physical_size is empty!\n");
  708. return;
  709. }
  710. SampleUtils_->setGlobelSize(ADIParam_.surfParam_.Global_physical_size.toDouble());
  711. // Get pointer to native MeshGems cad_t object
  712. meshgems_cad_t *mg_cad = cadsurf_.GetMeshgemsCadPtr();
  713. if (!ADIParam_.surfParam_.physicalSizeFaceId.isEmpty())
  714. {
  715. SampleUtils_->SetLocalSizeData(2, ADIParam_.surfParam_.physicalSizeFaceId);//"1,10;2,4;");
  716. szmp_iso_face_t_ = meshgems_sizemap_new(mg_cad, meshgems_sizemap_type_iso_cad_face, SampleUtils_->size_iso_face, SampleUtils_);
  717. if (!szmp_iso_face_t_) sys_error(MESHGEMS_STATUS_NOMEM);
  718. #ifdef ADI_DEBUG_PRINT
  719. printf("Sizemap face ok \n");
  720. #endif
  721. }
  722. // Create a sizemap associated with edges
  723. if (!ADIParam_.surfParam_.physicalSizeEdgeId.isEmpty())
  724. {
  725. SampleUtils_->SetLocalSizeData(1, ADIParam_.surfParam_.physicalSizeEdgeId);
  726. szmp_iso_edge_t_ = meshgems_sizemap_new(mg_cad, meshgems_sizemap_type_iso_cad_edge, SampleUtils_->size_iso_edge, SampleUtils_); //SampleUtils_.size_iso_edge, 0);
  727. if (!szmp_iso_edge_t_) sys_error(MESHGEMS_STATUS_NOMEM);
  728. #ifdef ADI_DEBUG_PRINT
  729. printf("Sizemap edge ok \n");
  730. #endif
  731. }
  732. // Create a sizemap associated with point
  733. if (!ADIParam_.surfParam_.physicalSizePointId.isEmpty())
  734. {
  735. SampleUtils_->SetLocalSizeData(0, ADIParam_.surfParam_.physicalSizePointId);
  736. szmp_iso_point_t_ = meshgems_sizemap_new(mg_cad, meshgems_sizemap_type_iso_cad_point, SampleUtils_->size_iso_point, SampleUtils_);
  737. if (!szmp_iso_point_t_) sys_error(MESHGEMS_STATUS_NOMEM);
  738. printf("Sizemap point ok \n");
  739. }
  740. // Get MeshGems native cadsurf sessions
  741. meshgems_cadsurf_session_t *mg_cadsurf[2];
  742. cadsurf_.GetMeshgemsSessionPtr(mg_cadsurf);
  743. // Set the sizemaps to the session
  744. if (szmp_iso_face_t_) {
  745. meshgems_cadsurf_set_sizemap(mg_cadsurf[0], szmp_iso_face_t_); // index 0 is for analytical CAD
  746. }
  747. if(szmp_iso_edge_t_){
  748. meshgems_cadsurf_set_sizemap(mg_cadsurf[0], szmp_iso_edge_t_);
  749. }
  750. if (szmp_iso_point_t_){
  751. meshgems_cadsurf_set_sizemap(mg_cadsurf[0], szmp_iso_point_t_);
  752. }
  753. }else if (USE_LOCAL_PHYSICAL_SIZE==2){//geometry size mode
  754. // Apply physical size functions, sizemaps
  755. //if (!ADIParam_.surfParam_.physical_size_mode.isEmpty())
  756. //{
  757. cadsurfParams_.SetParam("geometric_size_mode", ADIParam_.surfParam_.geometric_size_mode.toLatin1().data());
  758. //}
  759. // default: "none"; when use_local_physical_size需要設置為 "local"
  760. // Create a sizemap associated with faces
  761. SampleUtils_ = new DPMvolClass();
  762. if (ADIParam_.surfParam_.Global_physical_size.isEmpty())
  763. {
  764. printf("error : global_physical_size is empty!");
  765. return;
  766. }
  767. SampleUtils_->setGlobelSize(ADIParam_.surfParam_.Global_physical_size.toDouble());
  768. // Get pointer to native MeshGems cad_t object
  769. meshgems_cad_t *mg_cad = cadsurf_.GetMeshgemsCadPtr();
  770. if (!ADIParam_.surfParam_.geometricSizeFaceId.isEmpty())
  771. {
  772. SampleUtils_->SetLocalSizeData(2, ADIParam_.surfParam_.geometricSizeFaceId);//"1,10;2,4;");
  773. szmp_iso_face_t_ = meshgems_sizemap_new(mg_cad, meshgems_sizemap_type_iso_cad_face, SampleUtils_->size_iso_face, SampleUtils_);
  774. if (!szmp_iso_face_t_) sys_error(MESHGEMS_STATUS_NOMEM);
  775. #ifdef ADI_DEBUG_PRINT
  776. printf("Sizemap face ok \n");
  777. #endif
  778. }
  779. // Create a sizemap associated with edges
  780. if (!ADIParam_.surfParam_.geometricSizeEdgeId.isEmpty())
  781. {
  782. SampleUtils_->SetLocalSizeData(1, ADIParam_.surfParam_.geometricSizeEdgeId);
  783. szmp_iso_edge_t_ = meshgems_sizemap_new(mg_cad, meshgems_sizemap_type_iso_cad_edge, SampleUtils_->size_iso_edge, SampleUtils_); //SampleUtils_.size_iso_edge, 0);
  784. if (!szmp_iso_edge_t_) sys_error(MESHGEMS_STATUS_NOMEM);
  785. #ifdef ADI_DEBUG_PRINT
  786. printf("Sizemap edge ok \n");
  787. #endif
  788. }
  789. // Create a sizemap associated with point创建与点关联的尺寸映射
  790. if (!ADIParam_.surfParam_.geometricSizePointId.isEmpty())
  791. {
  792. SampleUtils_->SetLocalSizeData(0, ADIParam_.surfParam_.geometricSizePointId);
  793. szmp_iso_point_t_ = meshgems_sizemap_new(mg_cad, meshgems_sizemap_type_iso_cad_point, SampleUtils_->size_iso_point, SampleUtils_);
  794. if (!szmp_iso_point_t_) sys_error(MESHGEMS_STATUS_NOMEM);
  795. printf("Sizemap point ok \n");
  796. }
  797. // Get MeshGems native cadsurf sessions
  798. meshgems_cadsurf_session_t *mg_cadsurf[2];
  799. cadsurf_.GetMeshgemsSessionPtr(mg_cadsurf);
  800. // Set the sizemaps to the session
  801. if (szmp_iso_face_t_) {
  802. meshgems_cadsurf_set_sizemap(mg_cadsurf[0], szmp_iso_face_t_); // index 0 is for analytical CAD
  803. }
  804. if (szmp_iso_edge_t_) {
  805. meshgems_cadsurf_set_sizemap(mg_cadsurf[0], szmp_iso_edge_t_);
  806. }
  807. if (szmp_iso_point_t_) {
  808. meshgems_cadsurf_set_sizemap(mg_cadsurf[0], szmp_iso_point_t_);
  809. }
  810. }
  811. // Periodic Meshing / Mesh Matching周期性网格划分/网格匹配
  812. // Refer to "Section 4.3.7 Setting any CAD mesh matching specifications" in mg-cadsurf_user_manual.pdf for more examples
  813. if (APPLY_PERIODICITY)
  814. {
  815. if (SampleUtils_->apply_reflection_periodicity(cadsurf_))
  816. printf("Successfully applied mesh periodicity settings\n");
  817. else
  818. printf("Failed to apply mesh periodicity settings\n");
  819. }
  820. }
  821. /**
  822. * @brief createVol
  823. * --choose mesh style
  824. * @param[in]istyle ,cells
  825. style :
  826. 1:tetra;2:hexa;3:hybird
  827. cell:
  828. * @param[out]
  829. * @return ENTITY_LIST
  830. * @author QiYan
  831. * @date 20221202
  832. */
  833. void cmdMainProcess::createVol(int istyle,ENTITY_LIST &cells)
  834. {
  835. if (istyle==1){//四面体网格
  836. USE_TETRA = 1;
  837. USE_HEXA = 0;
  838. USE_HYBIRD = 0;
  839. }else if (istyle == 2){//六面体网格
  840. USE_HEXA = 1;
  841. USE_TETRA = 0;
  842. USE_HYBIRD = 0;
  843. }else if(istyle==3){//混合网格划分
  844. USE_HYBIRD = 1;
  845. USE_TETRA = 0;
  846. USE_HEXA = 0;
  847. }else {
  848. return;
  849. }
  850. if (USE_HEXA == 1)
  851. {
  852. USE_TETRA = 0;
  853. APPLY_PERIODICITY = 0;
  854. USE_LOCAL_PHYSICAL_SIZE = 0;
  855. }else{
  856. if (USE_HYBIRD == 0)
  857. {
  858. USE_TETRA = 1; // Make sure at least one type of volume mesh is chosen
  859. }
  860. }
  861. printf("USE_TETRA = %d\n", USE_TETRA);
  862. printf("USE_HEXA = %d\n", USE_HEXA);
  863. printf("USE_HYBIRD = %d\n", USE_HYBIRD);
  864. if (APPLY_PERIODICITY)
  865. {
  866. //// Mesh Matching of two periodic faces (reflection) with IDs 1 and 5
  867. //if (verify_mesh_periodicity(surfMesh_.GetMeshgemsMeshPtr(), 1, 5))
  868. // printf("Successfully verified mesh periodicity\n");
  869. //else
  870. // printf("Failed to verify mesh periodicity\n");
  871. }
  872. // Create the volume mesh.
  873. Spa3dpm::Mesh volMesh;
  874. Spa3dpm::Cell_VolumeElem_Assoc::VolumeElemType currentVolElemType = Spa3dpm::Cell_VolumeElem_Assoc::Tetra;
  875. std::string strElemType;
  876. // Create "user_data" for set_subdomain_description callback
  877. // Keep it in higher scope since other MeshGems functions may use this user_data
  878. std::vector<int> surfMeshFaceIndices;
  879. if (USE_HEXA)
  880. {
  881. // Specify the mesh element type
  882. strElemType = "Hexahedron";
  883. currentVolElemType = Spa3dpm::Cell_VolumeElem_Assoc::Hexa;
  884. // Set 3DPM-Hexa parameters
  885. Spa3dpm::Parameters hexaParams;
  886. if (ADIParam_.hexaParam.components.isEmpty())
  887. {
  888. printf(" hexaParam.components is empty!");
  889. return;
  890. }
  891. hexaParams.SetParam("components", ADIParam_.hexaParam.components.toLatin1().data()); // all connected components will be meshed
  892. printf("tags %s\n", ADIParam_.hexaParam.components.toLatin1().data());
  893. //hexaParams.SetParam("tags", "respect");
  894. if (!ADIParam_.hexaParam.min_size.isEmpty())
  895. {
  896. hexaParams.SetParam("min_size", ADIParam_.hexaParam.min_size.toLatin1().data());
  897. }
  898. if (!ADIParam_.hexaParam.max_size.isEmpty())
  899. {
  900. hexaParams.SetParam("max_size", ADIParam_.hexaParam.max_size.toLatin1().data());
  901. }
  902. //ADIParam_.hexaParam.min_size.toLatin1().data());// hexaParams.SetParam("manifold_geometry", "no"); // critical to mesh non-manifold bodies
  903. //printf("min_size %s\n", ADIParam_.hexaParam.min_size.toStdString());
  904. hexaParams.SetParam("verbose", "3"); // allows the user to raise the amount of information sent to the callback during the mesh generation process (default 3)
  905. //hexaParams.SetParam("min_size", "0.0001");
  906. // Current 3DPM-Hexa Limitation:
  907. // - subdomain description needs to be manually set for non-manifold regions in 3DPM-Hexa
  908. // to tag the subdomains in a similar fashion to 3DPM-Tetra and 3DPM-Tetra_HPC results (with 1, 2, 3, ...)
  909. // Helper function to find seed surface elements and populate "surfMeshFaceIndices" for setting the subdomain description
  910. //if (SampleUtils_ == NULL)
  911. //{
  912. // SampleUtils_ = new ADI3DPMNameSpace::DPMvolClass();
  913. //}
  914. //if (SampleUtils_->find_subdomain_seed_from_ct(cadsurf_, surfMesh_, cells, surfMeshFaceIndices))
  915. // printf("Successfully found seeds to set hexahedral subdomain description\n");
  916. //
  917. //// Set subdomain description on the input surface mesh
  918. //// Hexa will use this information to tag generated hexa elements accordingly
  919. //meshgems_mesh_t *mg_surf_mesh = surfMesh_.GetMeshgemsMeshPtr();
  920. //// Set subdomain count
  921. //meshgems_mesh_set_subdomain_count(mg_surf_mesh, cells.count()); // assume CELL count is equal to mesh subdomain count
  922. //
  923. ////qy // Set subdomain description
  924. //
  925. //meshgems_status_t setRes = meshgems_mesh_set_get_subdomain_description(mg_surf_mesh, (meshgems_mesh_get_subdomain_description_t)(SampleUtils_->hexa_mesh_get_subdomain_description_impl), &surfMeshFaceIndices);
  926. //printf("set_get_subdoamin_description was set: %s\n", ((setRes == MESHGEMS_STATUS_OK) ? "true" : "false"));
  927. //
  928. // Create Hexa session
  929. Spa3dpm::HexaSession hexa;
  930. exit_on_bad_outcome(api_3dpm_create_hexa_session(surfMesh_, hexa));
  931. printf("Successfully created hexa session\n");
  932. exit_on_bad_outcome(api_3dpm_compute_mesh(hexa, volMesh, &hexaParams));
  933. printf("Successfully created volume mesh\n");
  934. printf("Total Hexahedron count: %d\n", volMesh.HexahedronCount());
  935. // Get callback messages from Hexa session (optional)
  936. //get_mg_messages(dynamic_cast<Spa3dpm::MgSession&>(hexa));
  937. }
  938. if (USE_TETRA)
  939. {
  940. // Create a tetrahedral mesh
  941. strElemType = "Tetrahedron";
  942. currentVolElemType = Spa3dpm::Cell_VolumeElem_Assoc::Tetra;
  943. // Create a tetra session that will convert the MeshGems surface mesh into a MeshGems volume mesh containing tetrahedra only.
  944. Spa3dpm::TetraHpcSession tetra;
  945. exit_on_bad_outcome(api_3dpm_create_tetra_hpc_session(surfMesh_, tetra));
  946. printf("Successfully created tetra session\n");
  947. // Set Tetra Parameters
  948. Spa3dpm::Parameters tetParams;
  949. tetParams.SetParam("components", ADIParam_.tetraParam.components.toLatin1().data());//"all"); // all connected components will be meshed
  950. tetParams.SetParam("gradation", ADIParam_.tetraParam.gradation.toLatin1().data()); // critical to g enerate volume elements with uniform sizes set in the input surface mesh
  951. tetParams.SetParam("verbose", "10");
  952. tetParams.SetParam("max_number_of_threads", "8");
  953. tetParams.SetParam("number_of_subdomains", "1");
  954. if (!ADIParam_.tetraParam.min_size.isEmpty())
  955. {
  956. tetParams.SetParam("min_size", ADIParam_.tetraParam.min_size.toLatin1().data());
  957. printf("tetParams min_size:\n");
  958. }
  959. if (!ADIParam_.tetraParam.max_size.isEmpty())
  960. {
  961. tetParams.SetParam("max_size", ADIParam_.tetraParam.max_size.toLatin1().data());
  962. }
  963. exit_on_bad_outcome(api_3dpm_compute_mesh(tetra, volMesh, &tetParams));
  964. printf("Successfully created volume mesh\n");
  965. printf("Total Tetrahedron count: %d\n", volMesh.TetrahedronCount());
  966. }
  967. if (USE_HYBIRD)
  968. {
  969. // Create a Hybird mesh
  970. strElemType = "Hybrid";
  971. currentVolElemType = Spa3dpm::Cell_VolumeElem_Assoc::Tetra;
  972. // Create a tetra session that will convert the MeshGems surface mesh into a MeshGems volume mesh containing tetrahedra only.
  973. Spa3dpm::HybridSession Hybird;
  974. exit_on_bad_outcome(api_3dpm_create_hybrid_session(surfMesh_, Hybird));
  975. printf("Successfully created Hybird session\n");
  976. // Set Tetra Parameters
  977. Spa3dpm::Parameters HybirdParams;
  978. if (!ADIParam_.hybridParam.HybridStyle.isEmpty())
  979. {
  980. HybirdParams.SetParam("element_generation", ADIParam_.hybridParam.HybridStyle.toLatin1().data());
  981. }
  982. if (!ADIParam_.hybridParam.number_of_boundary_layers.isEmpty())
  983. {
  984. HybirdParams.SetParam("number_of_boundary_layers", ADIParam_.hybridParam.number_of_boundary_layers.toLatin1().data());
  985. }
  986. if (!ADIParam_.hybridParam.normal_direction.isEmpty())
  987. {
  988. HybirdParams.SetParam("normal_direction", ADIParam_.hybridParam.normal_direction.toLatin1().data());
  989. }
  990. if (!ADIParam_.hybridParam.boundary_layer_global_initial_height.isEmpty())
  991. {
  992. HybirdParams.SetParam("boundary_layer_global_initial_height", ADIParam_.hybridParam.boundary_layer_global_initial_height.toLatin1().data());
  993. }
  994. if (!ADIParam_.hybridParam.boundary_layer_geometric_progression.isEmpty())
  995. {
  996. HybirdParams.SetParam("boundary_layer_geometric_progression", ADIParam_.hybridParam.boundary_layer_geometric_progression.toLatin1().data());
  997. }
  998. exit_on_bad_outcome(api_3dpm_compute_mesh(Hybird, volMesh, &HybirdParams));
  999. printf("Successfully created volume mesh\n");
  1000. printf("Total Tetrahedron count: %d\n", volMesh.TetrahedronCount());
  1001. }
  1002. //print_mesh_info(volMesh); // optional
  1003. //Save the volumen mesh to .mesh (optional)
  1004. exit_on_bad_outcome(api_3dpm_save_mesh(volMesh, "3dpmSample_volMesh.mesh"));
  1005. printf("Successfully wrote VolMesh to .mesh format\n\n");
  1006. //// Extract CAD-Mesh associativity information
  1007. //meshgems_mesh_t *mg_mesh = volMesh.GetMeshgemsMeshPtr();
  1008. //meshgems_integer numSubdomain = -1;
  1009. //if (MESHGEMS_STATUS_IS_ERROR(meshgems_mesh_get_subdomain_count(mg_mesh, &numSubdomain)))
  1010. // sys_error(SPA3DPM_GENERIC_FAILURE);
  1011. //printf("Number of subdomains in mesh: %d\n", numSubdomain);
  1012. //// Create the association class between ACIS cells and MeshGems subdomains.
  1013. //Spa3dpm::Cell_VolumeElem_Assoc volumeAssoc;
  1014. //exit_on_bad_outcome(api_3dpm_create_volume_assoc(volMesh, volumeAssoc));
  1015. //printf("Successfully created volume element association object\n");
  1016. //// The following code demonstrates how to:
  1017. //// 1. Get the ACIS cell from a volume element index (Here, we are using the first element in the mesh)
  1018. //// 2. Get all volume elements associated with that ACIS cell and print out available information
  1019. //Spa3dpm::Cell_VolumeElem_Assoc::VolumeElemArray volElemArray;
  1020. //int seedElemIndex = 1;
  1021. //CELL *cell = volumeAssoc.FindCell(Spa3dpm::Cell_VolumeElem_Assoc::VolumeElem(currentVolElemType, seedElemIndex));
  1022. //volumeAssoc.FindVolumeElements(cell, volElemArray);
  1023. //// Cycle through the list of volume elements in the cell that contains the volume element with index 1.
  1024. //auto sz = volElemArray.Size();
  1025. //printf("Number of elements in the cell containing %s with index 1: %zu\n", strElemType.c_str(), sz);
  1026. //printf("List of elements in the cell containing %s with index 1:", strElemType.c_str());
  1027. //for (decltype(sz) i = 0; i < sz; i++)
  1028. //{
  1029. // if (i % 6 == 0)
  1030. // printf("\n\t(");
  1031. // else
  1032. // printf(", (");
  1033. // switch (volElemArray[i].elemType)
  1034. // {
  1035. // case Spa3dpm::Cell_VolumeElem_Assoc::Tetra:
  1036. // printf("tetra");
  1037. // break;
  1038. // case Spa3dpm::Cell_VolumeElem_Assoc::Hexa:
  1039. // printf("hexa");
  1040. // break;
  1041. // case Spa3dpm::Cell_VolumeElem_Assoc::Pyramid:
  1042. // printf("pyramid");
  1043. // break;
  1044. // case Spa3dpm::Cell_VolumeElem_Assoc::Prism:
  1045. // printf("prism");
  1046. // break;
  1047. // }
  1048. // printf(", #%d)", volElemArray[i].elemIndex);
  1049. //}
  1050. //printf("\n");
  1051. QString dDir = QDir::currentPath();
  1052. QString appPath = dDir + "\\Data\\";
  1053. QDateTime data = QDateTime::currentDateTime();
  1054. QString strName;
  1055. CRWriteFile* crw = new CRWriteFile();
  1056. if (ADIParam_.strResultFormat == ".ugrid")
  1057. {
  1058. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "VolResult.ugrid";
  1059. crw->WirteUgridFoamFile(volMesh, QString(appPath + strName).toLatin1());
  1060. }else if (ADIParam_.strResultFormat == ".vtk") {
  1061. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "VolResult.vtk";
  1062. crw->WirteVtkFoamFile(volMesh, QString(appPath + strName).toLatin1());
  1063. }else if (ADIParam_.strResultFormat == ".bdf") {
  1064. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "VolResult.bdf";
  1065. crw->WirteBDFFoamFile(volMesh, QString(appPath + strName).toLatin1());
  1066. }
  1067. else if (ADIParam_.strResultFormat == ".neu") {
  1068. strName = data.toString("yyyy_MM_dd_HH_mm_ss") + "VolResult.neu";
  1069. crw->WriteNeuFoamFile(volMesh, QString(appPath + strName).toLatin1());
  1070. }
  1071. exit_on_bad_outcome(api_3dpm_save_mesh(surfMesh_, "3dpmSample_surfMesh.mesh"));
  1072. printf("Successfully wrote vol to .mesh format\n");
  1073. //-----
  1074. //7.start show for qy --only for self show
  1075. QProcess *process = new QProcess;
  1076. process->setWorkingDirectory("F:\\czm\\qt_demo\\build-test_hoops-Desktop_Qt_5_12_0_MSVC2015_64bit-Debug\\debug\\gmsh");
  1077. QStringList strLName;
  1078. strLName << QString(appPath + strName);
  1079. process->start("F:\\czm\\qt_demo\\build-test_hoops-Desktop_Qt_5_12_0_MSVC2015_64bit-Debug\\debug\\gmsh\\win\\gmsh-git-Windows64-sdk\\bin\\gmsh.exe", strLName);
  1080. if(crw!=NULL){
  1081. delete crw;
  1082. crw = NULL;
  1083. }
  1084. }
  1085. //-callbacke
  1086. //static meshgems_status_t cmdMainProcess::size_iso_edge(meshgems_integer edge_id, meshgems_real t, meshgems_real *size, void *user_data)
  1087. //{
  1088. // Acis3dpmSampleUtils::size_iso_edge;
  1089. //}