Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #include <fstream>
34 : #include <algorithm>
35 : #include "file_io_stl.h"
36 : #include "common/util/loader/loader_util.h"
37 : #include "common/util/string_util.h"
38 : #include "lib_grid/lg_base.h"
39 : #include "lib_grid/algorithms/geom_obj_util/face_util.h"
40 :
41 : #include "stl_reader.h"
42 :
43 : using namespace std;
44 :
45 : namespace ug
46 : {
47 :
48 0 : bool LoadGridFromSTL(Grid& grid, const char* filename,
49 : ISubsetHandler* pSH,
50 : AVector3& aPos,
51 : AVector3& aNormFACE)
52 : {
53 : vector<number> coords, normals;
54 : vector<unsigned int> tris, solids;
55 :
56 0 : if(!stl_reader::ReadStlFile(filename, coords, normals, tris, solids))
57 : return false;
58 :
59 0 : if(!grid.has_vertex_attachment(aPos))
60 0 : grid.attach_to_vertices(aPos);
61 : Grid::VertexAttachmentAccessor<AVector3> aaPos(grid, aPos);
62 :
63 0 : const size_t numVrts = coords.size() / 3;
64 0 : grid.reserve<Vertex>(grid.num<Vertex>() + numVrts);
65 0 : vector<Vertex*> vrts(numVrts);
66 :
67 0 : for(size_t i = 0; i < numVrts; ++i){
68 0 : const size_t ci = i * 3;
69 0 : Vertex* v = *grid.create<RegularVertex>();
70 : vector3& p = aaPos[v];
71 0 : for(size_t j = 0; j < 3; ++j)
72 0 : p[j] = coords[ci + j];
73 0 : vrts[i] = v;
74 : }
75 :
76 0 : const size_t numTris = tris.size() / 3;
77 0 : grid.reserve<Face>(grid.num<Face>() + numTris);
78 :
79 : Grid::FaceAttachmentAccessor<AVector3> aaNormFACE;
80 0 : if(grid.has_face_attachment(aNormFACE))
81 : aaNormFACE.access(grid, aNormFACE);
82 :
83 : size_t curSolid = 0;
84 0 : for(size_t i = 0; i < numTris; ++i){
85 0 : const size_t ti = i*3;
86 : const unsigned int* t = &tris[ti];
87 0 : Face* f = *grid.create<Triangle>(
88 0 : TriangleDescriptor(vrts[t[0]], vrts[t[1]], vrts[t[2]]));
89 :
90 0 : if(pSH){
91 0 : while((curSolid + 1 < solids.size()) && (i >= solids[curSolid + 1]))
92 : ++curSolid;
93 0 : pSH->assign_subset(f, (int)curSolid);
94 : }
95 :
96 0 : if(aaNormFACE.valid()){
97 : vector3& n = aaNormFACE[f];
98 0 : for(size_t j = 0; j < 3; ++j)
99 0 : n[j] = normals[ti + j];
100 : }
101 : }
102 :
103 : return true;
104 0 : }
105 :
106 0 : bool SaveGridToSTL(Grid& grid, const char* filename,
107 : ISubsetHandler* pSH,
108 : AVector3& aPos)
109 : {
110 0 : ofstream out(filename);
111 0 : if(!out){
112 0 : UG_LOG("Couldn't open file " << filename << " for writing\n");
113 : return false;
114 : }
115 :
116 0 : if(!grid.has_vertex_attachment(aPos)){
117 : UG_LOG("Specified vertex-position attachment missing!\n");
118 : }
119 :
120 0 : if(grid.num<Quadrilateral>() > 0){
121 : UG_LOG("WARNING: The specified grid contains quadrilaterals. "
122 : "Those won't be written to the stl file!\n");
123 : }
124 :
125 : Grid::VertexAttachmentAccessor<APosition> aaPos(grid, aPos);
126 :
127 : const char* solidName = "stlFromUG4";
128 0 : out << "solid " << solidName << endl;
129 :
130 : for(Grid::traits<Triangle>::iterator iter = grid.begin<Triangle>();
131 0 : iter != grid.end<Triangle>(); ++iter)
132 : {
133 : Triangle* f = *iter;
134 : vector3 n;
135 0 : CalculateNormal(n, f, aaPos);
136 0 : out << "facet normal " << n.x() << " " << n.y() << " " << n.z() << endl;
137 : out << "outer loop" << endl;
138 0 : for(size_t i = 0; i < 3; ++i){
139 0 : vector3 v = aaPos[f->vertex(i)];
140 : out << "vertex " << v.x() << " " << v.y() << " " << v.z() << endl;
141 : }
142 : out << "endloop" << endl;
143 : out << "endfacet" << endl;
144 : }
145 :
146 0 : out << "endsolid " << solidName << endl;
147 : return true;
148 0 : }
149 :
150 : }
|