1#include <Core/Geometry/deprecated/TopologicalMesh.hpp>
3#include <Core/RaCore.hpp>
4#include <Core/Utils/Log.hpp>
6#include <Eigen/StdVector>
8#include <unordered_map>
21template <
typename P,
typename T>
22void addAttribPairToCore( TriangleMesh& triMesh,
23 const TopologicalMesh* topoMesh,
24 OpenMesh::HPropHandleT<T> oh,
26 AttribHandle<T> h = triMesh.addAttrib<T>( topoMesh->property( oh ).name() );
32 Eigen::aligned_allocator<std::pair<AttribHandle<T>, T>>>;
34template <
typename P,
typename T>
35void copyAttribToCoreVertex( HandleAndValueVector<T>& data,
36 const TopologicalMesh* topoMesh,
38 TopologicalMesh::HalfedgeHandle heh ) {
39 for (
auto pp : vprop ) {
40 data.push_back(
std::make_pair( pp.first, topoMesh->property( pp.second, heh ) ) );
45void copyAttribToCore( TriangleMesh& triMesh,
const HandleAndValueVector<T>& data ) {
47 for (
auto pp : data ) {
48 auto& attr = triMesh.getAttrib( pp.first );
49 auto& attrData = attr.getDataWithLock();
50 attrData.push_back( pp.second );
63 LOG( logWARNING ) <<
"Invalid face handle returned : face not added " + m_details;
80 add_property( m_inputTriangleMeshIndexPph );
84 struct VertexDataInternal {
93 bool operator==(
const VertexDataInternal& lhs )
const {
94 return _vertex == lhs._vertex && _normal == lhs._normal && _float == lhs._float &&
95 _vec2 == lhs._vec2 && _vec3 == lhs._vec3 && _vec4 == lhs._vec4;
100 size_t operator()(
const VertexDataInternal& lvalue )
const {
104 return ( hx ^ ( hy << 1 ) ) ^ hz;
112 VertexMap vertexHandles;
114 if ( !get_property_handle( m_outputTriangleMeshIndexPph,
"OutputTriangleMeshIndices" ) ) {
115 add_property( m_outputTriangleMeshIndexPph,
"OutputTriangleMeshIndices" );
124 for (
auto oh : m_floatPph )
125 addAttribPairToCore( out,
this, oh, vprop_float );
127 for (
auto oh : m_vec2Pph )
128 addAttribPairToCore( out,
this, oh, vprop_vec2 );
130 for (
auto oh : m_vec3Pph )
131 addAttribPairToCore( out,
this, oh, vprop_vec3 );
133 for (
auto oh : m_vec4Pph )
134 addAttribPairToCore( out,
this, oh, vprop_vec4 );
137 unsigned int vertexIndex = 0;
140 TriangleMesh::PointAttribHandle::Container vertices;
141 TriangleMesh::NormalAttribHandle::Container normals;
144 vertices.
reserve( n_vertices() );
145 normals.reserve( n_vertices() );
148 for ( TopologicalMesh::FaceIter f_it = faces_sbegin(); f_it != faces_end(); ++f_it ) {
153 for ( TopologicalMesh::ConstFaceHalfedgeIter fh_it = cfh_iter( *f_it ); fh_it.is_valid();
155 VertexDataInternal v;
156 CORE_ASSERT( i < 3,
"Non-triangular face found." );
157 v._vertex = point( to_vertex_handle( *fh_it ) );
159 if ( has_halfedge_normals() ) {
160 v._normal =
normal( to_vertex_handle( *fh_it ), *f_it );
162 copyAttribToCoreVertex( v._float,
this, vprop_float, *fh_it );
163 copyAttribToCoreVertex( v._vec2,
this, vprop_vec2, *fh_it );
164 copyAttribToCoreVertex( v._vec3,
this, vprop_vec3, *fh_it );
165 copyAttribToCoreVertex( v._vec4,
this, vprop_vec4, *fh_it );
168 VertexMap::iterator vtr = vertexHandles.find( v );
169 if ( vtr == vertexHandles.end() ) {
170 vi = int( vertexIndex++ );
171 vertexHandles.insert( vtr, VertexMap::value_type( v, vi ) );
172 vertices.push_back( v._vertex );
173 if ( has_halfedge_normals() ) { normals.push_back( v._normal ); }
174 copyAttribToCore( out, v._float );
175 copyAttribToCore( out, v._vec2 );
176 copyAttribToCore( out, v._vec3 );
177 copyAttribToCore( out, v._vec4 );
179 else { vi = vtr->second; }
181 property( m_outputTriangleMeshIndexPph, *fh_it ) = vi;
184 indices.
emplace_back( tindices[0], tindices[1], tindices[2] );
189 CORE_ASSERT( vertexIndex == vertices.size(),
190 "Inconsistent number of faces in generated TriangleMesh." );
215 if ( f < 0 || f > 1 ) {
return false; }
220 VertexHandle v0 = to_vertex_handle( he0 );
221 VertexHandle v1 = to_vertex_handle( he1 );
222 FaceHandle F0 = face_handle( he0 );
223 FaceHandle F1 = face_handle( he1 );
226 if ( ( !is_boundary( he0 ) && valence( F0 ) != 3 ) ||
227 ( !is_boundary( he1 ) && valence( F1 ) != 3 ) ) {
232 const Point p = Point( f * point( v0 ) + ( Scalar( 1. ) - f ) * point( v1 ) );
233 VertexHandle v = add_vertex( p );
236 HalfedgeHandle he3 = new_edge( v, v1 );
237 HalfedgeHandle he2 = opposite_halfedge_handle( he3 );
238 set_halfedge_handle( v, he0 );
239 set_vertex_handle( he1, v );
242 if ( !is_boundary( he0 ) ) {
243 HalfedgeHandle h0 = next_halfedge_handle( he0 );
244 HalfedgeHandle h1 = next_halfedge_handle( h0 );
246 VertexHandle A = to_vertex_handle( h0 );
247 HalfedgeHandle e2 = new_edge( v, A );
248 HalfedgeHandle e0 = opposite_halfedge_handle( e2 );
250 FaceHandle F2 = new_face();
251 set_halfedge_handle( F0, he0 );
252 set_halfedge_handle( F2, h1 );
254 set_face_handle( h0, F0 );
255 set_face_handle( e0, F0 );
256 set_face_handle( he0, F0 );
257 set_next_halfedge_handle( he0, h0 );
258 set_next_halfedge_handle( h0, e0 );
259 set_next_halfedge_handle( e0, he0 );
261 set_face_handle( h1, F2 );
262 set_face_handle( he2, F2 );
263 set_face_handle( e2, F2 );
264 set_next_halfedge_handle( e2, h1 );
265 set_next_halfedge_handle( h1, he2 );
266 set_next_halfedge_handle( he2, e2 );
274 HalfedgeHandle h1 = prev_halfedge_handle( he0 );
275 set_next_halfedge_handle( h1, he2 );
276 set_next_halfedge_handle( he2, he0 );
282 if ( !is_boundary( he1 ) ) {
283 HalfedgeHandle o1 = next_halfedge_handle( he1 );
284 HalfedgeHandle o0 = next_halfedge_handle( o1 );
286 VertexHandle B = to_vertex_handle( o1 );
287 HalfedgeHandle e1 = new_edge( v, B );
288 HalfedgeHandle e3 = opposite_halfedge_handle( e1 );
290 FaceHandle F3 = new_face();
291 set_halfedge_handle( F3, o1 );
292 set_halfedge_handle( F1, he1 );
294 set_face_handle( o1, F3 );
295 set_face_handle( e3, F3 );
296 set_face_handle( he3, F3 );
297 set_next_halfedge_handle( he3, o1 );
298 set_next_halfedge_handle( o1, e3 );
299 set_next_halfedge_handle( e3, he3 );
301 set_face_handle( o0, F1 );
302 set_face_handle( he1, F1 );
303 set_face_handle( e1, F1 );
304 set_next_halfedge_handle( he1, e1 );
305 set_next_halfedge_handle( e1, o0 );
306 set_next_halfedge_handle( o0, he1 );
317 HalfedgeHandle o1 = next_halfedge_handle( he1 );
319 set_next_halfedge_handle( he1, he3 );
320 set_next_halfedge_handle( he3, o1 );
325 if (
halfedge_handle( v1 ) == he0 ) { set_halfedge_handle( v1, he2 ); }
332void TopologicalMesh::split( EdgeHandle _eh, VertexHandle _vh ) {
336 VertexHandle v2 = to_vertex_handle( o0 );
338 HalfedgeHandle e1 = new_edge( _vh, v2 );
339 HalfedgeHandle t1 = opposite_halfedge_handle( e1 );
341 FaceHandle f0 = face_handle( h0 );
342 FaceHandle f3 = face_handle( o0 );
344 set_halfedge_handle( _vh, h0 );
345 set_vertex_handle( o0, _vh );
347 if ( !is_boundary( h0 ) ) {
348 HalfedgeHandle h1 = next_halfedge_handle( h0 );
349 HalfedgeHandle h2 = next_halfedge_handle( h1 );
351 VertexHandle v1 = to_vertex_handle( h1 );
353 HalfedgeHandle e0 = new_edge( _vh, v1 );
354 HalfedgeHandle t0 = opposite_halfedge_handle( e0 );
356 FaceHandle f1 = new_face();
357 set_halfedge_handle( f0, h0 );
358 set_halfedge_handle( f1, h2 );
360 set_face_handle( h1, f0 );
361 set_face_handle( t0, f0 );
362 set_face_handle( h0, f0 );
364 set_face_handle( h2, f1 );
365 set_face_handle( t1, f1 );
366 set_face_handle( e0, f1 );
368 set_next_halfedge_handle( h0, h1 );
369 set_next_halfedge_handle( h1, t0 );
370 set_next_halfedge_handle( t0, h0 );
372 set_next_halfedge_handle( e0, h2 );
373 set_next_halfedge_handle( h2, t1 );
374 set_next_halfedge_handle( t1, e0 );
377 set_next_halfedge_handle( prev_halfedge_handle( h0 ), t1 );
378 set_next_halfedge_handle( t1, h0 );
382 if ( !is_boundary( o0 ) ) {
383 HalfedgeHandle o1 = next_halfedge_handle( o0 );
384 HalfedgeHandle o2 = next_halfedge_handle( o1 );
386 VertexHandle v3 = to_vertex_handle( o1 );
388 HalfedgeHandle e2 = new_edge( _vh, v3 );
389 HalfedgeHandle t2 = opposite_halfedge_handle( e2 );
391 FaceHandle f2 = new_face();
392 set_halfedge_handle( f2, o1 );
393 set_halfedge_handle( f3, o0 );
395 set_face_handle( o1, f2 );
396 set_face_handle( t2, f2 );
397 set_face_handle( e1, f2 );
399 set_face_handle( o2, f3 );
400 set_face_handle( o0, f3 );
401 set_face_handle( e2, f3 );
403 set_next_halfedge_handle( e1, o1 );
404 set_next_halfedge_handle( o1, t2 );
405 set_next_halfedge_handle( t2, e1 );
407 set_next_halfedge_handle( o0, e2 );
408 set_next_halfedge_handle( e2, o2 );
409 set_next_halfedge_handle( o2, o0 );
412 set_next_halfedge_handle( e1, next_halfedge_handle( o0 ) );
413 set_next_halfedge_handle( o0, e1 );
414 set_halfedge_handle( _vh, e1 );
422void TopologicalMesh::split_copy( EdgeHandle _eh, VertexHandle _vh ) {
426 const int nf = n_faces();
433 for ( VEIter ve_it = ve_iter( _vh ); ve_it.is_valid(); ++ve_it )
434 copy_all_properties( _eh, *ve_it,
true );
436 for (
auto vh : { v0, v1 } ) {
438 const HalfedgeHandle h = find_halfedge( _vh, vh );
440 if ( !is_boundary( h ) ) {
441 FaceHandle fh0 = face_handle( h );
442 FaceHandle fh1 = face_handle( opposite_halfedge_handle( prev_halfedge_handle( h ) ) );
444 if ( fh0.idx() >= nf )
std::swap( fh0, fh1 );
447 copy_all_properties( fh0, fh1,
true );
void setNormals(PointAttribHandle::Container &&normals)
Set normals.
void setVertices(PointAttribHandle::Container &&vertices)
Set vertices.
void setIndices(IndexContainerType &&indices)
const Normal & normal(VertexHandle vh, FaceHandle fh) const
void copyAllProps(HalfedgeHandle input_heh, HalfedgeHandle copy_heh)
void interpolateAllProps(HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f)
bool splitEdge(TopologicalMesh::EdgeHandle eh, Scalar f)
HalfedgeHandle halfedge_handle(VertexHandle vh, FaceHandle fh) const
TriangleMesh toTriangleMesh()
T emplace_back(T... args)
@ Geometry
"Geometry" render objects are those loaded using Radium::IO and generated by GeometrySystem
hepler function to manage enum as underlying types in VariableSet
[Default command implementation]
void initialize(const TriangleMesh &)
Initalize with input Ra::Core::Geometry::TriangleMesh.
DefaultNonManifoldFaceCommand(const std::string &details={})
details string is printed along with the message
void postProcess(TopologicalMesh &)
If needed, apply post-processing on the TopologicalMesh.
void process(const std::vector< TopologicalMesh::VertexHandle > &)
Process non-manifold face.