1+ package assimp.postProcess
2+
3+ import assimp.AiScene
4+ import glm_.vec3.Vec3
5+
6+ object fastQuadraticMeshSimplification {
7+
8+ class SymmetricMatrix (val m : DoubleArray ) {
9+
10+ constructor (c: Double = 0.0 ) : this (DoubleArray (10 ) { c })
11+
12+ constructor (m11: Double , m12: Double , m13: Double , m14: Double ,
13+ m22: Double , m23: Double , m24: Double ,
14+ m33: Double , m34: Double ,
15+ m44: Double ) :
16+ this (doubleArrayOf(
17+ m11, m12, m13, m14,
18+ m22, m23, m24,
19+ m33, m34,
20+ m44))
21+
22+ // Make plane
23+ constructor (a: Double , b: Double , c: Double , d: Double ) :
24+ this (doubleArrayOf(
25+ a * a, a * b, a * c, a * d,
26+ b * b, b * c, b * d,
27+ c * c, c * d,
28+ d * d))
29+
30+ operator fun get (c : Int ) = m[c]
31+
32+ // Determinant
33+ fun det (a11 : Int , a12 : Int , a13 : Int ,
34+ a21 : Int , a22 : Int , a23 : Int ,
35+ a31 : Int , a32 : Int , a33 : Int ) =
36+ m[a11] * m[a22] * m[a33] + m[a13] * m[a21] * m[a32] + m[a12] * m[a23] * m[a31] -
37+ m[a13] * m[a22] * m[a31] - m[a11] * m[a23] * m[a32] - m[a12] * m[a21] * m[a33]
38+
39+ operator fun plus (n : SymmetricMatrix ) = SymmetricMatrix (
40+ m[0 ] + n[0 ], m[1 ] + n[1 ], m[2 ] + n[2 ], m[3 ] + n[3 ],
41+ m[4 ] + n[4 ], m[5 ] + n[5 ], m[6 ] + n[6 ],
42+ m[7 ] + n[7 ], m[8 ] + n[8 ],
43+ m[9 ] + n[9 ])
44+
45+ operator fun plusAssign (n : SymmetricMatrix ) {
46+ m[0 ] + = n[0 ]; m[1 ] + = n[1 ]; m[2 ] + = n[2 ]; m[3 ] + = n[3 ]
47+ m[4 ] + = n[4 ]; m[5 ] + = n[5 ]; m[6 ] + = n[6 ]; m[7 ] + = n[7 ]
48+ m[8 ] + = n[8 ]; m[9 ] + = n[9 ]
49+ }
50+ }
51+
52+ // Global Variables & Strctures
53+
54+ class Triangle (
55+ val v : IntArray , val err : DoubleArray ,
56+ var deleted : Int , var dirty : Int ,
57+ val n : Vec3 )
58+
59+ class Vertex (
60+ val p : Vec3 ,
61+ var tStart : Int ,
62+ var tCount : Int ,
63+ var q : SymmetricMatrix ,
64+ var border : Int )
65+
66+ class Ref (val tid : Int , val tvertex : Int )
67+
68+ val triangles = ArrayList <Triangle >()
69+ val vertices = ArrayList <Vertex >()
70+ val refs = ArrayList <Ref >()
71+
72+ /* *
73+ * Main simplification function
74+ *
75+ * target_count : target nr. of triangles
76+ * agressiveness : sharpness to increase the threshold.
77+ * 5..8 are good numbers
78+ * more iterations yield higher quality
79+ */
80+ fun simplify (scene : AiScene , targetCount : Int , aggressiveness : Int = 7) {
81+
82+ println (" simplify - start" )
83+ val timeStart = System .currentTimeMillis()
84+
85+ for (mesh in scene.meshes) {
86+
87+ triangles.forEach { it.deleted = 0 }
88+
89+ // main iteration loop
90+
91+ var deletedTriangles = 0
92+ val deleted0 = ArrayList <Int >()
93+ val deleted1 = ArrayList <Int >()
94+ val triangleCount = triangles.size
95+
96+ for (iteration in 0 .. 99 ) {
97+
98+ // target number of triangles reached ? Then break
99+ println (" iteration $iteration - triangles ${triangleCount - deletedTriangles} " )
100+
101+ if (triangleCount - deletedTriangles <= targetCount) break
102+
103+ // update mesh once in a while
104+ if (iteration % 5 == 0 )
105+ updateMesh(iteration)
106+ }
107+ }
108+ }
109+
110+ /* * compact triangles, compute edge error and build reference list */
111+ fun updateMesh (iteration : Int ) {
112+
113+ // if(iteration>0) { // compact triangles
114+ //
115+ // var dst=0;
116+ // loopi(0,triangles.size())
117+ // if(!triangles[i].deleted)
118+ // {
119+ // triangles[dst++]=triangles[i];
120+ // }
121+ // triangles.resize(dst);
122+ // }
123+ // //
124+ // // Init Quadrics by Plane & Edge Errors
125+ // //
126+ // // required at the beginning ( iteration == 0 )
127+ // // recomputing during the simplification is not required,
128+ // // but mostly improves the result for closed meshes
129+ // //
130+ // if( iteration == 0 )
131+ // {
132+ // loopi(0,vertices.size())
133+ // vertices[i].q=SymetricMatrix(0.0);
134+ //
135+ // loopi(0,triangles.size())
136+ // {
137+ // Triangle &t=triangles[i];
138+ // vec3f n,p[3];
139+ // loopj(0,3) p[j]=vertices[t.v[j]].p;
140+ // n.cross(p[1]-p[0],p[2]-p[0]);
141+ // n.normalize();
142+ // t.n=n;
143+ // loopj(0,3) vertices[t.v[j]].q =
144+ // vertices[t.v[j]].q+SymetricMatrix(n.x,n.y,n.z,-n.dot(p[0]));
145+ // }
146+ // loopi(0,triangles.size())
147+ // {
148+ // // Calc Edge Error
149+ // Triangle &t=triangles[i];vec3f p;
150+ // loopj(0,3) t.err[j]=calculate_error(t.v[j],t.v[(j+1)%3],p);
151+ // t.err[3]=min(t.err[0],min(t.err[1],t.err[2]));
152+ // }
153+ // }
154+ //
155+ // // Init Reference ID list
156+ // loopi(0,vertices.size())
157+ // {
158+ // vertices[i].tstart=0;
159+ // vertices[i].tcount=0;
160+ // }
161+ // loopi(0,triangles.size())
162+ // {
163+ // Triangle &t=triangles[i];
164+ // loopj(0,3) vertices[t.v[j]].tcount++;
165+ // }
166+ // int tstart=0;
167+ // loopi(0,vertices.size())
168+ // {
169+ // Vertex &v=vertices[i];
170+ // v.tstart=tstart;
171+ // tstart+=v.tcount;
172+ // v.tcount=0;
173+ // }
174+ //
175+ // // Write References
176+ // refs.resize(triangles.size()*3);
177+ // loopi(0,triangles.size())
178+ // {
179+ // Triangle &t=triangles[i];
180+ // loopj(0,3)
181+ // {
182+ // Vertex &v=vertices[t.v[j]];
183+ // refs[v.tstart+v.tcount].tid=i;
184+ // refs[v.tstart+v.tcount].tvertex=j;
185+ // v.tcount++;
186+ // }
187+ // }
188+ //
189+ // // Identify boundary : vertices[].border=0,1
190+ // if( iteration == 0 )
191+ // {
192+ // std::vector<int> vcount,vids;
193+ //
194+ // loopi(0,vertices.size())
195+ // vertices[i].border=0;
196+ //
197+ // loopi(0,vertices.size())
198+ // {
199+ // Vertex &v=vertices[i];
200+ // vcount.clear();
201+ // vids.clear();
202+ // loopj(0,v.tcount)
203+ // {
204+ // int k=refs[v.tstart+j].tid;
205+ // Triangle &t=triangles[k];
206+ // loopk(0,3)
207+ // {
208+ // int ofs=0,id=t.v[k];
209+ // while(ofs<vcount.size())
210+ // {
211+ // if(vids[ofs]==id)break;
212+ // ofs++;
213+ // }
214+ // if(ofs==vcount.size())
215+ // {
216+ // vcount.push_back(1);
217+ // vids.push_back(id);
218+ // }
219+ // else
220+ // vcount[ofs]++;
221+ // }
222+ // }
223+ // loopj(0,vcount.size()) if(vcount[j]==1)
224+ // vertices[vids[j]].border=1;
225+ // }
226+ // }
227+ }
228+ }
0 commit comments