js_ext_comx_cascade_render.cc 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. #include <comx_napi.hxx>
  2. #include <type_cast.hxx>
  3. using namespace KMAS::type;
  4. using namespace comx::napi;
  5. #include <fstream>
  6. #include <iostream>
  7. #include <map>
  8. #include <set>
  9. #include <string>
  10. #include <vector>
  11. using namespace std;
  12. #include <map>
  13. #include <set>
  14. #include <string>
  15. #include <vector>
  16. using namespace std;
  17. #include <base/function.hxx>
  18. #include <base/type_cast.hxx>
  19. using namespace KMAS::type;
  20. // Open Cascade library.
  21. #include <BRepBuilderAPI_MakeEdge.hxx>
  22. #include <BRepBuilderAPI_MakeFace.hxx>
  23. #include <BRepBuilderAPI_MakeWire.hxx>
  24. #include <BRepPrimAPI_MakeBox.hxx>
  25. #include <BRepPrimAPI_MakeCone.hxx>
  26. #include <BRepPrimAPI_MakeCylinder.hxx>
  27. #include <BRepPrimApI_MakeSphere.hxx>
  28. #include <BRepTools.hxx>
  29. #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
  30. #include <BRep_Tool.hxx>
  31. #include <Brep_TEdge.hxx>
  32. #include <Standard.hxx>
  33. #include <Standard_DefineAlloc.hxx>
  34. #include <Standard_Handle.hxx>
  35. #include <Standard_TypeDef.hxx>
  36. #include <TopTools_HSequenceOfShape.hxx>
  37. #include <TopTools_ListIteratorOfListOfShape.hxx>
  38. #include <TopoDS.hxx>
  39. #include <TopoDS_Edge.hxx>
  40. #include <TopoDS_Face.hxx>
  41. #include <TopoDS_Wire.hxx>
  42. #include <gp_Pln.hxx>
  43. #include <gp_Pnt.hxx>
  44. // #include <BRepMesh.hxx>
  45. #include <BRepMesh_IncrementalMesh.hxx>
  46. #include <Poly_Triangulation.hxx>
  47. #include <TShort_Array1OfShortReal.hxx>
  48. #include <TopExp.hxx>
  49. #include <TopExp_Explorer.hxx>
  50. #include <Poly.hxx>
  51. #include <Poly_Connect.hxx>
  52. #include <Poly_Triangulation.hxx>
  53. #include <Geom2dAdaptor.hxx>
  54. #include <Geom2dAdaptor_curve.hxx>
  55. #include <GeomAdaptor.hxx>
  56. #include <GeomAdaptor_curve.hxx>
  57. #include <BRepBuilderAPI_NurbsConvert.hxx>
  58. #include <Geom2dConvert.hxx>
  59. #include <Geom2d_TrimmedCurve.hxx>
  60. #include <Geom_Plane.hxx>
  61. #include <BRepLib_FindSurface.hxx>
  62. #include <GeomConvert.hxx>
  63. #include <Geom_BSplineSurface.hxx>
  64. #include <BRepLib.hxx>
  65. #include <GeomLib.hxx>
  66. #include <AIS_Shape.hxx>
  67. #include <BRepAdaptor_Curve.hxx>
  68. #include <BRepBuilderAPI_Sewing.hxx>
  69. #include <CPnts_AbscissaPoint.hxx>
  70. #include <IMeshTools_Parameters.hxx>
  71. #include <Poly_Polygon3D.hxx>
  72. #include <Quantity_Color.hxx>
  73. #include <ModelIO/CurveAdaptiveDiscrete.h>
  74. #include <ModelIO/ModelIO.h>
  75. // TopTools_HSequenceOfShape g_aHSequenceOfShape;//new
  76. // TopTools_HSequenceOfShape();
  77. ////////////////////////////////////////////////////////////////////////////
  78. // system pre-define segment, please don't modify the following codes.
  79. JS_EXT_DATA_DECLARE()
  80. ///////////////////////////////////////////////////////////////////////////
  81. // implement RenderToGLCache function
  82. struct point_t {
  83. Standard_Real x, y, z;
  84. public:
  85. point_t(Standard_Real vx = 0., Standard_Real vy = 0.,
  86. Standard_Real vz = 0.)
  87. : x(vx), y(vy), z(vz) {}
  88. };
  89. template <typename T> void ExportArray2File(string fileName, T arr) {
  90. ofstream exportFile;
  91. exportFile.open(fileName.c_str(), ios::out);
  92. for (int i = 0; i < arr.size(); i++) {
  93. exportFile << arr[i] << endl;
  94. }
  95. exportFile.close();
  96. }
  97. void ComputeNormals(const TopoDS_Face &theFace,
  98. const Handle(Poly_Triangulation) & theTris,
  99. Poly_Connect &thePolyConnect,
  100. vector<KMAS::vector3d_t> &ret) {
  101. if (theTris.IsNull() || theTris->HasNormals()) {
  102. return;
  103. }
  104. // take in face the surface location
  105. const TopoDS_Face aZeroFace =
  106. TopoDS::Face(theFace.Located(TopLoc_Location()));
  107. Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aZeroFace);
  108. const Poly_Array1OfTriangle &aTriangles = theTris->Triangles();
  109. if (!theTris->HasUVNodes() || aSurf.IsNull()) {
  110. // compute normals by averaging triangulation normals sharing
  111. // the same vertex
  112. Poly::ComputeNormals(theTris);
  113. return;
  114. }
  115. const Standard_Real aTol = Precision::Confusion();
  116. // Handle(TShort_HArray1OfShortReal) aNormals = new
  117. // TShort_HArray1OfShortReal(1, theTris->NbNodes() * 3);
  118. const TColgp_Array1OfPnt2d &aNodesUV = theTris->UVNodes();
  119. Standard_Integer aTri[3];
  120. const TColgp_Array1OfPnt &aNodes = theTris->Nodes();
  121. gp_Dir aNorm;
  122. for (Standard_Integer aNodeIter = aNodes.Lower();
  123. aNodeIter <= aNodes.Upper(); ++aNodeIter) {
  124. // try to retrieve normal from real surface first, when UV
  125. // coordinates are available
  126. if (GeomLib::NormEstim(aSurf, aNodesUV.Value(aNodeIter), aTol,
  127. aNorm) > 1) {
  128. if (thePolyConnect.Triangulation() != theTris) {
  129. thePolyConnect.Load(theTris);
  130. }
  131. // compute flat normals
  132. gp_XYZ eqPlan(0.0, 0.0, 0.0);
  133. for (thePolyConnect.Initialize(aNodeIter);
  134. thePolyConnect.More(); thePolyConnect.Next()) {
  135. aTriangles(thePolyConnect.Value())
  136. .Get(aTri[0], aTri[1], aTri[2]);
  137. const gp_XYZ v1(aNodes(aTri[1]).Coord() -
  138. aNodes(aTri[0]).Coord());
  139. const gp_XYZ v2(aNodes(aTri[2]).Coord() -
  140. aNodes(aTri[1]).Coord());
  141. const gp_XYZ vv = v1 ^ v2;
  142. const Standard_Real aMod = vv.Modulus();
  143. if (aMod >= aTol) {
  144. eqPlan += vv / aMod;
  145. }
  146. }
  147. const Standard_Real aModMax = eqPlan.Modulus();
  148. aNorm = (aModMax > aTol) ? gp_Dir(eqPlan) : gp::DZ();
  149. }
  150. KMAS::vector3d_t nor;
  151. nor.x = aNorm.X();
  152. nor.y = aNorm.Y();
  153. nor.z = aNorm.Z();
  154. ret.push_back(nor);
  155. }
  156. }
  157. bool IsPlanar(const TopoDS_Face &objFace) {
  158. Handle(Geom_Surface) surface = BRep_Tool::Surface(objFace);
  159. if (surface->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
  160. return true;
  161. }
  162. return false;
  163. }
  164. bool CreateGlBuffer4Face(const TopoDS_Face &objFace, vector<double> &triangles,
  165. vector<double> &triangles_normal) {
  166. TopLoc_Location location;
  167. opencascade::handle<Poly_Triangulation> triFace =
  168. BRep_Tool::Triangulation(objFace, location);
  169. if (triFace.IsNull()) {
  170. BRepMesh_IncrementalMesh(objFace, 0.01);
  171. triFace = BRep_Tool::Triangulation(objFace, location);
  172. if (triFace.IsNull()) {
  173. return false;
  174. }
  175. }
  176. vector<KMAS::vector3d_t> normals;
  177. ComputeNormals(objFace, triFace, Poly_Connect(), normals);
  178. Standard_Integer nTriangles = triFace->NbTriangles();
  179. gp_Pnt vertex1;
  180. gp_Pnt vertex2;
  181. gp_Pnt vertex3;
  182. Standard_Integer nVertexIndex1 = 0;
  183. Standard_Integer nVertexIndex2 = 0;
  184. Standard_Integer nVertexIndex3 = 0;
  185. TColgp_Array1OfPnt nodes(1, triFace->NbNodes());
  186. Poly_Array1OfTriangle objTriangles(1, triFace->NbTriangles());
  187. nodes = triFace->Nodes();
  188. objTriangles = triFace->Triangles();
  189. for (Standard_Integer i = 1; i <= triFace->NbTriangles(); i++) {
  190. Poly_Triangle aTriangle = objTriangles.Value(i);
  191. aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);
  192. vertex1 = nodes.Value(nVertexIndex1)
  193. .Transformed(location.Transformation());
  194. vertex2 = nodes.Value(nVertexIndex2)
  195. .Transformed(location.Transformation());
  196. vertex3 = nodes.Value(nVertexIndex3)
  197. .Transformed(location.Transformation());
  198. point_t pt1(vertex1.X(), vertex1.Y(), vertex1.Z());
  199. point_t pt2(vertex2.X(), vertex2.Y(), vertex2.Z());
  200. point_t pt3(vertex3.X(), vertex3.Y(), vertex3.Z());
  201. triangles.push_back(pt1.x);
  202. triangles.push_back(pt1.y);
  203. triangles.push_back(pt1.z);
  204. KMAS::vector3d_t nor1 = normals[nVertexIndex1 - 1];
  205. triangles_normal.push_back(nor1.x);
  206. triangles_normal.push_back(nor1.y);
  207. triangles_normal.push_back(nor1.z);
  208. triangles.push_back(pt2.x);
  209. triangles.push_back(pt2.y);
  210. triangles.push_back(pt2.z);
  211. KMAS::vector3d_t nor2 = normals[nVertexIndex2 - 1];
  212. triangles_normal.push_back(nor2.x);
  213. triangles_normal.push_back(nor2.y);
  214. triangles_normal.push_back(nor2.z);
  215. triangles.push_back(pt3.x);
  216. triangles.push_back(pt3.y);
  217. triangles.push_back(pt3.z);
  218. KMAS::vector3d_t nor3 = normals[nVertexIndex3 - 1];
  219. triangles_normal.push_back(nor3.x);
  220. triangles_normal.push_back(nor3.y);
  221. triangles_normal.push_back(nor3.z);
  222. }
  223. return true;
  224. }
  225. bool CreateGlBuffer4FaceEx(const TopoDS_Face &objFace, vector<double> &points,
  226. vector<double> &vnormals, vector<int> &triangles) {
  227. TopLoc_Location location;
  228. opencascade::handle<Poly_Triangulation> triFace =
  229. BRep_Tool::Triangulation(objFace, location);
  230. if (triFace.IsNull()) {
  231. cout << "triFace is Null" << endl;
  232. BRepMesh_IncrementalMesh(objFace, 0.01);
  233. triFace = BRep_Tool::Triangulation(objFace, location);
  234. if (triFace.IsNull()) {
  235. return false;
  236. }
  237. }
  238. vector<KMAS::vector3d_t> normals;
  239. ComputeNormals(objFace, triFace, Poly_Connect(), normals);
  240. vnormals.resize(normals.size() * 3);
  241. copy(&normals[0].x, &normals[0].x + normals.size() * 3, &vnormals[0]);
  242. Standard_Integer nTriangles = triFace->NbTriangles();
  243. Standard_Integer nVertexIndex1 = 0;
  244. Standard_Integer nVertexIndex2 = 0;
  245. Standard_Integer nVertexIndex3 = 0;
  246. TColgp_Array1OfPnt nodes(1, triFace->NbNodes());
  247. Poly_Array1OfTriangle objTriangles(1, triFace->NbTriangles());
  248. nodes = triFace->Nodes();
  249. points.resize(nodes.Size() * 3);
  250. for (int nid = 0; nid < nodes.Size(); ++nid) {
  251. gp_Pnt vertex =
  252. nodes.Value(nid + 1).Transformed(location.Transformation());
  253. points[nid * 3 + 0] = vertex.X();
  254. points[nid * 3 + 1] = vertex.Y();
  255. points[nid * 3 + 2] = vertex.Z();
  256. }
  257. objTriangles = triFace->Triangles();
  258. triangles.clear();
  259. for (Standard_Integer i = 1; i <= triFace->NbTriangles(); i++) {
  260. Poly_Triangle aTriangle = objTriangles.Value(i);
  261. aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);
  262. triangles.push_back(nVertexIndex1 - 1);
  263. triangles.push_back(nVertexIndex2 - 1);
  264. triangles.push_back(nVertexIndex3 - 1);
  265. }
  266. return true;
  267. }
  268. bool CreateGlBuffer4FaceEdge(const TopoDS_Face &objFace, vector<double> &points,
  269. vector<double> &vnormals, vector<int> &lines) {
  270. TopLoc_Location location;
  271. opencascade::handle<Poly_Triangulation> triFace =
  272. BRep_Tool::Triangulation(objFace, location);
  273. if (triFace.IsNull()) {
  274. BRepMesh_IncrementalMesh(objFace, 0.01);
  275. triFace = BRep_Tool::Triangulation(objFace, location);
  276. if (triFace.IsNull()) {
  277. return false;
  278. }
  279. }
  280. vector<KMAS::vector3d_t> normals;
  281. ComputeNormals(objFace, triFace, Poly_Connect(), normals);
  282. vnormals.resize(normals.size() * 3);
  283. copy(&normals[0].x, &normals[0].x + normals.size() * 3, &vnormals[0]);
  284. Standard_Integer nTriangles = triFace->NbTriangles();
  285. Standard_Integer nVertexIndex1 = 0;
  286. Standard_Integer nVertexIndex2 = 0;
  287. Standard_Integer nVertexIndex3 = 0;
  288. TColgp_Array1OfPnt nodes(1, triFace->NbNodes());
  289. Poly_Array1OfTriangle objTriangles(1, triFace->NbTriangles());
  290. nodes = triFace->Nodes();
  291. points.resize(nodes.Size() * 3);
  292. for (int nid = 0; nid < nodes.Size(); ++nid) {
  293. gp_Pnt vertex =
  294. nodes.Value(nid + 1).Transformed(location.Transformation());
  295. points[nid * 3 + 0] = vertex.X();
  296. points[nid * 3 + 1] = vertex.Y();
  297. points[nid * 3 + 2] = vertex.Z();
  298. }
  299. objTriangles = triFace->Triangles();
  300. lines.clear();
  301. for (Standard_Integer i = 1; i <= triFace->NbTriangles(); i++) {
  302. Poly_Triangle aTriangle = objTriangles.Value(i);
  303. aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);
  304. // triangles.push_back(nVertexIndex1 - 1);
  305. // triangles.push_back(nVertexIndex2 - 1);
  306. // triangles.push_back(nVertexIndex3 - 1);
  307. lines.push_back(nVertexIndex1 - 1);
  308. lines.push_back(nVertexIndex2 - 1);
  309. lines.push_back(nVertexIndex2 - 1);
  310. lines.push_back(nVertexIndex3 - 1);
  311. lines.push_back(nVertexIndex3 - 1);
  312. lines.push_back(nVertexIndex1 - 1);
  313. }
  314. return true;
  315. }
  316. void CreateGlBuffer4Edge(const TopoDS_Edge &objEdge, vector<double> &lines) {
  317. Standard_Real firstParam, lastParam;
  318. TopLoc_Location location;
  319. Handle(Geom_Curve) curve3D =
  320. BRep_Tool::Curve(objEdge, location, firstParam, lastParam);
  321. TopAbs_ShapeEnum t = objEdge.ShapeType();
  322. lines.clear();
  323. if (curve3D.IsNull()) {
  324. return;
  325. }
  326. GeomAdaptor_Curve adaptedCurve(curve3D);
  327. int LINE_SEG_NUM = 100;
  328. Standard_Real rParaStep = (lastParam - firstParam) / LINE_SEG_NUM;
  329. for (Standard_Integer i = 0; i < LINE_SEG_NUM; ++i) {
  330. gp_Pnt firstPoint, lastPoint;
  331. Standard_Real p1 = firstParam + i * rParaStep;
  332. Standard_Real p2 = firstParam + (i + 1) * rParaStep;
  333. adaptedCurve.D0(p1, firstPoint);
  334. adaptedCurve.D0(p2, lastPoint);
  335. firstPoint = firstPoint.Transformed(location.Transformation());
  336. lastPoint = lastPoint.Transformed(location.Transformation());
  337. lines.push_back(firstPoint.X());
  338. lines.push_back(firstPoint.Y());
  339. lines.push_back(firstPoint.Z());
  340. lines.push_back(lastPoint.X());
  341. lines.push_back(lastPoint.Y());
  342. lines.push_back(lastPoint.Z());
  343. }
  344. }
  345. void GetGlBuffer4Edge(const TopoDS_Edge &E, vector<double> &points,
  346. vector<int> &lines) {
  347. TopLoc_Location L;
  348. opencascade::handle<Poly_Polygon3D> edge = BRep_Tool::Polygon3D(E, L);
  349. if (edge.IsNull()) {
  350. return;
  351. }
  352. }
  353. void CreateGlBuffer4EdgeEx(const TopoDS_Edge &objEdge, vector<double> &points,
  354. vector<int> &lines) {
  355. Standard_Real firstParam, lastParam;
  356. TopLoc_Location location;
  357. Handle(Geom_Curve) curve3D =
  358. BRep_Tool::Curve(objEdge, location, firstParam, lastParam);
  359. TopAbs_ShapeEnum t = objEdge.ShapeType();
  360. points.clear();
  361. lines.clear();
  362. if (curve3D.IsNull()) {
  363. return;
  364. }
  365. GeomAdaptor_Curve adaptedCurve(curve3D);
  366. int LINE_SEG_NUM = 100;
  367. Standard_Real rParaStep = (lastParam - firstParam) / LINE_SEG_NUM;
  368. for (Standard_Integer i = 0; i <= LINE_SEG_NUM; ++i) {
  369. gp_Pnt pt;
  370. Standard_Real para = firstParam + i * rParaStep;
  371. adaptedCurve.D0(para, pt);
  372. pt = pt.Transformed(location.Transformation());
  373. points.push_back(pt.X());
  374. points.push_back(pt.Y());
  375. points.push_back(pt.Z());
  376. if (i < LINE_SEG_NUM) {
  377. lines.push_back(i);
  378. lines.push_back(i + 1);
  379. }
  380. }
  381. }
  382. TopTools_IndexedMapOfShape g_mapFace;
  383. TopTools_IndexedMapOfShape g_mapEdge;
  384. ///////////////////////////////////////////////////////////////////////////
  385. // implement RenderToBuffer function
  386. #define RenderToBufferEx_FUNC_USAGE \
  387. "RenderToBufferEx Usage: var res = " \
  388. "comx.occrender.RenderToBufferEx(db);"
  389. JS_EXT_FUNC_BEGIN(RenderToBufferEx, 3, RenderToBufferEx_FUNC_USAGE) {
  390. unsigned long long ullDB = JS_EXT_PARA(unsigned long long, 0);
  391. ModelIO &rDB = (*(ModelIO *)((void *)ullDB));
  392. g_mapEdge.Clear();
  393. g_mapFace.Clear();
  394. bool faceFlag = JS_EXT_PARA(bool, 1);
  395. bool edgeFlag = JS_EXT_PARA(bool, 2);
  396. uint32_t arr_idx = 0;
  397. Napi::Array ret = Napi::Array::New(info.Env());
  398. Napi::Object retObj = ret.As<Napi::Object>();
  399. NCollection_IndexedDataMap<int, FaceProperty> faceMap;
  400. rDB.GetFaceMap(faceMap);
  401. for (NCollection_IndexedDataMap<int, FaceProperty>::Iterator
  402. aKeyFaceIter(faceMap);
  403. aKeyFaceIter.More(); aKeyFaceIter.Next()) {
  404. int faceId = aKeyFaceIter.Key();
  405. FaceProperty faceProp = aKeyFaceIter.Value();
  406. if (faceFlag) {
  407. Napi::Value tri_buf = GL::createBufferEx(
  408. info.Env(), 2025, faceId, faceProp.points,
  409. faceProp.normals, faceProp.elements, {}, {}, {}, {},
  410. {}, faceProp.red, faceProp.green, faceProp.blue);
  411. retObj.Set(arr_idx++, tri_buf);
  412. }
  413. if (edgeFlag) {
  414. for (auto it = faceProp.edgeProperties.begin();
  415. it != faceProp.edgeProperties.end(); it++) {
  416. vector<int> freeLines;
  417. vector<int> innerLines;
  418. vector<int> shareLines;
  419. int edge_id = (*it).id;
  420. if ((*it).edgeType == FreeEdge) {
  421. for (int i = 0;
  422. i < (*it).edges.size() - 1; i++) {
  423. freeLines.push_back(
  424. (*it).edges[i]);
  425. freeLines.push_back(
  426. (*it).edges[i + 1]);
  427. }
  428. Napi::Value freeLine_buf =
  429. GL::createBufferEx(
  430. info.Env(), 2026, edge_id,
  431. faceProp.points, {}, {}, {},
  432. freeLines, {}, {}, {}, 255, 0,
  433. 0);
  434. retObj.Set(arr_idx++, freeLine_buf);
  435. } else if ((*it).edgeType == InnerEdge) {
  436. for (int i = 0;
  437. i < (*it).edges.size() - 1; i++) {
  438. innerLines.push_back(
  439. (*it).edges[i]);
  440. innerLines.push_back(
  441. (*it).edges[i + 1]);
  442. }
  443. Napi::Value innerLine_buf =
  444. GL::createBufferEx(
  445. info.Env(), 2027, edge_id,
  446. faceProp.points, {}, {}, {},
  447. innerLines, {}, {}, {}, 255,
  448. 255, 0);
  449. retObj.Set(arr_idx++, innerLine_buf);
  450. } else {
  451. for (int i = 0;
  452. i < (*it).edges.size() - 1; i++) {
  453. shareLines.push_back(
  454. (*it).edges[i]);
  455. shareLines.push_back(
  456. (*it).edges[i + 1]);
  457. }
  458. Napi::Value shareLine_buf =
  459. GL::createBufferEx(
  460. info.Env(), 2028, edge_id,
  461. faceProp.points, {}, {}, {},
  462. shareLines, {}, {}, {}, 0, 255,
  463. 255);
  464. retObj.Set(arr_idx++, shareLine_buf);
  465. }
  466. }
  467. }
  468. }
  469. return ret;
  470. }
  471. JS_EXT_FUNC_END()
  472. ///////////////////////////////////////////////////////////////////////////
  473. // implement RenderToBuffer function
  474. #define RenderToBuffer_FUNC_USAGE \
  475. "RenderToBuffer Usage: var res = comx.occrender.RenderToBuffer(db);"
  476. JS_EXT_FUNC_BEGIN(RenderToBuffer, 1, RenderToBuffer_FUNC_USAGE) {
  477. cout << "Get into RenderToBuffer" << endl;
  478. unsigned long long ullDB = JS_EXT_PARA(unsigned long long, 0);
  479. TopTools_HSequenceOfShape &rDB =
  480. (*(TopTools_HSequenceOfShape *)((void *)ullDB));
  481. // cout << "info.Env(): " << info.Env() << endl;
  482. Napi::Array ret = Napi::Array::New(info.Env());
  483. Napi::Object retObj = ret.As<Napi::Object>();
  484. g_mapEdge.Clear();
  485. g_mapFace.Clear();
  486. uint32_t arr_idx = 0;
  487. int totalPointCounts = 0;
  488. int totalLineCounts = 0;
  489. Standard_Integer iNumOfShape = rDB.Length();
  490. for (int idx = 1; idx <= iNumOfShape; ++idx) {
  491. // TopoDS_Shape &objShape = rDB.ChangeValue(idx);
  492. // BRepTools::Clean(objShape);
  493. TopoDS_Shape &_objShape = rDB.ChangeValue(idx);
  494. BRepTools::Clean(_objShape);
  495. BRepBuilderAPI_Sewing aSewingTool;
  496. aSewingTool.Init();
  497. aSewingTool.Load(_objShape);
  498. aSewingTool.Perform();
  499. TopoDS_Shape objShape = aSewingTool.SewedShape();
  500. if (objShape.IsNull())
  501. objShape = _objShape;
  502. BRepTools::Clean(objShape);
  503. BRepMesh_IncrementalMesh(objShape, 0.01, true, 0.2, false);
  504. TopExp::MapShapes(objShape, TopAbs_EDGE, g_mapEdge);
  505. TopExp::MapShapes(objShape, TopAbs_FACE, g_mapFace);
  506. TColStd_Array1OfInteger arrFaceCountOfEdge(1,
  507. g_mapEdge.Extent());
  508. arrFaceCountOfEdge.Init(0);
  509. // Create Face
  510. for (TopExp_Explorer faceExp(objShape, TopAbs_FACE);
  511. faceExp.More(); faceExp.Next()) {
  512. const TopoDS_Face &objFace =
  513. TopoDS::Face(faceExp.Current());
  514. Standard_Integer face_id = g_mapFace.FindIndex(objFace);
  515. string strFaceID = type_cast<string>(face_id);
  516. string face_comments =
  517. "render-cascade.face" + strFaceID;
  518. int color[] = {255, 255, 0};
  519. vector<double> points;
  520. vector<double> normals;
  521. vector<int> triangles;
  522. if (!CreateGlBuffer4FaceEx(objFace, points, normals,
  523. triangles)) {
  524. continue;
  525. }
  526. Napi::Value tri_buf = GL::createBuffer(
  527. info.Env(), 2025, face_id, points, normals,
  528. triangles, {}, {}, {}, {}, {});
  529. retObj.Set(arr_idx++, tri_buf);
  530. for (TopExp_Explorer edgeExp(faceExp.Current(),
  531. TopAbs_EDGE);
  532. edgeExp.More(); edgeExp.Next()) {
  533. arrFaceCountOfEdge(
  534. g_mapEdge.FindIndex(edgeExp.Current()))++;
  535. }
  536. }
  537. // Create Trangles Edge
  538. int flag = 1;
  539. for (TopExp_Explorer faceExp(objShape, TopAbs_FACE);
  540. faceExp.More(); faceExp.Next()) {
  541. const TopoDS_Face &objFace =
  542. TopoDS::Face(faceExp.Current());
  543. Standard_Integer edge_id =
  544. flag + g_mapFace.FindIndex(objFace);
  545. flag++;
  546. string strEdgeID = type_cast<string>(edge_id);
  547. string face_comments =
  548. "render-cascade.edge" + strEdgeID;
  549. int color[] = {255, 255, 0};
  550. vector<double> points;
  551. vector<double> normals;
  552. vector<int> lines;
  553. if (!CreateGlBuffer4FaceEdge(objFace, points, normals,
  554. lines)) {
  555. continue;
  556. }
  557. Napi::Value line_buf =
  558. GL::createBuffer(info.Env(), 2026, edge_id, points,
  559. {}, {}, {}, lines, {}, {}, {});
  560. // retObj.Set(arr_idx++, line_buf);
  561. }
  562. for (TopExp_Explorer edgeExp(objShape, TopAbs_EDGE);
  563. edgeExp.More(); edgeExp.Next()) {
  564. const TopoDS_Edge &objEdge =
  565. TopoDS::Edge(edgeExp.Current());
  566. vector<double> points;
  567. vector<int> lines;
  568. GetGlBuffer4Edge(objEdge, points, lines);
  569. }
  570. // Create Shape Edge
  571. for (Standard_Integer idx_edge = 1;
  572. idx_edge <= g_mapEdge.Extent(); ++idx_edge) {
  573. vector<double> points;
  574. vector<int> lines;
  575. BRepAdaptor_Curve adaptorCurve(
  576. TopoDS::Edge(g_mapEdge(idx_edge)));
  577. CurveAdaptiveDiscrete(adaptorCurve, points, lines,
  578. QuasiUniformDeflection);
  579. Standard_Integer edge_id =
  580. idx_edge + g_mapFace.Extent();
  581. string strEdgeID = type_cast<string>(edge_id);
  582. string edge_comments =
  583. "render-cascade.face" + strEdgeID;
  584. totalPointCounts += points.size() / 3;
  585. totalLineCounts += lines.size() / 3;
  586. if (lines.empty()) {
  587. continue;
  588. }
  589. switch (arrFaceCountOfEdge(idx_edge)) {
  590. case 0:
  591. // Free Edge
  592. {
  593. int color[] = {255, 0, 0};
  594. // JS_EXT_GL_CACHE_ENTRY_EX(&points[0],
  595. // NULL, points.size() / 3,
  596. // NULL, NULL&triangles_prop[0], 0,
  597. // &lines[0], NULL, lines.size() /
  598. // 2, NULL, NULL, 0,
  599. // edge_comments.c_str(), 1, color,
  600. // 2026, edge_id, true);
  601. Napi::Value line_buf = GL::createBuffer(
  602. info.Env(), 2026, edge_id, points,
  603. {}, {}, {}, lines, {}, {}, {});
  604. retObj.Set(arr_idx++, line_buf);
  605. }
  606. break;
  607. case 1: {
  608. int color[] = {255, 255, 255};
  609. // JS_EXT_GL_CACHE_ENTRY_EX(&points[0], NULL,
  610. // points.size() / 3,
  611. // NULL, NULL&triangles_prop[0], 0,
  612. // &lines[0], NULL, lines.size() / 2,
  613. // NULL, NULL, 0,
  614. // edge_comments.c_str(), 1, color, 2027,
  615. // edge_id, true);
  616. Napi::Value line_buf = GL::createBuffer(
  617. info.Env(), 2027, edge_id, points, {}, {},
  618. {}, lines, {}, {}, {});
  619. retObj.Set(arr_idx++, line_buf);
  620. }
  621. // Border Edge
  622. break;
  623. default: // Shared Edge
  624. {
  625. int color[] = {5, 5, 5};
  626. // JS_EXT_GL_CACHE_ENTRY_EX(&points[0], NULL,
  627. // points.size() / 3,
  628. // NULL, NULL&triangles_prop[0], 0,
  629. // &lines[0], NULL, lines.size() / 2,
  630. // NULL, NULL, 0,
  631. // edge_comments.c_str(), 1, color, 2028,
  632. // edge_id, true);
  633. Napi::Value line_buf = GL::createBuffer(
  634. info.Env(), 2028, edge_id, points, {}, {},
  635. {}, lines, {}, {}, {});
  636. retObj.Set(arr_idx++, line_buf);
  637. } break;
  638. }
  639. }
  640. }
  641. return ret;
  642. }
  643. JS_EXT_FUNC_END()
  644. ///////////////////////////////////////////////////////////////////////////
  645. // implement RenderToBufferGLTF function
  646. #include <gltf/threeAnimation.hxx>
  647. #include <gltf/threeMath.hxx>
  648. using namespace three;
  649. vector<GLTFMesh> gltfMeshes;
  650. ofstream logFile;
  651. vector<string> split(const string &str, string delim) {
  652. vector<string> res;
  653. if ("" == str)
  654. return res;
  655. char *strs = new char[str.length() + 1];
  656. strcpy_s(strs, strlen(str.c_str()) + 1, str.c_str());
  657. char *d = new char[delim.length() + 1];
  658. strcpy_s(d, strlen(delim.c_str()) + 1, delim.c_str());
  659. char *buf;
  660. char *p = strtok_s(strs, d, &buf);
  661. while (p) {
  662. string s = p;
  663. res.push_back(s);
  664. p = strtok_s(NULL, d, &buf);
  665. }
  666. return res;
  667. }
  668. bool readPropertyFile(string propFile) {
  669. ifstream inPropFile;
  670. inPropFile.open(propFile.c_str(), ios::in);
  671. if (!inPropFile.is_open()) {
  672. cout << "Open File: " << propFile << " Failed" << endl;
  673. return false;
  674. }
  675. while (!inPropFile.eof()) {
  676. string temp;
  677. inPropFile >> temp;
  678. vector<string> props;
  679. props = split(temp, ",");
  680. if (props.size() != 10) {
  681. continue;
  682. }
  683. GLTFMesh _gltfMesh;
  684. _gltfMesh.id = props[0];
  685. _gltfMesh.name = props[1];
  686. _gltfMesh.uid = props[2];
  687. //_gltfMesh.duration = props[3];
  688. _gltfMesh.frameCounts = atoi(props[4].c_str());
  689. _gltfMesh.animationCounts = atoi(props[5].c_str());
  690. _gltfMesh.morphTargetInfluencesCounts = atoi(props[6].c_str());
  691. if (strcmp(props[7].c_str(), "true") == 0) {
  692. _gltfMesh.morphTargetsRelative = true;
  693. } else {
  694. _gltfMesh.morphTargetsRelative = false;
  695. }
  696. _gltfMesh.bindMode = props[8];
  697. _gltfMesh.bonesCounts = atoi(props[9].c_str());
  698. gltfMeshes.push_back(_gltfMesh);
  699. }
  700. return true;
  701. }
  702. #define RenderToBufferGLTF_FUNC_USAGE \
  703. "RenderToBufferGLTF Usage: var res = " \
  704. "comx.occrender.RenderToBufferGLTF(db);"
  705. JS_EXT_FUNC_BEGIN(RenderToBufferGLTF, 1, RenderToBufferGLTF_FUNC_USAGE) {
  706. logFile.open("F:\\gltfLog.txt", ios::out);
  707. logFile << "Get into RenderToBuffer gltf" << endl;
  708. string cacheFileBaseName = JS_EXT_PARA(string, 0);
  709. Napi::Array ret = Napi::Array::New(info.Env());
  710. Napi::Object retObj = ret.As<Napi::Object>();
  711. uint32_t arr_idx = 0;
  712. Standard_Integer face_id = 1;
  713. gltfMeshes.clear();
  714. if (!readPropertyFile(cacheFileBaseName + ".prop")) {
  715. return ret;
  716. }
  717. for (unsigned int i = 0; i < gltfMeshes.size(); i++) {
  718. gltfMeshes[i].ReadCache(cacheFileBaseName);
  719. gltfMeshes[i].parseAnimation();
  720. }
  721. for (int idx = 0; idx < gltfMeshes.size(); ++idx) {
  722. // if (idx != 0) continue;
  723. Napi::Value tri_buf = GL::createBuffer(
  724. info.Env(), 2025, face_id++,
  725. gltfMeshes[idx].animations[0].frames[20].position,
  726. gltfMeshes[idx].animations[0].frames[20].normals,
  727. gltfMeshes[idx].index, {}, {}, {}, {}, {});
  728. retObj.Set(arr_idx++, tri_buf);
  729. }
  730. logFile.close();
  731. return ret;
  732. }
  733. JS_EXT_FUNC_END()
  734. // 0x4cc0c89c-0x0090-0x47e3-0xb7-0x63-0xc1-0xaf-0xf1-0xe7-0x99-0x4e
  735. // please don't modify or delete the previous line codes.
  736. ////////////////////////////////////////////////////////////////////////////
  737. // please set your js.ext namespace in the following codes.
  738. #define JS_EXT_NS "comx.occrender"
  739. ////////////////////////////////////////////////////////////////////////////
  740. // entry segment, please replace your function name in the following codes.
  741. JS_EXT_ENTRY_BEGIN()
  742. JS_EXT_ENTRY(RenderToBufferGLTF)
  743. JS_EXT_ENTRY(RenderToBufferEx)
  744. JS_EXT_ENTRY(RenderToBuffer)
  745. JS_EXT_ENTRY_END()
  746. JS_EXT_MAIN_BEGIN(JS_EXT_NS, 3)
  747. JS_EXT_FUNC_REG(RenderToBufferGLTF)
  748. JS_EXT_FUNC_REG(RenderToBufferEx)
  749. JS_EXT_FUNC_REG(RenderToBuffer)
  750. JS_EXT_MAIN_END()