Geogram Version 1.9.6-rc
A programming library of geometric algorithms
Loading...
Searching...
No Matches
meshcomesh.h
1/*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40#ifndef H_MESHCOMESH_H
41#define H_MESHCOMESH_H
42
44#include <geogram/mesh/mesh.h>
45#include <exploragram/hexdom/polygon.h>
46#include <exploragram/hexdom/intersect_tools.h>
47
52namespace GEO {
53 struct TrFan {
54 struct TrFanElt {
55 TrFanElt(Mesh* m, index_t v, index_t p_f, index_t p_chart) : f(p_f), chart(p_chart) {
56 geo_assert(m->facets.nb_vertices(f) == 3);
57 FOR (c, 3) {
58 if (m->facets.vertex(f, c) != v) continue;
59 org = m->facets.vertex(f, (c + 1) % 3);
60 dest = m->facets.vertex(f, (c + 2) % 3);
61 break;
62 }
63 }
64
65 index_t f;
66 index_t chart;
67 index_t org;
68 index_t dest;
69 };
70
71 TrFan(index_t v, Mesh *m, vector<vector<index_t> > &v2f, Attribute<index_t> &chart) : m_(m), v_(v), incomplete_(false) {
72 if (!v2f[v].size()) return;
73
74 FOR(i, v2f[v].size()) { // collect triangles around v
75 index_t f = v2f[v][i];
76 geo_assert(3 == m->facets.nb_vertices(f));
77 fan.push_back(TrFanElt(m, v, f, chart[f]));
78 }
79
80 FOR(i, fan.size()) { // find boundary fan element and put it in the first position
81 bool boundary = true;
82 FOR(j, fan.size()) {
83 if (fan[i].org == fan[j].dest) {
84 geo_assert(i != j);
85 boundary = false;
86 break;
87 }
88 }
89 if (boundary) {
90 std::swap(fan[0], fan[i]);
91 incomplete_ = true;
92 break;
93 }
94 }
95
96 FOR(f, fan.size()-1) { // sort triangles in circular order, first triangle is not moved
97 for (index_t i = f+2; i<fan.size(); i++) {
98 if (fan[f].dest == fan[i].org) {
99 std::swap(fan[f + 1], fan[i]);
100 break;
101 }
102 }
103 }
104
105 FOR(f, fan.size()) {
106 if (fan[f].dest == fan[(f+1) % fan.size()].org) continue;
107 if (f+1==fan.size() && incomplete_) continue;
108 GEO::Logger::out("HexDom") << "Fan around vertex " << v_ << " is not valid" << std::endl;
109 FOR(ff, fan.size()) GEO::Logger::out("HexDom") << "fan[ff].org = " << fan[ff].org << "\tfan[ff].dest = " << fan[ff].dest << std::endl;
111 }
112
113 if (!incomplete_) {
114 index_t rotate = 0; // find a boundary between charts (any boundary will do); if no boundary rotate will be zero
115 FOR(f, fan.size()) {
116 if (fan[rotate].chart != fan[(rotate-1+fan.size())%fan.size()].chart) break;
117 rotate++;
118 }
119 geo_assert(rotate <= fan.size());
120 std::rotate(fan.begin(), fan.begin() + int(rotate), fan.end());
121 }
122
123 chart_offset.push_back(0);
124 FOR(f, fan.size()-1) {
125 if (fan[f].chart == fan[f+1].chart) continue;
126 chart_offset.push_back(int(f + 1));
127 }
128 }
129
130 index_t ncharts() {
131 return index_t(chart_offset.size());
132 }
133
134 bool triangulate() {
135 // 2 charts max, and incomplete fan must not have more than 1 chart
136 Attribute<bool> selection(m_->vertices.attributes(), "selection");
137 if (2<ncharts() || (incomplete_ && 1!=ncharts())) {
138 selection[v_] = true;
139 return false;
140 }
141
142 bool result = true;
143 FOR(ichart, ncharts()) {
144 vector<index_t> vidx;
145 int off1 = chart_offset[ichart];
146 int off2 = ichart+1 < ncharts() ? chart_offset[ichart+1] : int(fan.size());
147 for (int ivert=off1; ivert<off2; ivert++) {
148 vidx.push_back(fan[ivert].org);
149 }
150 if (incomplete_ || 1<ncharts()) {
151 vidx.push_back(fan[off2-1].dest);
152 }
153 triangles.push_back(vector<index_t>());
154 if (3>vidx.size()) continue;
155
156 vector<vec3> pts3d;
157 FOR(ivert, vidx.size()) {
158 pts3d.push_back(X(m_)[vidx[ivert]]);
159 }
160
161 pts3d.push_back(X(m_)[v_]);
162
163 vec3 nrm = Poly3d(pts3d).normal();
164 if (nrm.length()<1e-10) nrm = vec3(0,0,1); // ça va, si c'est un polygon degenere, prenons un truc au pif
165
166 Basis3d b(nrm);
167 pts3d.pop_back(); // v_ was useful for computing the normal, removing it for the triangulation
168
169 vector<vec2> pts2d;
170 FOR(ivert, pts3d.size()) {
171 pts2d.push_back(b.project_xy(pts3d[ivert]));
172 }
173
174 vector<index_t> tri_local_indices;
175 if (!Poly2d(pts2d).try_triangulate_minweight(tri_local_indices)) {
176 error("was not able to triangulate");
177// tri_local_indices.clear();
178 result = false;
179 }
180
181 FOR(ivert, tri_local_indices.size()) {
182 triangles.back().push_back(vidx[tri_local_indices[ivert]]);
183 }
184
185 geo_assert(0 == triangles.back().size() % 3);
186 }
187 return result;
188 }
189
190 TrFanElt& operator[](int i) {
191 geo_assert(i >= 0 && i < int(fan.size()));
192 return fan[i];
193 }
194
195 TrFanElt& operator[](index_t i) {
196 geo_assert(i < fan.size());
197 return fan[i];
198 }
199
200 index_t nb_fan_triangles() {
201 return index_t(fan.size());
202 }
203
204 vector<vector<index_t> > triangles;
205 vector<TrFanElt> fan;
206 vector<int> chart_offset;
207
208 Mesh *m_;
209 index_t v_;
210 bool incomplete_;
211 };
212
213 vector<vector<index_t> > generate_v2f(Mesh *m);
214 bool find_self_intersections(Mesh* facets_with_quads_and_tri_only, vector<index_t> &intersections);
215 bool lock_self_intersecting_regions(Mesh* facets_with_quads_and_tri_only, vector<BBox>& regions_to_lock);
216 bool lock_self_intersecting_regions(Mesh* facets_with_quads_and_tri_only, Attribute<bool> &verts_to_remove, Attribute<index_t> &undo);
217 bool try_simplify(Mesh* m, Attribute<index_t> &chart, Attribute<bool> &verts_to_remove, Attribute<index_t> &undo);
218}
219
220#endif
#define geo_assert_not_reached
Sets a non reachable point in the program.
Definition assert.h:177
#define geo_assert(x)
Verifies that a condition is met.
Definition assert.h:149
Manages an attribute attached to a set of object.
static std::ostream & out(const std::string &feature)
Gets the stream to send information messages.
index_t vertex(index_t f, index_t lv) const
Gets a vertex by facet and local vertex index.
Definition mesh.h:1143
index_t nb_vertices(index_t f) const
Gets the number of vertices of a facet.
Definition mesh.h:1132
AttributesManager & attributes() const
Gets the attributes manager.
Definition mesh.h:109
Represents a mesh.
Definition mesh.h:3050
Vector with aligned memory allocation.
Definition memory.h:660
index_t size() const
Gets the number of elements.
Definition memory.h:706
Included by all headers in exploragram.
The class that represents a mesh.
Global Vorpaline namespace.
Definition basic.h:55
vecng< 3, Numeric::float64 > vec3
Represents points and vectors in 3d.
Definition geometry.h:65
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:329